diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec60df8b35..0b48680830 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1040,6 +1040,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+ ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_freq_equalization.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_measurements_gNB.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
@@ -1144,6 +1145,7 @@ add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
add_library(PHY_NR ${PHY_NR_SRC})
add_library(PHY_NR_UE ${PHY_NR_UE_SRC})
+target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs)
add_library(PHY_RU ${PHY_SRC_RU})
target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs)
diff --git a/ci-scripts/cls_physim1.py b/ci-scripts/cls_physim1.py
index b0c9012d7d..70f8729764 100644
--- a/ci-scripts/cls_physim1.py
+++ b/ci-scripts/cls_physim1.py
@@ -161,7 +161,7 @@ class PhySim:
isRunning = False
count = 0
# Check whether the containers are in Running state or not under 2 mins
- while(count < 2 and isRunning == False):
+ while(count < 5 and isRunning == False):
time.sleep(60)
mySSH.command('oc get pods -o wide -l app=physim | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 30, resync=True)
running_count = mySSH.getBefore().count('Running')
diff --git a/ci-scripts/datalog_rt_stats.1x1.60.yaml b/ci-scripts/datalog_rt_stats.1x1.60.yaml
index c65c4614d2..dca2b28901 100644
--- a/ci-scripts/datalog_rt_stats.1x1.60.yaml
+++ b/ci-scripts/datalog_rt_stats.1x1.60.yaml
@@ -15,7 +15,7 @@ Ref :
DLSCH encoding : 137.0
L1 Rx processing : 345.0
PUSCH inner-receiver : 210.0
- PUSCH decoding : 210.0
+ PUSCH decoding : 2200.0
Schedule Response : 48.0
DL & UL scheduling timing : 13.0
UL Indication : 60.0
diff --git a/ci-scripts/datalog_rt_stats.60.2x2.yaml b/ci-scripts/datalog_rt_stats.60.2x2.yaml
index 50444cc6b0..7d2ea1ef03 100644
--- a/ci-scripts/datalog_rt_stats.60.2x2.yaml
+++ b/ci-scripts/datalog_rt_stats.60.2x2.yaml
@@ -15,7 +15,7 @@ Ref :
DLSCH encoding : 177.0
L1 Rx processing : 345.0
PUSCH inner-receiver : 210.0
- PUSCH decoding : 210.0
+ PUSCH decoding : 2200.0
Schedule Response : 111.0
DL & UL scheduling timing : 20.0
UL Indication : 127.0
diff --git a/ci-scripts/datalog_rt_stats.default.yaml b/ci-scripts/datalog_rt_stats.default.yaml
index 6304404742..bbc5b2d016 100644
--- a/ci-scripts/datalog_rt_stats.default.yaml
+++ b/ci-scripts/datalog_rt_stats.default.yaml
@@ -15,7 +15,7 @@ Ref :
DLSCH encoding : 118.0
L1 Rx processing : 305.0
PUSCH inner-receiver : 150.0
- PUSCH decoding : 210.0
+ PUSCH decoding : 2200.0
Schedule Response : 30.0
DL & UL scheduling timing : 10.0
UL Indication : 40.0
diff --git a/ci-scripts/xml_files/container_4g_l2sim_proxy.xml b/ci-scripts/xml_files/container_4g_l2sim_proxy.xml
index 4c8f9ae019..795bce6bef 100644
--- a/ci-scripts/xml_files/container_4g_l2sim_proxy.xml
+++ b/ci-scripts/xml_files/container_4g_l2sim_proxy.xml
@@ -36,7 +36,7 @@
1
1
True
- f390610304baf6b66e4ec8cc00bf91398a651172
+ b64d9bce986b38ca59e8582864ade3fcdd05c0dc
diff --git a/ci-scripts/xml_files/container_l2sim_proxy.xml b/ci-scripts/xml_files/container_l2sim_proxy.xml
index 8a8dbd05c2..81ee7c1bfa 100644
--- a/ci-scripts/xml_files/container_l2sim_proxy.xml
+++ b/ci-scripts/xml_files/container_l2sim_proxy.xml
@@ -36,7 +36,7 @@
1
1
True
- f390610304baf6b66e4ec8cc00bf91398a651172
+ b64d9bce986b38ca59e8582864ade3fcdd05c0dc
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index bacd781c43..cbd9f7265b 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -319,8 +319,7 @@ check_install_usrp_uhd_driver(){
$SUDO apt-get remove libuhd3.15.0 -y || true
local distribution=$(get_distribution_release)
if [[ "$distribution" == "ubuntu18.04" || "$distribution" == "ubuntu20.04" || "$distribution" == "ubuntu22.04" ]]; then
- $SUDO apt-get remove libuhd4.0.0 -y || true
- $SUDO apt-get remove libuhd4.1.0 -y || true
+ $SUDO apt-get remove libuhd4.?.? -y || true
fi
v=$(lsb_release -cs)
$SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main"
@@ -350,7 +349,7 @@ check_install_usrp_uhd_driver(){
$SUDO apt-get -y install python-tk $boost_libs_ubuntu libusb-1.0-0-dev
case "$(get_distribution_release)" in
"ubuntu18.04" | "ubuntu20.04" | "ubuntu22.04")
- $SUDO apt-get -y install libuhd-dev libuhd4.4.0 uhd-host
+ $SUDO apt-get -y install libuhd-dev libuhd4.5.0 uhd-host
;;
esac
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
diff --git a/common/utils/ds/byte_array.c b/common/utils/ds/byte_array.c
index dfc8872662..c3281ffa27 100644
--- a/common/utils/ds/byte_array.c
+++ b/common/utils/ds/byte_array.c
@@ -22,6 +22,7 @@
#include "byte_array.h"
#include "common/utils/assertions.h"
+#include
#include
byte_array_t copy_byte_array(byte_array_t src)
@@ -56,3 +57,19 @@ bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1)
return true;
}
+
+byte_array_t cp_str_to_ba(const char* str)
+{
+ assert(str != NULL);
+
+ const size_t sz = strlen(str);
+
+ byte_array_t dst = {.len = sz};
+
+ dst.buf = calloc(sz,sizeof(uint8_t));
+ assert(dst.buf != NULL && "Memory exhausted");
+
+ memcpy(dst.buf, str, sz);
+
+ return dst;
+}
diff --git a/common/utils/ds/byte_array.h b/common/utils/ds/byte_array.h
index f16fd7c01d..236f3e683f 100644
--- a/common/utils/ds/byte_array.h
+++ b/common/utils/ds/byte_array.h
@@ -19,8 +19,10 @@
* contact@openairinterface.org
*/
-#ifndef BYTE_ARRAY_H_OAI
-#define BYTE_ARRAY_H_OAI
+#ifndef BYTE_ARRAY_H
+#define BYTE_ARRAY_H
+
+/* WARNING: This file is also defined at XXXXX. Both files need to be completely equal. Same applies for *.c */
#include
#include
@@ -39,4 +41,6 @@ byte_array_t copy_byte_array(byte_array_t src);
void free_byte_array(byte_array_t ba);
bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1);
+byte_array_t cp_str_to_ba(const char* str);
+
#endif
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 64f7a4772c..da4d4ccaa1 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -37,6 +37,46 @@
const char *duplex_mode[]={"FDD","TDD"};
+static const uint8_t bit_reverse_table_256[] = {
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8,
+ 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
+ 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6,
+ 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1,
+ 0x31, 0xB1, 0x71, 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
+ 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB,
+ 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF};
+
+// Reverse bits implementation based on http://graphics.stanford.edu/~seander/bithacks.html
+uint64_t reverse_bits(uint64_t in, int n_bits)
+{
+ // Reverse n_bits in uint64_t variable, example:
+ // n_bits: 10
+ // in: 10 0000 1111
+ // return: 11 1100 0001
+
+ AssertFatal(n_bits <= 64, "Maximum bits to reverse is 64, impossible to reverse %d bits!\n", n_bits);
+ uint64_t rev_bits = 0;
+ uint8_t *p = (uint8_t *)∈
+ uint8_t *q = (uint8_t *)&rev_bits;
+ int n_bytes = n_bits >> 3;
+ for (int n = 0; n < n_bytes; n++) {
+ q[n_bytes - 1 - n] = bit_reverse_table_256[p[n]];
+ }
+
+ // Reverse remaining bits (not aligned with 8-bit)
+ rev_bits = rev_bits << (n_bits % 8);
+ for (int i = n_bytes * 8; i < n_bits; i++) {
+ rev_bits |= ((in >> i) & 0x1) << (n_bits - i - 1);
+ }
+ return rev_bits;
+}
+
static const int tables_5_3_2[5][12] = {
{25, 52, 79, 106, 133, 160, 216, 270, -1, -1, -1, -1}, // 15 FR1
{11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 245, 273}, // 30 FR1
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
index d9ac675493..ea879e93b4 100644
--- a/common/utils/nr/nr_common.h
+++ b/common/utils/nr/nr_common.h
@@ -90,6 +90,8 @@ static inline int get_num_dmrs(uint16_t dmrs_mask ) {
return(num_dmrs);
}
+uint64_t reverse_bits(uint64_t in, int n_bits);
+
int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols);
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs);
int get_SLIV(uint8_t S, uint8_t L);
diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index b0d05c6aca..941e4de6ef 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -49,6 +49,7 @@ extern "C" {
int nb_fd_epoll=0;
int epoll_fd=-1;
int sem_fd=-1;
+ size_t last_log_size = 0;
} task_list_t;
int timer_expired(int fd);
@@ -131,11 +132,23 @@ extern "C" {
int message_id = message->ittiMsgHeader.messageId;
size_t s=t->message_queue.size();
- if ( s > t->admin.queue_size )
- LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s );
-
- if ( s > 50 )
- LOG_I(ITTI,"Queue for %s task size: %ld (last message %s)\n",itti_get_task_name(destination_task_id), s+1,ITTI_MSG_NAME(message));
+ // to reduce the number of logs, we give a message each increase of 25%
+ if ((s > t->last_log_size * 1.25) && (s > t->admin.queue_size / 10)) {
+ if (s > t->admin.queue_size) {
+ LOG_E(TMR, "Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s);
+ } else {
+ LOG_I(ITTI,
+ "Queue for %s task size: %ld (last message %s)\n",
+ itti_get_task_name(destination_task_id),
+ s + 1,
+ ITTI_MSG_NAME(message));
+ }
+ t->last_log_size = s;
+ } else if (t->last_log_size && s < t->admin.queue_size / 10) {
+ // Inform when the queue decreases
+ LOG_I(ITTI, "Queue for %s task size is back under 10%% of max size\n", itti_get_task_name(destination_task_id));
+ t->last_log_size = 0;
+ }
t->message_queue.insert(t->message_queue.begin(), message);
eventfd_t sem_counter = 1;
diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt
index d310e1162c..d7b9b3cf9d 100644
--- a/common/utils/telnetsrv/CMakeLists.txt
+++ b/common/utils/telnetsrv/CMakeLists.txt
@@ -59,8 +59,13 @@ add_library(telnetsrv_ci MODULE telnetsrv_ci.c)
target_link_libraries(telnetsrv_ci PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_dependencies(telnetsrv telnetsrv_ci)
+message(STATUS "Add bearer specific telnet functions in libtelnetsrv_bearer.so")
+add_library(telnetsrv_bearer MODULE telnetsrv_bearer.c)
+target_link_libraries(telnetsrv_bearer PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
+add_dependencies(telnetsrv telnetsrv_bearer)
+
# all libraries should be written to root build dir
-set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci
+set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci telnetsrv_bearer
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../..
)
diff --git a/common/utils/telnetsrv/telnetsrv_bearer.c b/common/utils/telnetsrv/telnetsrv_bearer.c
new file mode 100644
index 0000000000..f019d3d48b
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv_bearer.c
@@ -0,0 +1,121 @@
+/*
+ * 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
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
+
+#define TELNETSERVERCODE
+#include "telnetsrv.h"
+
+#define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0)
+
+static int get_single_ue_rnti(void)
+{
+ rrc_gNB_ue_context_t *ue_context_p = NULL;
+ RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[0]->rrc_ue_head)) {
+ return ue_context_p->ue_context.rnti;
+ }
+ return -1;
+}
+
+int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt)
+{
+ if (buf)
+ ERROR_MSG_RET("no parameter allowed\n");
+
+ int rnti = get_single_ue_rnti();
+ if (rnti < 1)
+ ERROR_MSG_RET("different number of UEs\n");
+
+ prnt("single UE RNTI %04x\n", rnti);
+ return 0;
+}
+
+void rrc_gNB_trigger_new_bearer(int rnti);
+int add_bearer(char *buf, int debug, telnet_printfunc_t prnt)
+{
+ int rnti = -1;
+ if (!buf) {
+ rnti = get_single_ue_rnti();
+ if (rnti < 1)
+ ERROR_MSG_RET("no UE found\n");
+ } else {
+ rnti = strtol(buf, NULL, 16);
+ if (rnti < 1 || rnti >= 0xfffe)
+ ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
+ }
+
+ // verify it exists in RRC as well
+ rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
+ if (!rrcue)
+ ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
+
+ rrc_gNB_trigger_new_bearer(rnti);
+ prnt("called rrc_gNB_trigger_new_bearer(%04x)\n", rnti);
+ return 0;
+}
+
+void rrc_gNB_trigger_release_bearer(int rnti);
+int release_bearer(char *buf, int debug, telnet_printfunc_t prnt)
+{
+ int rnti = -1;
+ if (!buf) {
+ rnti = get_single_ue_rnti();
+ if (rnti < 1)
+ ERROR_MSG_RET("no UE found\n");
+ } else {
+ rnti = strtol(buf, NULL, 16);
+ if (rnti < 1 || rnti >= 0xfffe)
+ ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
+ }
+
+ // verify it exists in RRC as well
+ rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
+ if (!rrcue)
+ ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
+
+ rrc_gNB_trigger_release_bearer(rnti);
+ prnt("called rrc_gNB_trigger_release_bearer(%04x)\n", rnti);
+ return 0;
+}
+
+static telnetshell_cmddef_t bearercmds[] = {
+ {"get_single_rnti", "", get_single_rnti},
+ {"add_bearer", "[rnti(hex,opt)]", add_bearer},
+ {"release_bearer", "[rnti(hex,opt)]", release_bearer},
+ {"", "", NULL},
+};
+
+static telnetshell_vardef_t bearervars[] = {
+
+ {"", 0, 0, NULL}
+};
+
+void add_bearer_cmds(void) {
+ add_telnetcmd("bearer", bearervars, bearercmds);
+}
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 33fe6b3f2a..e4a9e4e5e6 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -475,10 +475,12 @@ void init_gNB_Tpool(int inst) {
PHY_VARS_gNB *gNB;
gNB = RC.gNB[inst];
gNB_L1_proc_t *proc = &gNB->proc;
-
+ // PUSCH symbols per thread need to be calculated by how many threads we have
+ gNB->num_pusch_symbols_per_thread = 1;
// ULSCH decoding threadpool
initTpool(get_softmodem_params()->threadPoolConfig, &gNB->threadPool, cpumeas(CPUMEAS_GETSTATE));
// ULSCH decoder result FIFO
+ initNotifiedFIFO(&gNB->respPuschSymb);
initNotifiedFIFO(&gNB->respDecode);
// L1 RX result FIFO
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 8bffda8f61..31bde16b97 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -709,7 +709,7 @@ int main( int argc, char **argv ) {
const int mcc = rrc->configuration.mcc[0];
const int mnc = rrc->configuration.mnc[0];
const int mnc_digit_len = rrc->configuration.mnc_digit_length[0];
- const ngran_node_t node_type = rrc->node_type;
+ // const ngran_node_t node_type = rrc->node_type;
int nb_id = 0;
int cu_du_id = 0;
if (node_type == ngran_gNB) {
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index 97f73ef880..67f6c346c7 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -1070,6 +1070,7 @@ int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
rx_ind->pdu_list[j].rnti = ind->pdu_list[j].rnti;
rx_ind->pdu_list[j].timing_advance = ind->pdu_list[j].timing_advance;
rx_ind->pdu_list[j].ul_cqi = ind->pdu_list[j].ul_cqi;
+ rx_ind->pdu_list[j].rssi = ind->pdu_list[j].rssi;
}
if (!put_queue(&gnb_rx_ind_queue, rx_ind))
{
diff --git a/nfapi/open-nFAPI/nfapi/inc/nfapi.h b/nfapi/open-nFAPI/nfapi/inc/nfapi.h
index e1a0ec4f4e..dc2d3d3ec0 100644
--- a/nfapi/open-nFAPI/nfapi/inc/nfapi.h
+++ b/nfapi/open-nFAPI/nfapi/inc/nfapi.h
@@ -77,6 +77,9 @@ uint8_t unpackarray(uint8_t **ppReadPackedMsg,
uint8_t *end,
unpack_array_elem_fn fn);
+uint32_t pack_dci_payload(uint8_t payload[], uint16_t payloadSizeBits, uint8_t **out, uint8_t *end);
+uint32_t unpack_dci_payload(uint8_t payload[], uint16_t payloadSizeBits, uint8_t **in, uint8_t *end);
+
uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end);
uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end);
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index a9338cf3ca..21c9558653 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -932,6 +932,8 @@ typedef struct
typedef struct
{
+ uint16_t bwp_size; // Needed for SCF222 10.02
+ uint16_t bwp_start; // Needed for SCF222 10.02
uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
uint16_t start_rb; // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c
index ef80c86849..62d79bb511 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c
@@ -49,6 +49,7 @@
#include
#include
+#include
#include
#include
@@ -544,6 +545,43 @@ uint8_t unpackarray(uint8_t **ppReadPackedMsg, void *array, uint16_t array_eleme
return 1;
}
+uint32_t pack_dci_payload(uint8_t payload[], uint16_t payloadSizeBits, uint8_t **out, uint8_t *end)
+{
+ // Helper vars for DCI Payload
+ uint8_t dci_bytes_inverted[DCI_PAYLOAD_BYTE_LEN];
+ uint8_t dci_byte_len = (payloadSizeBits + 7) / 8;
+ // Align the dci payload bits to the left on the payload buffer
+ uint64_t *dci_pdu = (uint64_t *)payload;
+ if (payloadSizeBits % 8 != 0) {
+ uint8_t rotation_bits = 8 - (payloadSizeBits % 8);
+ *dci_pdu = (*dci_pdu << rotation_bits);
+ }
+ // Invert the byte order of the DCI Payload
+ for (int j = 0; j < dci_byte_len; j++) {
+ dci_bytes_inverted[j] = payload[(dci_byte_len - 1) - j];
+ }
+ return pusharray8(dci_bytes_inverted, DCI_PAYLOAD_BYTE_LEN, dci_byte_len, out, end);
+}
+
+uint32_t unpack_dci_payload(uint8_t payload[], uint16_t payloadSizeBits, uint8_t **in, uint8_t *end)
+{
+ // Pull the inverted DCI and invert it back
+ // Helper vars for DCI Payload
+ uint8_t dci_bytes_inverted[DCI_PAYLOAD_BYTE_LEN];
+ uint8_t dci_byte_len = (payloadSizeBits + 7) / 8;
+ // Get DCI array inverted
+ uint32_t pullresult = pullarray8(in, dci_bytes_inverted, DCI_PAYLOAD_BYTE_LEN, dci_byte_len, end);
+ uint64_t *dci_pdu = (uint64_t *)payload;
+ // Reversing the byte order of the inverted DCI payload
+ for (uint16_t j = 0; j < dci_byte_len; j++) {
+ payload[j] = dci_bytes_inverted[(dci_byte_len - 1) - j];
+ }
+ if (payloadSizeBits % 8 != 0) {
+ uint8_t rotation_bits = 8 - (payloadSizeBits % 8);
+ *dci_pdu = (*dci_pdu >> rotation_bits);
+ }
+ return pullresult;
+}
uint32_t pack_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
if(ve != 0 && config != 0) {
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index f5a05d0d71..8f7a7c2804 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -196,124 +196,176 @@ static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t *value, uint8_t **ppW
return 1;
}
-
-static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
- return(
- push8(value->subcarrier_spacing, ppWritePackedMsg, end) &&
- push8(value->cyclic_prefix, ppWritePackedMsg, end) &&
- push16(value->start_rb, ppWritePackedMsg, end) &&
- push16(value->nr_of_rbs, ppWritePackedMsg, end) &&
- push8(value->csi_type, ppWritePackedMsg, end) &&
- push8(value->row, ppWritePackedMsg, end) &&
- push16(value->freq_domain, ppWritePackedMsg, end) &&
- push8(value->symb_l0, ppWritePackedMsg, end) &&
- push8(value->symb_l1, ppWritePackedMsg, end) &&
- push8(value->cdm_type, ppWritePackedMsg, end) &&
- push8(value->freq_density, ppWritePackedMsg, end) &&
- push16(value->scramb_id, ppWritePackedMsg, end) &&
- push8(value->power_control_offset, ppWritePackedMsg, end) &&
- push8(value->power_control_offset_ss, ppWritePackedMsg, end)
- );
+ return (push16(value->bwp_size, ppWritePackedMsg, end) && push16(value->bwp_start, ppWritePackedMsg, end)
+ && push8(value->subcarrier_spacing, ppWritePackedMsg, end) && push8(value->cyclic_prefix, ppWritePackedMsg, end)
+ && push16(value->start_rb, ppWritePackedMsg, end) && push16(value->nr_of_rbs, ppWritePackedMsg, end)
+ && push8(value->csi_type, ppWritePackedMsg, end) && push8(value->row, ppWritePackedMsg, end)
+ && push16(value->freq_domain, ppWritePackedMsg, end) && push8(value->symb_l0, ppWritePackedMsg, end)
+ && push8(value->symb_l1, ppWritePackedMsg, end) && push8(value->cdm_type, ppWritePackedMsg, end)
+ && push8(value->freq_density, ppWritePackedMsg, end) && push16(value->scramb_id, ppWritePackedMsg, end)
+ && push8(value->power_control_offset, ppWritePackedMsg, end)
+ && push8(value->power_control_offset_ss, ppWritePackedMsg, end) &&
+ // TODO Add Precoding and Beamforming, hardcoded for now
+ push16(0, ppWritePackedMsg, end) && push16(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end));
}
+static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
-static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+ if (!(push16(value->BWPSize, ppWritePackedMsg, end) && push16(value->BWPStart, ppWritePackedMsg, end)
+ && push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && push8(value->CyclicPrefix, ppWritePackedMsg, end)
+ && push8(value->StartSymbolIndex, ppWritePackedMsg, end) && push8(value->DurationSymbols, ppWritePackedMsg, end)
+ && pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end)
+ && push8(value->CceRegMappingType, ppWritePackedMsg, end) && push8(value->RegBundleSize, ppWritePackedMsg, end)
+ && push8(value->InterleaverSize, ppWritePackedMsg, end) && push8(value->CoreSetType, ppWritePackedMsg, end)
+ && push16(value->ShiftIndex, ppWritePackedMsg, end) && push8(value->precoderGranularity, ppWritePackedMsg, end)
+ && push16(value->numDlDci, ppWritePackedMsg, end))) {
+ return 0;
+ }
- nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv;
- for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
- {
- if(!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) &&
- push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
- push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
- push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
- push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
- push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
- push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
- push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
- pusharray8(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end)))
- return 0;
- }
- // TODO: resolve the packaging of array (currently sending a single element)
- return(
- push16(value->BWPSize, ppWritePackedMsg, end) &&
- push16(value->BWPStart, ppWritePackedMsg, end) &&
- push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
- push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
- push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
- push8(value->DurationSymbols, ppWritePackedMsg, end) &&
- pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
- push8(value->CceRegMappingType, ppWritePackedMsg, end) &&
- push8(value->RegBundleSize, ppWritePackedMsg, end) &&
- push8(value->InterleaverSize, ppWritePackedMsg, end) &&
- push8(value->CoreSetType, ppWritePackedMsg, end) &&
- push16(value->ShiftIndex, ppWritePackedMsg, end) &&
- push8(value->precoderGranularity, ppWritePackedMsg, end) &&
- push16(value->numDlDci, ppWritePackedMsg, end));
+ for (uint16_t i = 0; i < value->numDlDci; ++i) {
+ if (!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end)
+ && push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end)
+ && push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end)
+ && push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ // Precoding and beamforming
+ // TODO get these values from elsewhere and delete the hardcoded ones
+ value->dci_pdu[i].precodingAndBeamforming.num_prgs = 0;
+ value->dci_pdu[i].precodingAndBeamforming.prg_size = 0; // 1 PRG of max size for analogue beamforming
+ value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces = 0;
+ value->dci_pdu[i].precodingAndBeamforming.prgs_list[0].pm_idx = 0;
+ value->dci_pdu[i].precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
+ if (!(push16(value->dci_pdu[i].precodingAndBeamforming.num_prgs, ppWritePackedMsg, end)
+ && push16(value->dci_pdu[i].precodingAndBeamforming.prg_size, ppWritePackedMsg, end)
+ && push8(value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int prg = 0; prg < value->dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
+ if (!push16(value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ for (int digInt = 0; digInt < value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces; digInt++) {
+ if (!push16(value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].dig_bf_interface_list[digInt].beam_idx,
+ ppWritePackedMsg,
+ end)) {
+ return 0;
+ }
+ }
+ }
+ // TX Power info
+ if (!(push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end)
+ && push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
+ // DCI Payload fields
+ push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
+ // Pack DCI Payload
+ pack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ }
+ return 1;
}
-
-static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
- // TODO: resolve the packaging of array (currently sending a single element)
- return(
- push16(value->pduBitmap, ppWritePackedMsg, end) &&
- push16(value->rnti, ppWritePackedMsg, end) &&
- push16(value->pduIndex, ppWritePackedMsg, end) &&
- push16(value->BWPSize, ppWritePackedMsg, end) &&
- push16(value->BWPStart, ppWritePackedMsg, end) &&
- push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
- push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
- push8(value->NrOfCodewords, ppWritePackedMsg, end) &&
- pusharray16(value->targetCodeRate, 2, 1, ppWritePackedMsg, end) &&
- pusharray8(value->qamModOrder, 2, 1, ppWritePackedMsg, end) &&
- pusharray8(value->mcsIndex, 2, 1, ppWritePackedMsg, end) &&
- pusharray8(value->mcsTable, 2, 1, ppWritePackedMsg, end) &&
- pusharray8(value->rvIndex, 2, 1, ppWritePackedMsg, end) &&
- pusharray32(value->TBSize, 2, 1, ppWritePackedMsg, end) &&
- push16(value->dataScramblingId, ppWritePackedMsg, end) &&
- push8(value->nrOfLayers, ppWritePackedMsg, end) &&
- push8(value->transmissionScheme, ppWritePackedMsg, end) &&
- push8(value->refPoint, ppWritePackedMsg, end) &&
- push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) &&
- push8(value->dmrsConfigType, ppWritePackedMsg, end) &&
- push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) &&
- push8(value->SCID, ppWritePackedMsg, end) &&
- push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) &&
- push16(value->dmrsPorts, ppWritePackedMsg, end) &&
- push8(value->resourceAlloc, ppWritePackedMsg, end) &&
- push16(value->rbStart, ppWritePackedMsg, end) &&
- push16(value->rbSize, ppWritePackedMsg, end) &&
- push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) &&
- push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
- push8(value->NrOfSymbols, ppWritePackedMsg, end) &&
- push8(value->PTRSPortIndex, ppWritePackedMsg, end) &&
- push8(value->PTRSTimeDensity, ppWritePackedMsg, end) &&
- push8(value->PTRSFreqDensity, ppWritePackedMsg, end) &&
- push8(value->PTRSReOffset, ppWritePackedMsg, end)
- );
+
+ if (!(push16(value->pduBitmap, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
+ && push16(value->pduIndex, ppWritePackedMsg, end) && push16(value->BWPSize, ppWritePackedMsg, end)
+ && push16(value->BWPStart, ppWritePackedMsg, end) && push8(value->SubcarrierSpacing, ppWritePackedMsg, end)
+ && push8(value->CyclicPrefix, ppWritePackedMsg, end) && push8(value->NrOfCodewords, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int i = 0; i < value->NrOfCodewords; ++i) {
+ if (!(push16(value->targetCodeRate[i], ppWritePackedMsg, end) && push8(value->qamModOrder[i], ppWritePackedMsg, end)
+ && push8(value->mcsIndex[i], ppWritePackedMsg, end) && push8(value->mcsTable[i], ppWritePackedMsg, end)
+ && push8(value->rvIndex[i], ppWritePackedMsg, end) && push32(value->TBSize[i], ppWritePackedMsg, end))) {
+ return 0;
+ }
+ }
+
+ if (!(push16(value->dataScramblingId, ppWritePackedMsg, end) && push8(value->nrOfLayers, ppWritePackedMsg, end)
+ && push8(value->transmissionScheme, ppWritePackedMsg, end) && push8(value->refPoint, ppWritePackedMsg, end)
+ && push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && push8(value->dmrsConfigType, ppWritePackedMsg, end)
+ && push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && push8(value->SCID, ppWritePackedMsg, end)
+ && push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && push16(value->dmrsPorts, ppWritePackedMsg, end)
+ && push8(value->resourceAlloc, ppWritePackedMsg, end) && (int)pusharray8(value->rbBitmap, 36, 36, ppWritePackedMsg, end)
+ && push16(value->rbStart, ppWritePackedMsg, end) && push16(value->rbSize, ppWritePackedMsg, end)
+ && push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && push8(value->StartSymbolIndex, ppWritePackedMsg, end)
+ && push8(value->NrOfSymbols, ppWritePackedMsg, end))) {
+ return 0;
+ }
+
+ // Check pduBitMap bit 1 to add or not PTRS parameters
+ if (value->pduBitmap & 0b1) {
+ if (!(push8(value->PTRSPortIndex, ppWritePackedMsg, end) && push8(value->PTRSTimeDensity, ppWritePackedMsg, end)
+ && push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && push8(value->PTRSReOffset, ppWritePackedMsg, end)
+ && push8(value->nEpreRatioOfPDSCHToPTRS, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ }
+
+ if (!(push16(value->precodingAndBeamforming.num_prgs, ppWritePackedMsg, end)
+ && push16(value->precodingAndBeamforming.prg_size, ppWritePackedMsg, end)
+ && push8(value->precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int i = 0; i < value->precodingAndBeamforming.num_prgs; ++i) {
+ if (!push16(value->precodingAndBeamforming.prgs_list[i].pm_idx, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ for (int k = 0; k < value->precodingAndBeamforming.dig_bf_interfaces; ++k) {
+ if (!push16(value->precodingAndBeamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ }
+ }
+ // TODO Add TX power info
+ // Hardcoded values that represent 0db
+ if (!(push8(8, ppWritePackedMsg, end) && // powerControlOffset
+ push8(1, ppWritePackedMsg, end))) { // powerControlOffsetSS
+ return 0;
+ }
+ // TODO Add CBG Fields
+ return 1;
}
+static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n");
+ nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
-static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
- NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n");
- nfapi_nr_dl_tti_ssb_pdu_rel15_t* value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t*)tlv;
-
- return(
- push16(value->PhysCellId, ppWritePackedMsg, end) &&
- push8(value->BetaPss, ppWritePackedMsg, end) &&
- push8(value->SsbBlockIndex, ppWritePackedMsg, end) &&
- push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) &&
- push16(value->ssbOffsetPointA, ppWritePackedMsg, end) &&
- push8(value->bchPayloadFlag, ppWritePackedMsg, end) &&
- push32(value->bchPayload, ppWritePackedMsg, end) &&
- push8(value->ssbRsrp, ppWritePackedMsg, end)
- // TODO: pack precoding_and_beamforming too
- );
-
+ if (!(push16(value->PhysCellId, ppWritePackedMsg, end) && push8(value->BetaPss, ppWritePackedMsg, end)
+ && push8(value->SsbBlockIndex, ppWritePackedMsg, end) && push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end)
+ && push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end)
+ && push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end)
+ && push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end)
+ && push8(0, ppWritePackedMsg, end) &&
+ // TODO add Tx Power Info
+ push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end)
+ && push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end)
+ && push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end)
+ && push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int i = 0; i < value->precoding_and_beamforming.num_prgs; ++i) {
+ if (!push16(value->precoding_and_beamforming.prgs_list[i].pm_idx, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ for (int k = 0; k < value->precoding_and_beamforming.dig_bf_interfaces; ++k) {
+ if (!push16(value->precoding_and_beamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ }
+ }
+ return 1;
}
-
static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
nfapi_dl_config_dci_dl_pdu_rel13_t *value = (nfapi_dl_config_dci_dl_pdu_rel13_t *)tlv;
return( push8(value->laa_end_partial_sf_flag, ppWritePackedMsg, end) &&
@@ -594,47 +646,47 @@ static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppWrit
push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end));
}
-
-static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)tlv;
-
- if(!(push32(value->PDUSize, ppWritePackedMsg, end) &&
- push16(value->PDUType, ppWritePackedMsg, end) ))
+ uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
+ if (!push16(value->PDUType, ppWritePackedMsg, end))
+ return 0;
+ uint8_t *pPackedLengthField = *ppWritePackedMsg;
+ if (!push16(value->PDUSize, ppWritePackedMsg, end))
return 0;
// first match the pdu type, then call the respective function
- switch(value->PDUType) {
+ switch (value->PDUType) {
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
- if(!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppWritePackedMsg,end)))
+ if (!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppWritePackedMsg, end)))
return 0;
- }
- break;
+ } break;
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
- if(!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppWritePackedMsg,end)))
+ if (!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppWritePackedMsg, end)))
return 0;
- }
- break;
+ } break;
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
- if(!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppWritePackedMsg,end)))
+ if (!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppWritePackedMsg, end)))
return 0;
- }
- break;
+ } break;
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
- if(!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppWritePackedMsg,end)))
+ if (!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppWritePackedMsg, end)))
return 0;
- }
- break;
+ } break;
default: {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
- }
- break;
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType);
+ } break;
}
-
- return 1;
+ // pack proper size
+ uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
+ uint16_t packedMsgLen = msgEnd - msgHead;
+ value->PDUSize = packedMsgLen;
+ return push16(value->PDUSize, &pPackedLengthField, end);
}
static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
@@ -777,42 +829,34 @@ static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePac
return 1;
}
-
-static uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+static uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
- nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t*)msg;
+ nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
- if (!(push16(pNfapiMsg->SFN , ppWritePackedMsg, end) &&
- push16(pNfapiMsg->Slot , ppWritePackedMsg, end) &&
- push8(pNfapiMsg->dl_tti_request_body.nGroup , ppWritePackedMsg, end) &&
- push8(pNfapiMsg->dl_tti_request_body.nPDUs , ppWritePackedMsg, end) &&
- pusharray8(pNfapiMsg->dl_tti_request_body.nUe, 256, pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end)
- //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end)
- ))
- return 0;
+ if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
+ && push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end)
+ && push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
+ if (!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i], ppWritePackedMsg, end))
+ return 0;
+ }
- int arr[12];
- for(int i=0;idl_tti_request_body.nGroup;i++)
- {
- for(int j=0;jdl_tti_request_body.nUe[i];j++)
- {
- arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j];
- }
- if(!(pusharrays32(arr, 12, pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end)))
- return 0;
- }
+ for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
+ if (!push8(pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end))
+ return 0;
+ for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
+ if (!(push32(pNfapiMsg->dl_tti_request_body.PduIdx[i][j], ppWritePackedMsg, end))) {
+ return 0;
+ }
+ }
+ return 0;
+ }
- for(int i=0;idl_tti_request_body.nPDUs;i++)
- {
- if(!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i],ppWritePackedMsg,end))
- return 0;
- }
-
-return 1;
+ return 1;
}
-
-
static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg;
//return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
@@ -882,148 +926,178 @@ static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppW
//Pack fns for ul_tti PDUS
-
-static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
- return(
- push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) &&
- push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end) &&
- push8(prach_pdu->prach_format, ppWritePackedMsg, end) &&
- push8(prach_pdu->num_ra, ppWritePackedMsg, end) &&
- push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) &&
- push16(prach_pdu->num_cs, ppWritePackedMsg, end)
- // TODO: ignoring beamforming tlv for now
- );
-}
-
-static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
- return(
- push16(pucch_pdu->rnti, ppWritePackedMsg, end) &&
- push32(pucch_pdu->handle, ppWritePackedMsg, end) &&
- push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) &&
- push16(pucch_pdu->bwp_start, ppWritePackedMsg, end) &&
- push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
- push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
- push8(pucch_pdu->format_type, ppWritePackedMsg, end) &&
- push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end) &&
- push8(pucch_pdu->pi_2bpsk, ppWritePackedMsg, end) &&
- push16(pucch_pdu->prb_start, ppWritePackedMsg, end) &&
- push16(pucch_pdu->prb_size, ppWritePackedMsg, end) &&
- push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
- push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) &&
- push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end) &&
- push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) &&
- push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end) &&
- push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) &&
- push16(pucch_pdu->hopping_id, ppWritePackedMsg, end) &&
- push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end) &&
- push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
- push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) &&
- push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end) &&
- push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) &&
- push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end) &&
- push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end) &&
- push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) &&
- push8(pucch_pdu->sr_flag, ppWritePackedMsg, end) &&
- push8(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) &&
- push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end) &&
- push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end)
- // TODO: ignoring beamforming tlv for now
- );
-}
-
-
-static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
- if (!(
- push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) &&
- push16(pusch_pdu->rnti, ppWritePackedMsg, end) &&
- push32(pusch_pdu->handle, ppWritePackedMsg, end) &&
- push16(pusch_pdu->bwp_size, ppWritePackedMsg, end) &&
- push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) &&
- push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
- push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
- push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end) &&
- push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) &&
- push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) &&
- push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) &&
- push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) &&
- push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
- push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) &&
- push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) &&
- push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) &&
- push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) &&
- push8(pusch_pdu->scid, ppWritePackedMsg, end) &&
- push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end) &&
- push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
- push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end) &&
- push8(pusch_pdu->resource_alloc,ppWritePackedMsg, end) &&
- push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
- push16(pusch_pdu->rb_start, ppWritePackedMsg, end) &&
- push16(pusch_pdu->rb_size, ppWritePackedMsg, end) &&
- push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end) &&
- push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end) &&
- push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end) &&
- push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end) &&
- push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
- push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end)
- // TODO: ignoring beamforming tlv for now
- ))
+static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ if (!(push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) && push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end)
+ && push8(prach_pdu->prach_format, ppWritePackedMsg, end) && push8(prach_pdu->num_ra, ppWritePackedMsg, end)
+ && push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) && push16(prach_pdu->num_cs, ppWritePackedMsg, end))) {
return 0;
-
- //Pack Optional Data only included if indicated in pduBitmap
- switch(pusch_pdu->pdu_bit_map) {
- case PUSCH_PDU_BITMAP_PUSCH_DATA: {
- // pack optional TLVs
- return(
- push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end) &&
- push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end) &&
- push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end) &&
- pusharray8(pusch_pdu->pusch_data.cb_present_and_position,1,1,ppWritePackedMsg, end)
- );
- }
- break;
-
- case PUSCH_PDU_BITMAP_PUSCH_UCI: {
- return(
- push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end) &&
- push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end) &&
- push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end)
- );
- }
- break;
-
- case PUSCH_PDU_BITMAP_PUSCH_PTRS: {
- return(
- push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, ppWritePackedMsg, end) &&
- push16(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end) &&
- push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end)
- );
- }
- break;
-
- case PUSCH_PDU_BITMAP_DFTS_OFDM: {
- return(
- push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end) &&
- push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end) &&
- push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end) &&
- push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end)
- );
- }
- break;
-
- default: {
- NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
- }
}
+ // TODO: put these hardoded values elsewhere
+ // Beamforming
+ prach_pdu->beamforming.num_prgs = 0;
+ prach_pdu->beamforming.prg_size = 0;
+ prach_pdu->beamforming.dig_bf_interface = 0;
+
+ if (prach_pdu->beamforming.prgs_list == NULL) {
+ prach_pdu->beamforming.prgs_list = calloc(prach_pdu->beamforming.num_prgs, sizeof(*prach_pdu->beamforming.prgs_list));
+ }
+ if (prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) {
+ prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list =
+ calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list));
+ }
+ prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
+
+ // Pack RX Beamforming PDU
+ if (!(push16(prach_pdu->beamforming.num_prgs, ppWritePackedMsg, end)
+ && push16(prach_pdu->beamforming.prg_size, ppWritePackedMsg, end)
+ && push8(prach_pdu->beamforming.dig_bf_interface, ppWritePackedMsg, end)))
+ return 0;
+
+ for (int prg = 0; prg < prach_pdu->beamforming.num_prgs; prg++) {
+ for (int digBFInterface = 0; digBFInterface < prach_pdu->beamforming.dig_bf_interface; digBFInterface++) {
+ if (!push16(prach_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ if (!(push16(pucch_pdu->rnti, ppWritePackedMsg, end) && push32(pucch_pdu->handle, ppWritePackedMsg, end)
+ && push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) && push16(pucch_pdu->bwp_start, ppWritePackedMsg, end)
+ && push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end)
+ && push8(pucch_pdu->format_type, ppWritePackedMsg, end) && push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end)
+ && push8(pucch_pdu->pi_2bpsk, ppWritePackedMsg, end) && push16(pucch_pdu->prb_start, ppWritePackedMsg, end)
+ && push16(pucch_pdu->prb_size, ppWritePackedMsg, end) && push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end)
+ && push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) && push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end)
+ && push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) && push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end)
+ && push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) && push16(pucch_pdu->hopping_id, ppWritePackedMsg, end)
+ && push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end)
+ && push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end)
+ && push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) && push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end)
+ && push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) && push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end)
+ && push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end)
+ && push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) && push8(pucch_pdu->sr_flag, ppWritePackedMsg, end)
+ && push16(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) && push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end)
+ && push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end)
+ // Pack RX Beamforming PDU
+ && push16(pucch_pdu->beamforming.num_prgs, ppWritePackedMsg, end)
+ && push16(pucch_pdu->beamforming.prg_size, ppWritePackedMsg, end)
+ && push8(pucch_pdu->beamforming.dig_bf_interface, ppWritePackedMsg, end))) {
+ return 0;
+ }
+
+ for (int prg = 0; prg < pucch_pdu->beamforming.num_prgs; prg++) {
+ for (int digBFInterface = 0; digBFInterface < pucch_pdu->beamforming.dig_bf_interface; digBFInterface++) {
+ if (!push16(pucch_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ if (!(push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) && push16(pusch_pdu->rnti, ppWritePackedMsg, end)
+ && push32(pusch_pdu->handle, ppWritePackedMsg, end) && push16(pusch_pdu->bwp_size, ppWritePackedMsg, end)
+ && push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) && push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end)
+ && push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) && push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end)
+ && push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_index, ppWritePackedMsg, end)
+ && push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end)
+ && push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end)
+ && push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end)
+ && push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end)
+ && push16(pusch_pdu->pusch_identity, ppWritePackedMsg, end) && push8(pusch_pdu->scid, ppWritePackedMsg, end)
+ && push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end)
+ && push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) && push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end)
+ && pusharray8(pusch_pdu->rb_bitmap, 36, 36, ppWritePackedMsg, end) && push16(pusch_pdu->rb_start, ppWritePackedMsg, end)
+ && push16(pusch_pdu->rb_size, ppWritePackedMsg, end) && push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end)
+ && push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end)
+ && push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end)
+ && push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end)
+ && push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) && push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end)
+ // TODO: ignoring beamforming tlv for now
+ )) {
+ return 0;
+ }
+ // Pack Optional Data only included if indicated in pduBitmap
+ switch (pusch_pdu->pdu_bit_map) {
+ case PUSCH_PDU_BITMAP_PUSCH_DATA: {
+ // pack optional TLVs
+ if (!(push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_data.new_data_indicator, ppWritePackedMsg, end)
+ && push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end)
+ && push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end)
+ && pusharray8(pusch_pdu->pusch_data.cb_present_and_position,
+ (pusch_pdu->pusch_data.num_cb + 7) / 8,
+ (pusch_pdu->pusch_data.num_cb + 7) / 8,
+ ppWritePackedMsg,
+ end))) {
+ return 0;
+ }
+ } break;
+
+ case PUSCH_PDU_BITMAP_PUSCH_UCI: {
+ if (!(push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end)
+ && push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end)
+ && push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ } break;
+
+ case PUSCH_PDU_BITMAP_PUSCH_PTRS: {
+ if (!push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ for (int i = 0; i < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++i) {
+ if (!(push16(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_port_index, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_dmrs_port, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_re_offset, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ }
+
+ if (!(push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end)
+ && push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ } break;
+
+ case PUSCH_PDU_BITMAP_DFTS_OFDM: {
+ if (!(push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end)
+ && push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end)
+ && push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end)
+ && push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ } break;
+
+ default: {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map);
+ }
+ }
+ // Pack RX Beamforming PDU
+ if (!(push16(pusch_pdu->beamforming.num_prgs, ppWritePackedMsg, end)
+ && push16(pusch_pdu->beamforming.prg_size, ppWritePackedMsg, end)
+ && push8(pusch_pdu->beamforming.dig_bf_interface, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int prg = 0; prg < pusch_pdu->beamforming.num_prgs; prg++) {
+ for (int digBFInterface = 0; digBFInterface < pusch_pdu->beamforming.dig_bf_interface; digBFInterface++) {
+ if (!push16(pusch_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ }
+ }
return 1;
}
@@ -1346,48 +1420,50 @@ static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t *
push8(nrach_pdu_rel13->nprach_config_2, ppWritePackedMsg, end));
}
-
-
-static uint8_t pack_ul_tti_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+static uint8_t pack_ul_tti_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
nfapi_nr_ul_tti_request_number_of_pdus_t *value = (nfapi_nr_ul_tti_request_number_of_pdus_t *)tlv;
-
- if(!(push16(value->pdu_size, ppWritePackedMsg, end) &&
- push16(value->pdu_type, ppWritePackedMsg, end) ))
+ uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
+ if (!push16(value->pdu_type, ppWritePackedMsg, end)) {
return 0;
+ }
+ uint8_t *pPackedLengthField = *ppWritePackedMsg;
- // first match the pdu type, then call the respective function
- switch(value->pdu_type) {
+ if (!push16(value->pdu_size, ppWritePackedMsg, end))
+ return 0;
+ // pack PDUs
+ // first match the pdu type, then call the respective function
+ switch (value->pdu_type) {
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
- if(!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
+ if (!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
return 0;
- }
- break;
+ } break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
- if(!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
+ if (!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
return 0;
- }
- break;
+ } break;
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
- if(!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
+ if (!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
return 0;
- }
- break;
+ } break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
- if(!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
+ if (!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
return 0;
- }
- break;
+ } break;
default: {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type );
- }
- break;
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type);
+ } break;
}
- return 1;
+ // pack proper size
+ uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
+ uint16_t packedMsgLen = msgEnd - msgHead;
+ value->pdu_size = packedMsgLen;
+ return push16(value->pdu_size, &pPackedLengthField, end);
}
static uint8_t pack_ul_tti_groups_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
@@ -1577,9 +1653,23 @@ static uint8_t pack_ul_config_request_body_value(void *tlv, uint8_t **ppWritePac
return 1;
}
-
-static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
+ pNfapiMsg->n_ulcch = 0;
+ pNfapiMsg->n_ulsch = 0;
+ for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
+ switch ((&pNfapiMsg->pdus_list[i])->pdu_type) {
+ case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
+ pNfapiMsg->n_ulcch++;
+ } break;
+ case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
+ pNfapiMsg->n_ulsch++;
+ } break;
+ default:
+ break;
+ }
+ }
if (!push16(pNfapiMsg->SFN, ppWritePackedMsg, end))
return 0;
@@ -1587,29 +1677,28 @@ static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_
return 0;
if (!push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end))
return 0;
- if (!push8(pNfapiMsg->n_group, ppWritePackedMsg, end))
- return 0;
if (!push8(pNfapiMsg->rach_present, ppWritePackedMsg, end))
return 0;
if (!push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end))
return 0;
if (!push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end))
return 0;
+ if (!push8(pNfapiMsg->n_group, ppWritePackedMsg, end))
+ return 0;
- for(int i=0; in_pdus; i++) {
- if(!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
+ for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
+ if (!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
return 0;
}
- for(int i=0; in_group; i++) {
- if(!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
+ for (int i = 0; i < pNfapiMsg->n_group; i++) {
+ if (!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
return 0;
}
return 1;
}
-
static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t *)msg;
return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
@@ -1810,45 +1899,87 @@ static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePacke
return 1;
}
-static uint8_t pack_ul_dci_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+static uint8_t pack_ul_dci_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
- nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)tlv;
- for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
- {
- if(!(push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, ppWritePackedMsg, end) &&
- push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
+ nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)tlv;
+ uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
+ if (!push16(value->PDUType, ppWritePackedMsg, end)) {
+ return 0;
+ }
+ uint8_t *pPackedLengthField = *ppWritePackedMsg;
+ if (!(push16(value->PDUSize, ppWritePackedMsg, end) && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end)
+ && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end)
+ && pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end)
+ && push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, ppWritePackedMsg, end)
+ && push16(value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
+ if (!(push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, ppWritePackedMsg, end)
+ && push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, ppWritePackedMsg, end)
+ && push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ // Precoding and Beamforming
+ // TODO get these values from elsewhere and delete the hardcoded ones
+ value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs = 0;
+ value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prg_size = 0;
+ value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces = 0;
+ value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[0].pm_idx = 0;
+ value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
- push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
-
- push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
- push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
- pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end)))
-
- return 0;
- }
-
- return (push16(value->PDUType, ppWritePackedMsg, end) &&
- push16(value->PDUSize, ppWritePackedMsg, end) &&
- push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end) &&
- push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end) &&
-
- push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end) &&
- pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end) &&
-
- push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end) &&
- push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end) &&
- push8(value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, ppWritePackedMsg, end) &&
- push16(value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end));
+ if (!(push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs, ppWritePackedMsg, end)
+ && push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prg_size, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ for (int prg = 0; prg < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
+ if (!push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx,
+ ppWritePackedMsg,
+ end)) {
+ return 0;
+ }
+ for (int digInt = 0; digInt < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces;
+ digInt++) {
+ if (!push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i]
+ .precodingAndBeamforming.prgs_list[prg]
+ .dig_bf_interface_list[digInt]
+ .beam_idx,
+ ppWritePackedMsg,
+ end)) {
+ return 0;
+ }
+ }
+ }
+ if (!(push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end)
+ && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
+ // DCI Payload fields
+ push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
+ // Pack DCI Payload
+ pack_dci_payload(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload,
+ value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits,
+ ppWritePackedMsg,
+ end))) {
+ return 0;
+ }
+ }
+ // pack proper size
+ uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
+ uint16_t packedMsgLen = msgEnd - msgHead;
+ value->PDUSize = packedMsgLen;
+ return push16(value->PDUSize, &pPackedLengthField, end);
}
static uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
@@ -1878,40 +2009,32 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8
}
//pack_tx_data_pdu_list_value
-static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
-
- if(!(push32(value->num_TLV, ppWritePackedMsg, end) &&
- push16(value->PDU_index, ppWritePackedMsg, end) &&
- push16(value->PDU_length, ppWritePackedMsg, end)
- ))
+ if (!(push16(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
+ && push32(value->num_TLV, ppWritePackedMsg, end)))
return 0;
uint16_t i = 0;
uint16_t total_number_of_tlvs = value->num_TLV;
- for(; i < total_number_of_tlvs; ++i) {
- if (!(push16(value->TLVs[i].length, ppWritePackedMsg, end) &&
- push16(value->TLVs[i].tag, ppWritePackedMsg, end)))
+ for (; i < total_number_of_tlvs; ++i) {
+ if (!(push16(value->TLVs[i].tag, ppWritePackedMsg, end) && push16(value->TLVs[i].length, ppWritePackedMsg, end)))
return 0;
- switch(value->TLVs[i].tag) {
+ switch (value->TLVs[i].tag) {
case 0: {
- if (!pusharray32(value->TLVs[i].value.direct, sizeof(value->TLVs[i].value.direct) / sizeof(uint32_t),
- value->TLVs[i].length / sizeof(uint32_t), ppWritePackedMsg, end)) {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n",
- __FUNCTION__, __LINE__, value->TLVs[i].length);
+ if (!pusharray32(value->TLVs[i].value.direct, 16384, (value->TLVs[i].length + 3) / 4, ppWritePackedMsg, end)) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
return 0;
}
-
break;
}
case 1: {
- if (!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length / sizeof(uint32_t),
- value->TLVs[i].length / sizeof(uint32_t), ppWritePackedMsg, end)) {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n",
- __FUNCTION__, __LINE__, value->TLVs[i].length);
+ if (!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length, value->TLVs[i].length, ppWritePackedMsg, end)) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
return 0;
}
@@ -1919,7 +2042,7 @@ static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg
}
default: {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag );
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag);
break;
}
}
@@ -1971,19 +2094,25 @@ static uint8_t pack_tx_request_body_value(void *tlv, uint8_t **ppWritePackedMsg,
return 1;
}
-static uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
+static uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
- if (!(
- push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
- push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
- push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)
- ))
+ if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
+ && push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)))
return 0;
- for(int i=0; iNumber_of_PDUs; i++) {
- if(!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end))
+ for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
+ if (!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end)) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR,
+ "%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
+ __FUNCTION__,
+ __LINE__,
+ i,
+ pNfapiMsg->pdu_list[i].PDU_length,
+ pNfapiMsg->pdu_list[i].PDU_index);
return 0;
+ }
}
return 1;
@@ -3034,79 +3163,84 @@ return 1;
static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
- if(!(push32(value->handle, ppWritePackedMsg, end) &&
- push16(value->rnti, ppWritePackedMsg, end) &&
- push8(value->harq_id, ppWritePackedMsg, end) &&
- push16(value->pdu_length, ppWritePackedMsg, end) &&
- push8(value->ul_cqi, ppWritePackedMsg, end) &&
- push16(value->timing_advance, ppWritePackedMsg, end) &&
- push16(value->rssi, ppWritePackedMsg, end)
- ))
- return 0;
+ if(!(push32(value->handle, ppWritePackedMsg, end) &&
+ push16(value->rnti, ppWritePackedMsg, end) &&
+ push8(value->harq_id, ppWritePackedMsg, end) &&
+ push16(value->pdu_length, ppWritePackedMsg, end) &&
+ push8(value->ul_cqi, ppWritePackedMsg, end) &&
+ push16(value->timing_advance, ppWritePackedMsg, end) &&
+ push16(value->rssi, ppWritePackedMsg, end)
+ ))
+ return 0;
- if(pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
- return 0;
+ if(pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
+ return 0;
- return 1;
+ return 1;
}
static uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
- nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t*)msg;
+ nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t*)msg;
- if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) &&
- push16(pNfapiMsg->slot , ppWritePackedMsg, end) &&
- push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)
- ))
- return 0;
+ if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->slot , ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)
+ ))
+ return 0;
- for (int i = 0; i < pNfapiMsg->number_of_pdus; i++)
- {
- if(!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
- return 0;
- }
+ for (int i = 0; i < pNfapiMsg->number_of_pdus; i++)
+ {
+ if(!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
+ return 0;
+ }
- return 1;
+ return 1;
}
//NR CRC INDICATION
-static uint8_t pack_nr_crc_indication_body(nfapi_nr_crc_t* value, uint8_t **ppWritePackedMsg, uint8_t *end)
+static uint8_t pack_nr_crc_indication_body(nfapi_nr_crc_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
-
- if(!(push32(value->handle, ppWritePackedMsg, end) &&
- push16(value->rnti, ppWritePackedMsg, end) &&
- push8(value->harq_id, ppWritePackedMsg, end) &&
- push8(value->tb_crc_status, ppWritePackedMsg, end) &&
- push16(value->num_cb, ppWritePackedMsg, end) &&
- //pusharray8(value->cb_crc_status, (int)(value->num_cb / 8) + 1, (int)(value->num_cb / 8) + 1, ppWritePackedMsg, end) && //length is ceil(NumCb/8)
- push8(value->ul_cqi, ppWritePackedMsg, end) &&
- push16(value->timing_advance, ppWritePackedMsg, end) &&
- push16(value->rssi, ppWritePackedMsg, end)
- ))
- return 0;
-
- return 1;
+ if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
+ && push8(value->harq_id, ppWritePackedMsg, end) && push8(value->tb_crc_status, ppWritePackedMsg, end)
+ && push16(value->num_cb, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ if (value->num_cb != 0) {
+ if (!pusharray8(value->cb_crc_status,
+ (int)(value->num_cb / 8) + 1,
+ (int)(value->num_cb / 8) + 1,
+ ppWritePackedMsg,
+ end)) { // length is ceil(NumCb/8)
+ return 0;
+ }
+ }
+ if (!(push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
+ && push16(value->rssi, ppWritePackedMsg, end))) {
+ return 0;
+ }
+ return 1;
}
static uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
- nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t*)msg;
+ nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t*)msg;
- if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) &&
- push16(pNfapiMsg->slot , ppWritePackedMsg, end) &&
- push16(pNfapiMsg->number_crcs, ppWritePackedMsg, end)
- ))
- return 0;
+ if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->slot , ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->number_crcs, ppWritePackedMsg, end)
+ ))
+ return 0;
- for (int i = 0; i < pNfapiMsg->number_crcs; i++)
- {
- if(!pack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppWritePackedMsg, end))
- return 0;
- }
+ for (int i = 0; i < pNfapiMsg->number_crcs; i++)
+ {
+ if(!pack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppWritePackedMsg, end))
+ return 0;
+ }
-return 1;
+ return 1;
}
//SRS INDICATION
@@ -3287,7 +3421,7 @@ return 1;
//UCI INDICATION
static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
- nfapi_nr_uci_pucch_pdu_format_0_1_t* value = (nfapi_nr_uci_pucch_pdu_format_0_1_t*)tlv;
+ nfapi_nr_uci_pucch_pdu_format_0_1_t* value = (nfapi_nr_uci_pucch_pdu_format_0_1_t*)tlv;
if (!push8(value->pduBitmap, ppWritePackedMsg, end))
return 0;
@@ -3322,123 +3456,192 @@ static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint
}
}
- return 1;
+ return 1;
}
static uint8_t pack_nr_uci_pucch_2_3_4(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
- nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t*) tlv;
+ nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t*) tlv;
- if (!push8(value->pduBitmap, ppWritePackedMsg, end))
- return 0;
- if (!push32(value->handle, ppWritePackedMsg, end))
- return 0;
- if (!push16(value->rnti, ppWritePackedMsg, end))
- return 0;
- if (!push8(value->pucch_format, ppWritePackedMsg, end))
- return 0;
- if (!push8(value->ul_cqi, ppWritePackedMsg, end))
- return 0;
- if (!push16(value->timing_advance, ppWritePackedMsg, end))
- return 0;
- if (!push16(value->rssi, ppWritePackedMsg, end))
- return 0;
+ if (!push8(value->pduBitmap, ppWritePackedMsg, end))
+ return 0;
+ if (!push32(value->handle, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->rnti, ppWritePackedMsg, end))
+ return 0;
+ if (!push8(value->pucch_format-2, ppWritePackedMsg, end))
+ return 0;
+ if (!push8(value->ul_cqi, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->timing_advance, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->rssi, ppWritePackedMsg, end))
+ return 0;
- if (value->pduBitmap & 0x01) { //SR
- if (!push16(value->sr.sr_bit_len, ppWritePackedMsg, end))
- return 0;
- if (!pusharray8(value->sr.sr_payload,
- (int)((value->sr.sr_bit_len / 8) + 1),
- (int)((value->sr.sr_bit_len / 8) + 1),
- ppWritePackedMsg,
- end))
- return 0;
- }
+ if (value->pduBitmap & 0x01) { //SR
+ if (!push16(value->sr.sr_bit_len, ppWritePackedMsg, end))
+ return 0;
+ if (!pusharray8(value->sr.sr_payload,
+ (int)((value->sr.sr_bit_len / 8) + 1),
+ (int)((value->sr.sr_bit_len / 8) + 1),
+ ppWritePackedMsg,
+ end))
+ return 0;
+ }
- if ((value->pduBitmap >> 1) & 0x01) { //HARQ
- if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
- return 0;
- if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
- return 0;
- if (!pusharray8(value->harq.harq_payload,
- (int)((value->harq.harq_bit_len / 8) + 1),
- (int)((value->harq.harq_bit_len / 8) + 1),
- ppWritePackedMsg,
- end))
- return 0;
- }
+ if ((value->pduBitmap >> 1) & 0x01) { //HARQ
+ if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
+ return 0;
+ if (!pusharray8(value->harq.harq_payload,
+ (int)((value->harq.harq_bit_len / 8) + 1),
+ (int)((value->harq.harq_bit_len / 8) + 1),
+ ppWritePackedMsg,
+ end))
+ return 0;
+ }
- if ((value->pduBitmap >> 2) & 0x01) { //CSI-1
- if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
- return 0;
- if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
- return 0;
- if (!pusharray8(value->csi_part1.csi_part1_payload,
- (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
- (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
- ppWritePackedMsg,
- end))
- return 0;
- }
+ if ((value->pduBitmap >> 2) & 0x01) { //CSI-1
+ if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
+ return 0;
+ if (!pusharray8(value->csi_part1.csi_part1_payload,
+ (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+ (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+ ppWritePackedMsg,
+ end))
+ return 0;
+ }
- if ((value->pduBitmap >> 3) & 0x01) { //CSI-2
- if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
- return 0;
- if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
- return 0;
- if (!pusharray8(value->csi_part2.csi_part2_payload,
- (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
- (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
- ppWritePackedMsg,
- end))
- return 0;
- }
+ if ((value->pduBitmap >> 3) & 0x01) { //CSI-2
+ if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
+ return 0;
+ if (!pusharray8(value->csi_part2.csi_part2_payload,
+ (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+ (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+ ppWritePackedMsg,
+ end))
+ return 0;
+ }
- return 1;
+ return 1;
+}
+
+static uint8_t pack_nr_uci_pusch(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_uci_pusch_pdu_t *value = (nfapi_nr_uci_pusch_pdu_t *)tlv;
+
+ if (!push8(value->pduBitmap, ppWritePackedMsg, end))
+ return 0;
+ if (!push32(value->handle, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->rnti, ppWritePackedMsg, end))
+ return 0;
+ if (!push8(value->ul_cqi, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->timing_advance, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->rssi, ppWritePackedMsg, end))
+ return 0;
+
+ // Bit 0 not used in PUSCH PDU
+ if ((value->pduBitmap >> 1) & 0x01) { // HARQ
+ if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
+ return 0;
+
+ if (!pusharray8(value->harq.harq_payload,
+ (int)((value->harq.harq_bit_len / 8) + 1),
+ (int)((value->harq.harq_bit_len / 8) + 1),
+ ppWritePackedMsg,
+ end))
+ return 0;
+ }
+
+ if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
+ if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
+ return 0;
+
+ if (!pusharray8(value->csi_part1.csi_part1_payload,
+ (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+ (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+ ppWritePackedMsg,
+ end))
+ return 0;
+ }
+
+ if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
+ if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
+ return 0;
+
+ if (!pusharray8(value->csi_part2.csi_part2_payload,
+ (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+ (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+ ppWritePackedMsg,
+ end))
+ return 0;
+ }
+
+ return 1;
}
static uint8_t pack_nr_uci_indication_body(nfapi_nr_uci_t* value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
- if (!push16(value->pdu_type, ppWritePackedMsg, end))
- return 0;
- if (!push16(value->pdu_size, ppWritePackedMsg, end))
- return 0;
+ if (!push16(value->pdu_type, ppWritePackedMsg, end))
+ return 0;
+ if (!push16(value->pdu_size, ppWritePackedMsg, end))
+ return 0;
- switch (value->pdu_type) {
- case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
- NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n");
- break;
+ switch (value->pdu_type) {
+ case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
+ if(!pack_nr_uci_pusch(&value->pusch_pdu, ppWritePackedMsg, end)){
+ return 0;
+ }
+ break;
- case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
- pack_nr_uci_pucch_0_1(&value->pucch_pdu_format_0_1, ppWritePackedMsg, end);
- break;
+ case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
+ if(!pack_nr_uci_pucch_0_1(&value->pucch_pdu_format_0_1, ppWritePackedMsg, end)){
+ return 0;
+ }
+ break;
- case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
- pack_nr_uci_pucch_2_3_4(&value->pucch_pdu_format_2_3_4, ppWritePackedMsg, end);
- break;
- }
+ case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
+ if(!pack_nr_uci_pucch_2_3_4(&value->pucch_pdu_format_2_3_4, ppWritePackedMsg, end)){
+ return 0;
+ }
+ break;
+ }
- return 1;
+ return 1;
}
static uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
- nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t*)msg;
+ nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t*)msg;
- if (!push16(pNfapiMsg->sfn , ppWritePackedMsg, end))
- return 0;
- if (!push16(pNfapiMsg->slot , ppWritePackedMsg, end))
- return 0;
- if (!push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end))
- return 0;
+ if (!push16(pNfapiMsg->sfn , ppWritePackedMsg, end))
+ return 0;
+ if (!push16(pNfapiMsg->slot , ppWritePackedMsg, end))
+ return 0;
+ if (!push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end))
+ return 0;
- for (int i = 0; i < pNfapiMsg->num_ucis; i++)
- {
- if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end))
- return 0;
+ for (int i = 0; i < pNfapiMsg->num_ucis; i++)
+ {
+ if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end))
+ return 0;
- }
+ }
-return 1;
+ return 1;
}
@@ -3446,95 +3649,95 @@ return 1;
int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config)
{
-nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
-uint8_t *pWritePackedMessage = pPackedBuf;
-uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+ nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
+ uint8_t *pWritePackedMessage = pPackedBuf;
+ uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-if (pMessageBuf == NULL || pPackedBuf == NULL) {
+ if (pMessageBuf == NULL || pPackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
return -1;
-}
+ }
-uint8_t *end = (uint8_t *)pPackedBuf + packedBufLen;
+ uint8_t *end = (uint8_t *)pPackedBuf + packedBufLen;
-// process the header
-if (!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && push16(pMessageHeader->message_id, &pWritePackedMessage, end)
- && push16(0 /*pMessageHeader->message_length*/, &pWritePackedMessage, end)
- && push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end)
- && push32(0 /*pMessageHeader->checksum*/, &pWritePackedMessage, end)
- && push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) {
+ // process the header
+ if (!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && push16(pMessageHeader->message_id, &pWritePackedMessage, end)
+ && push16(0 /*pMessageHeader->message_length*/, &pWritePackedMessage, end)
+ && push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end)
+ && push32(0 /*pMessageHeader->checksum*/, &pWritePackedMessage, end)
+ && push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
return -1;
-}
+ }
-if (pMessageHeader->message_id != NFAPI_TIMING_INFO) {
+ if (pMessageHeader->message_id != NFAPI_TIMING_INFO) {
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__,
// pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
-}
-// look for the specific message
-uint8_t result = 0;
-switch (pMessageHeader->message_id) {
+ }
+ // look for the specific message
+ uint8_t result = 0;
+ switch (pMessageHeader->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
- result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
- result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
- result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
- result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_UE_RELEASE_REQUEST:
- result = pack_nr_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_UE_RELEASE_RESPONSE:
- result = pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
- result = pack_nr_slot_indication(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_slot_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
- result = pack_nr_rx_data_indication(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_rx_data_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
- result = pack_nr_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
- result = pack_nr_uci_indication(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_uci_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
- result = pack_nr_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
- result = pack_nr_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
- result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
- result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_TIMING_INFO:
- result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
- break;
+ result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
default: {
- if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+ if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
if (config && config->pack_p7_vendor_extension) {
result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
} else {
@@ -3543,47 +3746,47 @@ switch (pMessageHeader->message_id) {
__FUNCTION__,
pMessageHeader->message_id);
}
- } else {
+ } else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
- }
+ }
} break;
-}
+ }
-if (result == 0) {
+ if (result == 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
return -1;
-}
+ }
-// check for a valid message length
-uintptr_t msgHead = (uintptr_t)pPackedBuf;
-uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
-uint32_t packedMsgLen = msgEnd - msgHead;
-uint16_t packedMsgLen16;
-if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
+ // check for a valid message length
+ uintptr_t msgHead = (uintptr_t)pPackedBuf;
+ uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
+ uint32_t packedMsgLen = msgEnd - msgHead;
+ uint16_t packedMsgLen16;
+ if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
return -1;
-} else {
+ } else {
packedMsgLen16 = (uint16_t)packedMsgLen;
-}
+ }
-// Update the message length in the header
-pMessageHeader->message_length = packedMsgLen16;
+ // Update the message length in the header
+ pMessageHeader->message_length = packedMsgLen16;
-if (!push16(packedMsgLen16, &pPackedLengthField, end))
+ if (!push16(packedMsgLen16, &pPackedLengthField, end))
return -1;
-if (1) {
+ if (1) {
// quick test
if (pMessageHeader->message_length != packedMsgLen) {
- NFAPI_TRACE(NFAPI_TRACE_ERROR,
- "nfapi packedMsgLen(%d) != message_length(%d) id %d\n",
- packedMsgLen,
- pMessageHeader->message_length,
- pMessageHeader->message_id);
+ NFAPI_TRACE(NFAPI_TRACE_ERROR,
+ "nfapi packedMsgLen(%d) != message_length(%d) id %d\n",
+ packedMsgLen,
+ pMessageHeader->message_length,
+ pMessageHeader->message_id);
}
-}
+ }
-return (packedMsgLen);
+ return (packedMsgLen);
}
int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config) {
@@ -3751,122 +3954,179 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
// Unpack routines
// NR:
-static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
- return(
- pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) &&
- pull8(ppReadPackedMsg, &value->cyclic_prefix, end) &&
- pull16(ppReadPackedMsg, &value->start_rb, end) &&
- pull16(ppReadPackedMsg, &value->nr_of_rbs, end) &&
- pull8(ppReadPackedMsg, &value->csi_type, end) &&
- pull8(ppReadPackedMsg, &value->row, end) &&
- pull16(ppReadPackedMsg, &value->freq_domain, end) &&
- pull8(ppReadPackedMsg, &value->symb_l0, end) &&
- pull8(ppReadPackedMsg, &value->symb_l1, end) &&
- pull8(ppReadPackedMsg, &value->cdm_type, end) &&
- pull8(ppReadPackedMsg, &value->freq_density, end) &&
- pull16(ppReadPackedMsg, &value->scramb_id, end) &&
- pull8(ppReadPackedMsg, &value->power_control_offset, end) &&
- pull8(ppReadPackedMsg, &value->power_control_offset_ss, end)
- );
+ uint16_t num_prgs = 0, prg_size = 0;
+ uint8_t dig_bf_interfaces = 0;
+ return (pull16(ppReadPackedMsg, &value->bwp_size, end) && pull16(ppReadPackedMsg, &value->bwp_start, end)
+ && pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &value->cyclic_prefix, end)
+ && pull16(ppReadPackedMsg, &value->start_rb, end) && pull16(ppReadPackedMsg, &value->nr_of_rbs, end)
+ && pull8(ppReadPackedMsg, &value->csi_type, end) && pull8(ppReadPackedMsg, &value->row, end)
+ && pull16(ppReadPackedMsg, &value->freq_domain, end) && pull8(ppReadPackedMsg, &value->symb_l0, end)
+ && pull8(ppReadPackedMsg, &value->symb_l1, end) && pull8(ppReadPackedMsg, &value->cdm_type, end)
+ && pull8(ppReadPackedMsg, &value->freq_density, end) && pull16(ppReadPackedMsg, &value->scramb_id, end)
+ && pull8(ppReadPackedMsg, &value->power_control_offset, end)
+ && pull8(ppReadPackedMsg, &value->power_control_offset_ss, end) &&
+ // Precoding and Beamforming hardcoded to 0
+ pull16(ppReadPackedMsg, &num_prgs, end) && pull16(ppReadPackedMsg, &prg_size, end)
+ && pull8(ppReadPackedMsg, &dig_bf_interfaces, end));
}
+static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
-static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+ if (!(pull16(ppReadPackedMsg, &value->BWPSize, end) && pull16(ppReadPackedMsg, &value->BWPStart, end)
+ && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && pull8(ppReadPackedMsg, &value->CyclicPrefix, end)
+ && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && pull8(ppReadPackedMsg, &value->DurationSymbols, end)
+ && pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end)
+ && pull8(ppReadPackedMsg, &value->CceRegMappingType, end) && pull8(ppReadPackedMsg, &value->RegBundleSize, end)
+ && pull8(ppReadPackedMsg, &value->InterleaverSize, end) && pull8(ppReadPackedMsg, &value->CoreSetType, end)
+ && pull16(ppReadPackedMsg, &value->ShiftIndex, end) && pull8(ppReadPackedMsg, &value->precoderGranularity, end)
+ && pull16(ppReadPackedMsg, &value->numDlDci, end))) {
+ return 0;
+ }
- nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv;
- for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
- {
- if(!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) &&
- pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end) &&
- pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end) &&
- pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end) &&
- pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end) &&
- pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end) &&
- pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end) &&
- pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end) &&
-
- pullarray8(ppReadPackedMsg, value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, value->dci_pdu[i].PayloadSizeBits, end)))
-
- return 0;
- }
- // TODO: resolve the packaging of array (currently sending a single element)
- return(
- pull16(ppReadPackedMsg, &value->BWPSize, end) &&
- pull16(ppReadPackedMsg, &value->BWPStart, end) &&
- pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
- pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
- pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
- pull8(ppReadPackedMsg, &value->DurationSymbols, end) &&
- pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end) &&
- pull8(ppReadPackedMsg, &value->CceRegMappingType, end) &&
- pull8(ppReadPackedMsg, &value->RegBundleSize, end) &&
- pull8(ppReadPackedMsg, &value->InterleaverSize, end) &&
- pull8(ppReadPackedMsg, &value->CoreSetType, end) &&
- pull16(ppReadPackedMsg, &value->ShiftIndex, end) &&
- pull8(ppReadPackedMsg, &value->precoderGranularity, end) &&
- pull16(ppReadPackedMsg, &value->numDlDci, end));
+ for (uint16_t i = 0; i < value->numDlDci; ++i) {
+ if (!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end)
+ && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end)
+ && pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end)
+ && pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end)
+ && pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.num_prgs, end)
+ && pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.prg_size, end)
+ && pull8(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, end))) {
+ return 0;
+ }
+ for (int prg = 0; prg < value->dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
+ if (!pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx, end)) {
+ return 0;
+ }
+ for (int digInt = 0; digInt < value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces; digInt++) {
+ if (!pull16(ppReadPackedMsg,
+ &value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].dig_bf_interface_list[digInt].beam_idx,
+ end)) {
+ return 0;
+ }
+ }
+ }
+ if (!(pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end)
+ && pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end)
+ && pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end)
+ && unpack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppReadPackedMsg, end))) {
+ return 0;
+ }
+ }
+ // TODO: resolve the packaging of array (currently sending a single element)
+ return 1;
}
-
-
-static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
// TODO: resolve the packaging of array (currently sending a single element)
- return(
- pull16(ppReadPackedMsg, &value->pduBitmap, end) &&
- pull16(ppReadPackedMsg, &value->rnti, end) &&
- pull16(ppReadPackedMsg, &value->pduIndex, end) &&
- pull16(ppReadPackedMsg, &value->BWPSize, end) &&
- pull16(ppReadPackedMsg, &value->BWPStart, end) &&
- pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
- pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
- pull8(ppReadPackedMsg, &value->NrOfCodewords, end) &&
- pullarray16(ppReadPackedMsg, value->targetCodeRate, 2, 1, end) &&
- pullarray8(ppReadPackedMsg, value->qamModOrder, 2, 1, end) &&
- pullarray8(ppReadPackedMsg, value->mcsIndex, 2, 1, end) &&
- pullarray8(ppReadPackedMsg, value->mcsTable, 2, 1, end) &&
- pullarray8(ppReadPackedMsg, value->rvIndex, 2, 1, end) &&
- pullarray32(ppReadPackedMsg, value->TBSize, 2, 1, end) &&
- pull16(ppReadPackedMsg, &value->dataScramblingId, end) &&
- pull8(ppReadPackedMsg, &value->nrOfLayers, end) &&
- pull8(ppReadPackedMsg, &value->transmissionScheme, end) &&
- pull8(ppReadPackedMsg, &value->refPoint, end) &&
- pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) &&
- pull8(ppReadPackedMsg, &value->dmrsConfigType, end) &&
- pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) &&
- pull8(ppReadPackedMsg, &value->SCID, end) &&
- pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) &&
- pull16(ppReadPackedMsg, &value->dmrsPorts, end) &&
- pull8(ppReadPackedMsg, &value->resourceAlloc, end) &&
- pull16(ppReadPackedMsg, &value->rbStart, end) &&
- pull16(ppReadPackedMsg, &value->rbSize, end) &&
- pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) &&
- pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
- pull8(ppReadPackedMsg, &value->NrOfSymbols, end) &&
- pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) &&
- pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end) &&
- pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) &&
- pull8(ppReadPackedMsg, &value->PTRSReOffset, end)
- );
+ uint8_t powerControlOffset = 0, powerControlOffsetSS = 0;
+
+ if (!(pull16(ppReadPackedMsg, &value->pduBitmap, end) && pull16(ppReadPackedMsg, &value->rnti, end)
+ && pull16(ppReadPackedMsg, &value->pduIndex, end) && pull16(ppReadPackedMsg, &value->BWPSize, end)
+ && pull16(ppReadPackedMsg, &value->BWPStart, end) && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end)
+ && pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && pull8(ppReadPackedMsg, &value->NrOfCodewords, end))) {
+ return 0;
+ }
+ for (int i = 0; i < value->NrOfCodewords; ++i) {
+ if (!(pull16(ppReadPackedMsg, &value->targetCodeRate[i], end) && pull8(ppReadPackedMsg, &value->qamModOrder[i], end)
+ && pull8(ppReadPackedMsg, &value->mcsIndex[i], end) && pull8(ppReadPackedMsg, &value->mcsTable[i], end)
+ && pull8(ppReadPackedMsg, &value->rvIndex[i], end) && pull32(ppReadPackedMsg, &value->TBSize[i], end))) {
+ return 0;
+ }
+ }
+
+ if (!(pull16(ppReadPackedMsg, &value->dataScramblingId, end) && pull8(ppReadPackedMsg, &value->nrOfLayers, end)
+ && pull8(ppReadPackedMsg, &value->transmissionScheme, end) && pull8(ppReadPackedMsg, &value->refPoint, end)
+ && pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) && pull8(ppReadPackedMsg, &value->dmrsConfigType, end)
+ && pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) && pull8(ppReadPackedMsg, &value->SCID, end)
+ && pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) && pull16(ppReadPackedMsg, &value->dmrsPorts, end)
+ && pull8(ppReadPackedMsg, &value->resourceAlloc, end) && pullarray8(ppReadPackedMsg, &value->rbBitmap[0], 36, 36, end)
+ && pull16(ppReadPackedMsg, &value->rbStart, end) && pull16(ppReadPackedMsg, &value->rbSize, end)
+ && pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end)
+ && pull8(ppReadPackedMsg, &value->NrOfSymbols, end))) {
+ return 0;
+ }
+ // Check pduBitMap bit 1 to pull PTRS parameters or not
+ if (value->pduBitmap & 0b1) {
+ if (!(pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) && pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end)
+ && pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) && pull8(ppReadPackedMsg, &value->PTRSReOffset, end)
+ && pull8(ppReadPackedMsg, &value->nEpreRatioOfPDSCHToPTRS, end))) {
+ return 0;
+ }
+ }
+
+ if (!(pull16(ppReadPackedMsg, &value->precodingAndBeamforming.num_prgs, end)
+ && pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prg_size, end)
+ && pull8(ppReadPackedMsg, &value->precodingAndBeamforming.dig_bf_interfaces, end))) {
+ return 0;
+ }
+
+ for (int i = 0; i < value->precodingAndBeamforming.num_prgs; ++i) {
+ if (!pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prgs_list[i].pm_idx, end)) {
+ return 0;
+ }
+ for (int k = 0; k < value->precodingAndBeamforming.dig_bf_interfaces; ++k) {
+ if (!pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, end)) {
+ return 0;
+ }
+ }
+ }
+ // TODO Add TX power info
+ // Hardcoded values that represent 0db
+
+ if (!(pull8(ppReadPackedMsg, &powerControlOffset, end) && // powerControlOffset
+ pull8(ppReadPackedMsg, &powerControlOffsetSS, end))) { // powerControlOffsetSS
+ return 0;
+ }
+ // TODO Add CBG Fields
+ return 1;
}
-
-static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Unpacking ssb. \n");
+ uint8_t byte3, byte2, byte1, byte0;
nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
- return(
- pull16(ppReadPackedMsg, &value->PhysCellId, end) &&
- pull8(ppReadPackedMsg, &value->BetaPss, end) &&
- pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) &&
- pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) &&
- pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) &&
- pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) &&
- pull32(ppReadPackedMsg, &value->bchPayload, end) &&
- pull8(ppReadPackedMsg, &value->ssbRsrp, end)
- // TODO: pack precoding_and_beamforming too
- );
-}
+ if (!(pull16(ppReadPackedMsg, &value->PhysCellId, end) && pull8(ppReadPackedMsg, &value->BetaPss, end)
+ && pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) && pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end)
+ && pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && pull8(ppReadPackedMsg, &value->bchPayloadFlag, end)
+ && pull8(ppReadPackedMsg, &byte3, end) && pull8(ppReadPackedMsg, &byte2, end) && pull8(ppReadPackedMsg, &byte1, end)
+ && pull8(ppReadPackedMsg, &byte0, end))) { // this should be always 0, bchpayload is 24 bits
+ return 0;
+ }
+ // rebuild the bchpayload
+ value->bchPayload = byte3;
+ value->bchPayload = value->bchPayload << 8;
+ value->bchPayload |= byte2;
+ value->bchPayload = value->bchPayload << 8;
+ value->bchPayload |= byte1;
+ // TODO add Tx Power Info
+ if (!(pull8(ppReadPackedMsg, &byte1, end) && pull8(ppReadPackedMsg, &byte0, end)
+ && pull16(ppReadPackedMsg, &value->precoding_and_beamforming.num_prgs, end)
+ && pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prg_size, end)
+ && pull8(ppReadPackedMsg, &value->precoding_and_beamforming.dig_bf_interfaces, end))) {
+ return 0;
+ }
+
+ for (int i = 0; i < value->precoding_and_beamforming.num_prgs; ++i) {
+ if (!pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prgs_list[i].pm_idx, end)) {
+ return 0;
+ }
+ for (int k = 0; k < value->precoding_and_beamforming.dig_bf_interfaces; ++k) {
+ if (!pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, end)) {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
// LTE:
static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
@@ -4260,8 +4520,8 @@ static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppRe
static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)msg;
- if(!(pull32(ppReadPackedMsg, &value->PDUSize, end) &&
- pull16(ppReadPackedMsg, &value->PDUType, end) ))
+ if(!(pull16(ppReadPackedMsg, &value->PDUType, end) &&
+ pull16(ppReadPackedMsg, (uint16_t *) &value->PDUSize, end)))
return 0;
// first match the pdu type, then call the respective function
@@ -4470,189 +4730,180 @@ static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPa
return 1;
}
-
-static uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+static uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
- if (!(pull16(ppReadPackedMsg,&pNfapiMsg->SFN, end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
- pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end) &&
- pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end) &&
- pullarray8(ppReadPackedMsg,pNfapiMsg->dl_tti_request_body.nUe,256,pNfapiMsg->dl_tti_request_body.nGroup, end)
- //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end)
- ))
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
+ && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end)
+ && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end))) {
return 0;
+ }
+ for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
+ if (!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
+ return 0;
+ }
int arr[12];
-
- for(int i=0; idl_tti_request_body.nGroup; i++) {
- for(int j=0; jdl_tti_request_body.nUe[i]; j++) {
+ if (!pullarray8(ppReadPackedMsg, pNfapiMsg->dl_tti_request_body.nUe, 256, pNfapiMsg->dl_tti_request_body.nGroup, end)) {
+ return 0;
+ }
+ for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
+ for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j];
}
- if(!(pullarrays32(ppReadPackedMsg,arr,12,pNfapiMsg->dl_tti_request_body.nUe[i], end)))
- return 0;
- }
-
- for(int i=0; idl_tti_request_body.nPDUs; i++) {
- if(!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
+ if (!(pullarrays32(ppReadPackedMsg, arr, 12, pNfapiMsg->dl_tti_request_body.nUe[i], end)))
return 0;
}
return 1;
}
-
-static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
nfapi_nr_prach_pdu_t *prach_pdu = (nfapi_nr_prach_pdu_t *)tlv;
- return(
- pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) &&
- pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end) &&
- pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) &&
- pull8(ppReadPackedMsg, &prach_pdu->num_ra, end) &&
- pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) &&
- pull16(ppReadPackedMsg, &prach_pdu->num_cs, end)
- // TODO: ignoring beamforming tlv for now
- );
+
+ if (!(pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) && pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end)
+ && pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) && pull8(ppReadPackedMsg, &prach_pdu->num_ra, end)
+ && pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) && pull16(ppReadPackedMsg, &prach_pdu->num_cs, end))) {
+ return 0;
+ }
+ // TODO: ignoring beamforming tlv for now
+ if (prach_pdu->beamforming.prgs_list == NULL) {
+ prach_pdu->beamforming.prgs_list = calloc(prach_pdu->beamforming.num_prgs, sizeof(*prach_pdu->beamforming.prgs_list));
+ }
+ if (prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) {
+ prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list =
+ calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list));
+ }
+ // Pack RX Beamforming PDU
+ if (!(pull16(ppReadPackedMsg, &prach_pdu->beamforming.num_prgs, end)
+ && pull16(ppReadPackedMsg, &prach_pdu->beamforming.prg_size, end)
+ && pull8(ppReadPackedMsg, &prach_pdu->beamforming.dig_bf_interface, end))) {
+ return 0;
+ }
+ for (int prg = 0; prg < prach_pdu->beamforming.num_prgs; prg++) {
+ for (int digBFInterface = 0; digBFInterface < prach_pdu->beamforming.dig_bf_interface; digBFInterface++) {
+ if (!pull16(ppReadPackedMsg, &prach_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) {
+ return 0;
+ }
+ }
+ }
+
+ return 1;
}
-
-static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
nfapi_nr_pucch_pdu_t *pucch_pdu = (nfapi_nr_pucch_pdu_t *)tlv;
- return(
- pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) &&
- pull32(ppReadPackedMsg, &pucch_pdu->handle, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->pi_2bpsk, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end) &&
- pull8(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end) &&
- pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end)
+ uint16_t dummy16 = 0;
+ uint8_t dummy8 = 0;
+ return (pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) && pull32(ppReadPackedMsg, &pucch_pdu->handle, end)
+ && pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->format_type, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) && pull8(ppReadPackedMsg, &pucch_pdu->pi_2bpsk, end)
+ && pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) && pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) && pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end) && pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end) && pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end)
+ && pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end) && pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end)
+ && pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end) && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end) && pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) && pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end)
+ && pull8(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end)
+ && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end) &&
// TODO: ignoring beamforming tlv for now
- );
+ pull16(ppReadPackedMsg, &dummy16, end) && pull16(ppReadPackedMsg, &dummy16, end) && pull8(ppReadPackedMsg, &dummy8, end));
}
-
-static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
nfapi_nr_pusch_pdu_t *pusch_pdu = (nfapi_nr_pusch_pdu_t *)tlv;
- if (!(
- pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->rnti, end) &&
- pull32(ppReadPackedMsg, &pusch_pdu->handle, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->scid, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc,end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)
+ if (!(pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) && pull16(ppReadPackedMsg, &pusch_pdu->rnti, end)
+ && pull32(ppReadPackedMsg, &pusch_pdu->handle, end) && pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) && pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) && pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->scid, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) && pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end) && pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end) && pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end) && pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) && pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)
// TODO: ignoring beamforming tlv for now
- ))
+ ))
return 0;
- //Pack Optional Data only included if indicated in pduBitmap
- switch(pusch_pdu->pdu_bit_map) {
+ // Pack Optional Data only included if indicated in pduBitmap
+ switch (pusch_pdu->pdu_bit_map) {
case PUSCH_PDU_BITMAP_PUSCH_DATA: {
// pack optional TLVs
- return(
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end) &&
- pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end) &&
- pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position,1,1,end)
- );
- }
- break;
+ if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end)
+ && pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end)
+ && pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position, 1, 1, end))) {
+ return 0;
+ }
+ } break;
case PUSCH_PDU_BITMAP_PUSCH_UCI: {
- return(
- pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end)
- );
- }
- break;
+ if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end))) {
+ return 0;
+ }
+ } break;
case PUSCH_PDU_BITMAP_PUSCH_PTRS: {
- return(
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end)
- );
- }
- break;
+ if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end))) {
+ return 0;
+ }
+ } break;
case PUSCH_PDU_BITMAP_DFTS_OFDM: {
- return(
- pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end) &&
- pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end) &&
- pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end)
- );
- }
- break;
+ if (!(pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end)
+ && pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end)
+ && pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end))) {
+ return 0;
+ }
+ } break;
default: {
- NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map);
}
}
+ uint16_t dummy16 = 0;
+ uint8_t dummy8 = 0;
+ if (!(pull16(ppReadPackedMsg, &dummy16, end) && pull16(ppReadPackedMsg, &dummy16, end) && pull8(ppReadPackedMsg, &dummy8, end))) {
+ return 0;
+ }
return 1;
}
-
static uint8_t unpack_ul_tti_request_srs_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
nfapi_nr_srs_pdu_t *srs_pdu = (nfapi_nr_srs_pdu_t *)tlv;
return(
@@ -4687,8 +4938,8 @@ static uint8_t unpack_ul_tti_request_srs_pdu(void *tlv, uint8_t **ppReadPackedMs
static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
nfapi_nr_ul_tti_request_number_of_pdus_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t *)msg;
- if(!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) ))
+ if(!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end) ))
return 0;
// first natch the pdu type, then call the respective function
@@ -4741,8 +4992,8 @@ static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_
return 1;
}
-
-static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
if (!pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end))
@@ -4751,21 +5002,20 @@ static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, vo
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end))
return 0;
- if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end))
- return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end))
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end))
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end))
return 0;
-
- for(int i=0; i< pNfapiMsg->n_pdus; i++) {
+ if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end))
+ return 0;
+ for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
return 0;
}
- for(int i=0; i< pNfapiMsg->n_group; i++) {
+ for (int i = 0; i < pNfapiMsg->n_group; i++) {
if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
return 0;
}
@@ -4773,8 +5023,6 @@ static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, vo
return 1;
}
-
-
static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg;
unpack_p7_tlv_t unpack_fns[] = {
@@ -5557,43 +5805,66 @@ static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPack
static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
{
- nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)msg;
- for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
- {
- if(!(pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, end) &&
- pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, end) &&
+ nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)msg;
- pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, end) &&
+ if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, &value->PDUSize, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end)
+ && pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end))) {
+ return 0;
+ }
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, end) &&
- pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end) &&
-
- pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end)))
-
- return 0;
- }
-
- return (pull16(ppReadPackedMsg, &value->PDUType, end) &&
- pull16(ppReadPackedMsg, &value->PDUSize, end) &&
- pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end) &&
- pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end) &&
-
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end) &&
- pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end) &&
-
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end) &&
- pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end) &&
- pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end) &&
- pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end));
+ for (uint16_t i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
+ if (!(pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prg_size, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, end))) {
+ return 0;
+ }
+ for (int prg = 0; prg < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
+ if (!pull16(ppReadPackedMsg,
+ &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx,
+ end)) {
+ return 0;
+ }
+ for (int digInt = 0; digInt < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces;
+ digInt++) {
+ if (!pull16(ppReadPackedMsg,
+ &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i]
+ .precodingAndBeamforming.prgs_list[prg]
+ .dig_bf_interface_list[digInt]
+ .beam_idx,
+ end)) {
+ return 0;
+ }
+ }
+ }
+ if (!(pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, end)
+ && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, end)
+ && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end)
+ && unpack_dci_payload(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload,
+ value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits,
+ ppReadPackedMsg,
+ end))) {
+ return 0;
+ }
+ }
+ return 1;
}
static uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
@@ -5624,25 +5895,25 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
- if(!(pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end) &&
+ if(!(pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) &&
pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end)
- ))
+ pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)
+ ))
return 0;
uint16_t i = 0;
uint16_t total_number_of_tlvs = pNfapiMsg->num_TLV;
for(; i < total_number_of_tlvs; ++i) {
- if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end)))
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end)))
return 0;
switch(pNfapiMsg->TLVs[i].tag) {
case 0: {
if (!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct,
- sizeof(pNfapiMsg->TLVs[i].value.direct) / sizeof(uint32_t),
- pNfapiMsg->TLVs[i].length / sizeof(uint32_t), end))
+ sizeof(pNfapiMsg->TLVs[i].value.direct) / sizeof(uint32_t),
+ (pNfapiMsg->TLVs[i].length+3)/4, end))
return 0;
break;
@@ -5650,8 +5921,8 @@ static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t
case 1: {
if (!pullarray32(ppReadPackedMsg,pNfapiMsg->TLVs[i].value.ptr,
- pNfapiMsg->TLVs[i].length / sizeof(uint32_t),
- pNfapiMsg->TLVs[i].length / sizeof(uint32_t), end))
+ pNfapiMsg->TLVs[i].length,
+ pNfapiMsg->TLVs[i].length, end))
return 0;
break;
@@ -5667,17 +5938,25 @@ static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t
return 1;
}
-static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
+static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
- if(!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
+ && pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
return 0;
- for(int i=0; i< pNfapiMsg->Number_of_PDUs; i++) {
- if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i]))
+ for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
+ if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
+ printf("%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
+ __FUNCTION__,
+ __LINE__,
+ i,
+ pNfapiMsg->pdu_list[i].PDU_length,
+ pNfapiMsg->pdu_list[i].PDU_index);
+
return 0;
+ }
}
return 1;
@@ -5787,101 +6066,102 @@ static uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg, uint8_t *end
return 1;
}
-//RX DATA INDICATION
+//RX DATA INDICATION
-static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t* value,
+static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
- nfapi_p7_codec_config_t* config)
+ nfapi_p7_codec_config_t *config)
{
- if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
- pull16(ppReadPackedMsg, &value->rnti, end) &&
- pull8(ppReadPackedMsg, &value->harq_id, end) &&
- pull16(ppReadPackedMsg, &value->pdu_length, end) &&
- pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
- pull16(ppReadPackedMsg, &value->timing_advance, end) &&
- pull16(ppReadPackedMsg, &value->rssi, end)
- ))
- return 0;
+if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
+ && pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, &value->pdu_length, end)
+ && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
+ && pull16(ppReadPackedMsg, &value->rssi, end)))
+ return 0;
- uint16_t length = value->pdu_length;
- value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * length, config);
-
- if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0)
- {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
- return 0;
- }
- return 1;
+uint32_t length = value->pdu_length;
+value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * length, config);
+if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
+ return 0;
+}
+return 1;
}
-
static uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_rx_data_indication_t *msg, nfapi_p7_codec_config_t* config)
{
- nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t*)msg;
+ nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t*)msg;
- if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end)
- ))
- return 0;
- if (pNfapiMsg->number_of_pdus > 0)
- {
- pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config);
- }
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end)
+ ))
+ return 0;
- for (int i = 0; i < pNfapiMsg->number_of_pdus; i++)
- {
- if(!unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
- return 0;
- }
+ if (pNfapiMsg->number_of_pdus > 0)
+ {
+ pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config);
+ }
-return 1;
+ for (int i = 0; i < pNfapiMsg->number_of_pdus; i++)
+ {
+ if(!unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
+ return 0;
+ }
+
+ return 1;
}
//NR CRC INDICATION
-static uint8_t unpack_nr_crc_indication_body(nfapi_nr_crc_t* value, uint8_t **ppReadPackedMsg, uint8_t *end)
+static uint8_t unpack_nr_crc_indication_body(nfapi_nr_crc_t *value, uint8_t **ppReadPackedMsg, uint8_t *end)
{
- if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
- pull16(ppReadPackedMsg, &value->rnti, end) &&
- pull8(ppReadPackedMsg, &value->harq_id, end) &&
- pull8(ppReadPackedMsg, &value->tb_crc_status, end) &&
- pull16(ppReadPackedMsg, &value->num_cb, end) &&
- //pullarray8(ppReadPackedMsg, value->cb_crc_status, (int)(value->num_cb / 8) + 1, (int)(value->num_cb / 8) + 1, end) && //length is ceil(NumCb/8)
- pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
- pull16(ppReadPackedMsg, &value->timing_advance, end) &&
- pull16(ppReadPackedMsg, &value->rssi, end)
- ))
- return 0;
+ if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
+ && pull8(ppReadPackedMsg, &value->harq_id, end) && pull8(ppReadPackedMsg, &value->tb_crc_status, end)
+ && pull16(ppReadPackedMsg, &value->num_cb, end))) {
+ return 0;
+ }
+ if (value->num_cb != 0) {
+ if (!pullarray8(ppReadPackedMsg,
+ value->cb_crc_status,
+ (int)(value->num_cb / 8) + 1,
+ (int)(value->num_cb / 8) + 1,
+ end)) { // length is ceil(NumCb/8)
+ return 0;
+ }
+ }
+ if (!(pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
+ && pull16(ppReadPackedMsg, &value->rssi, end))) {
+ return 0;
+ }
- //memcpy((nfapi_nr_crc_t *)tlv,value,sizeof(nfapi_nr_crc_t));
+ // memcpy((nfapi_nr_crc_t *)tlv,value,sizeof(nfapi_nr_crc_t));
- return 1;
+ return 1;
}
static uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_crc_indication_t *msg, nfapi_p7_codec_config_t* config)
{
- nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t*)msg;
+ nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t*)msg;
- if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->number_crcs, end)
- ))
- return 0;
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->number_crcs, end)
+ ))
+ return 0;
- if (pNfapiMsg->number_crcs > 0)
- {
- pNfapiMsg->crc_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->crc_list) * pNfapiMsg->number_crcs, config);
- }
+ if (pNfapiMsg->number_crcs > 0)
+ {
+ pNfapiMsg->crc_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->crc_list) * pNfapiMsg->number_crcs, config);
+ }
- for (int i = 0; i < pNfapiMsg->number_crcs; i++)
- {
- if(!unpack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppReadPackedMsg, end))
- return 0;
- }
+ for (int i = 0; i < pNfapiMsg->number_crcs; i++)
+ {
+ if(!unpack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppReadPackedMsg, end))
+ return 0;
+ }
-return 1;
+ return 1;
}
//SRS INDICATION
@@ -6009,100 +6289,86 @@ static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end,
//NR RACH
-static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t* value,
+static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
- nfapi_p7_codec_config_t* config)
+ nfapi_p7_codec_config_t *config)
{
+ if (!(pull16(ppReadPackedMsg, &value->phy_cell_id, end) && pull8(ppReadPackedMsg, &value->symbol_index, end)
+ && pull8(ppReadPackedMsg, &value->slot_index, end) && pull8(ppReadPackedMsg, &value->freq_index, end)
+ && pull8(ppReadPackedMsg, &value->avg_rssi, end) && pull8(ppReadPackedMsg, &value->avg_snr, end)
+ && pull8(ppReadPackedMsg, &value->num_preamble, end))) {
+ return 0;
+ }
- if(!(pull16(ppReadPackedMsg, &value->phy_cell_id, end) &&
- pull8(ppReadPackedMsg, &value->symbol_index, end) &&
- pull8(ppReadPackedMsg, &value->slot_index, end) &&
- pull8(ppReadPackedMsg, &value->freq_index, end) &&
- pull8(ppReadPackedMsg, &value->avg_rssi, end) &&
- pull8(ppReadPackedMsg, &value->avg_snr, end) &&
- pull8(ppReadPackedMsg, &value->num_preamble, end)
- ))
- return 0;
-
- if (value->num_preamble > 0) {
- value->preamble_list = nfapi_p7_allocate(sizeof(*value->preamble_list) * value->num_preamble, config);
- for(int i = 0; i < value->num_preamble; i++)
- {
- if(!(pull8(ppReadPackedMsg, &value->preamble_list[i].preamble_index, end) &&
- pull16(ppReadPackedMsg, &value->preamble_list[i].timing_advance, end) &&
- pull32(ppReadPackedMsg, &value->preamble_list[i].preamble_pwr, end)
- ))
- return 0;
- }
- }
- return 1;
+ if (value->num_preamble > 0) {
+ value->preamble_list = nfapi_p7_allocate(sizeof(*value->preamble_list) * value->num_preamble, config);
+ for (int i = 0; i < value->num_preamble; i++) {
+ nfapi_nr_prach_indication_preamble_t *preamble = &(value->preamble_list[i]);
+ if (!(pull8(ppReadPackedMsg, &preamble->preamble_index, end) && pull16(ppReadPackedMsg, &preamble->timing_advance, end)
+ && pull32(ppReadPackedMsg, &preamble->preamble_pwr, end))) {
+ return 0;
+ }
+ }
+ }
+ return 1;
}
-static uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_rach_indication_t* msg, nfapi_p7_codec_config_t* config) {
+static uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
+ uint8_t *end,
+ nfapi_nr_rach_indication_t *msg,
+ nfapi_p7_codec_config_t *config)
+{
+ nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
- nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t*)msg;
- if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) &&
- pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) &&
- pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end)
- ))
- return 0;
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
+ && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
+ return 0;
+ }
- if (pNfapiMsg->number_of_pdus > 0) {
- pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config);
- for(int i = 0; i < pNfapiMsg->number_of_pdus; i++)
- {
- if(!unpack_nr_rach_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
- return 0;
- }
- }
- return 1;
+ if (pNfapiMsg->number_of_pdus > 0) {
+ pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config);
+ for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
+ if (!unpack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppReadPackedMsg, end, config))
+ return 0;
+ }
+ }
+ return 1;
}
-//NR UCI
+//NR UCI
static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
- nfapi_p7_codec_config_t *config) {
+ nfapi_p7_codec_config_t *config)
+{
+ if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end)
+ && pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->pucch_format, end)
+ && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
+ && pull16(ppReadPackedMsg, &value->rssi, end)))
+ return 0;
+ if (value->pduBitmap & 0x01) { // SR
+ if (!(pull8(ppReadPackedMsg, &value->sr.sr_indication, end) && pull8(ppReadPackedMsg, &value->sr.sr_confidence_level, end)))
+ return 0;
+ }
- if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) &&
- pull32(ppReadPackedMsg, &value->handle, end) &&
- pull16(ppReadPackedMsg, &value->rnti, end) &&
- pull8(ppReadPackedMsg, &value->pucch_format, end) &&
- pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
- pull16(ppReadPackedMsg, &value->timing_advance, end) &&
- pull16(ppReadPackedMsg, &value->rssi, end)
- ))
- return 0;
- if (value->pduBitmap & 0x01) { //SR
- if(!(pull8(ppReadPackedMsg, &value->sr.sr_indication, end) &&
- pull8(ppReadPackedMsg, &value->sr.sr_confidence_level, end)
- ))
- return 0;
- }
+ if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
- if (((value->pduBitmap >> 1) & 0x01)) { //HARQ
+ if (!(pull8(ppReadPackedMsg, &value->harq.num_harq, end) && pull8(ppReadPackedMsg, &value->harq.harq_confidence_level, end)))
+ return 0;
+ if (value->harq.num_harq > 0) {
+ for (int i = 0; i < value->harq.num_harq; i++) {
+ if (!pull8(ppReadPackedMsg, &value->harq.harq_list[i].harq_value, end)) {
+ return 0;
+ }
+ }
+ }
+ }
-
- if (!(pull8(ppReadPackedMsg, &value->harq.num_harq, end) &&
- pull8(ppReadPackedMsg, &value->harq.harq_confidence_level, end)
- ))
- return 0;
- if (value->harq.num_harq > 0) {
-
- for (int i = 0; i < value->harq.num_harq; i++) {
- if (!pull8(ppReadPackedMsg, &value->harq.harq_list[i].harq_value, end)) {
- return 0;
- }
- }
- }
- }
-
- return 1;
+ return 1;
}
-
static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
@@ -6123,6 +6389,7 @@ static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t*
if (!pull16(ppReadPackedMsg, &value->rssi, end))
return 0;
+ value->pucch_format += 2;
if (value->pduBitmap & 0x01) { //SR
if (!pull16(ppReadPackedMsg, &value->sr.sr_bit_len, end))
return 0;
@@ -6214,60 +6481,148 @@ static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t*
return 1;
}
+static uint8_t unpack_nr_uci_pusch(nfapi_nr_uci_pusch_pdu_t *value,
+ uint8_t **ppReadPackedMsg,
+ uint8_t *end,
+ nfapi_p7_codec_config_t *config)
+{
+ if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
+ return 0;
+ if (!pull32(ppReadPackedMsg, &value->handle, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &value->rnti, end))
+ return 0;
+ if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &value->rssi, end))
+ return 0;
+
+ // Bit 0 not used in PUSCH PDU
+ if ((value->pduBitmap >> 1) & 0x01) { // HARQ
+ if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
+ return 0;
+
+ value->harq.harq_payload =
+ nfapi_p7_allocate(sizeof(*value->harq.harq_payload) * (int)((value->harq.harq_bit_len / 8) + 1), config);
+ if (value->harq.harq_payload == NULL) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
+ return 0;
+ }
+
+ if (!pullarray8(ppReadPackedMsg,
+ value->harq.harq_payload,
+ (int)((value->harq.harq_bit_len / 8) + 1),
+ (int)((value->harq.harq_bit_len / 8) + 1),
+ end))
+ return 0;
+ }
+
+ if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
+ if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
+ return 0;
+
+ value->csi_part1.csi_part1_payload =
+ nfapi_p7_allocate(sizeof(*value->csi_part1.csi_part1_payload) * (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+ config);
+ if (value->csi_part1.csi_part1_payload == NULL) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
+ return 0;
+ }
+
+ if (!pullarray8(ppReadPackedMsg,
+ value->csi_part1.csi_part1_payload,
+ (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+ (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+ end))
+ return 0;
+ }
+
+ if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
+ if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
+ return 0;
+
+ value->csi_part2.csi_part2_payload =
+ nfapi_p7_allocate(sizeof(*value->csi_part2.csi_part2_payload) * (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+ config);
+ if (value->csi_part2.csi_part2_payload == NULL) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
+ return 0;
+ }
+
+ if (!pullarray8(ppReadPackedMsg,
+ value->csi_part2.csi_part2_payload,
+ (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+ (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+ end))
+ return 0;
+ }
+
+ return 1;
+}
+
static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
- if (!pull16(ppReadPackedMsg, &value->pdu_type, end))
- return 0;
- if (!pull16(ppReadPackedMsg, &value->pdu_size, end))
- return 0;
+ if (!pull16(ppReadPackedMsg, &value->pdu_type, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &value->pdu_size, end))
+ return 0;
- switch (value->pdu_type) {
- case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
- NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n");
- break;
+ switch (value->pdu_type) {
+ case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
+ nfapi_nr_uci_pusch_pdu_t *uci_pdu = &value->pusch_pdu;
+ if (!unpack_nr_uci_pusch(uci_pdu, ppReadPackedMsg, end, config))
+ return 0;
+ break;
+ }
+ case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
+ nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1;
+ if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config))
+ return 0;
+ break;
+ }
+ case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
+ nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4;
+ if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config))
+ return 0;
+ break;
+ }
+ default:
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected pdu type %d\n", value->pdu_type);
+ break;
+ }
- case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
- nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1;
- if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config))
- return 0;
- break;
- }
- case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
- nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4;
- if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config))
- return 0;
- break;
- }
- default:
- NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected pdu type %d\n", value->pdu_type);
- break;
- }
-
- return 1;
+ return 1;
}
-static uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+static uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
- nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t*)msg;
+ nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
- if (!pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end))
- return 0;
- if (!pull16(ppReadPackedMsg, &pNfapiMsg->slot , end))
- return 0;
- if (!pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end))
- return 0;
+ if (!pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &pNfapiMsg->slot, end))
+ return 0;
+ if (!pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end))
+ return 0;
- pNfapiMsg->uci_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->uci_list) * pNfapiMsg->num_ucis, config);
- for (int i = 0; i < pNfapiMsg->num_ucis; i++)
- {
- if (!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
- return 0;
- }
+ pNfapiMsg->uci_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->uci_list) * pNfapiMsg->num_ucis, config);
+ for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
+ if (!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
+ return 0;
+ }
- return 1;
+ return 1;
}
static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
@@ -8093,41 +8448,29 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
result = unpack_dl_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
result = unpack_ul_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
result = unpack_tx_data_request(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
result = unpack_ul_dci_request(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_UE_RELEASE_REQUEST:
if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION, unpackedBufLen)){
nfapi_nr_slot_indication_scf_t* msg = (nfapi_nr_slot_indication_scf_t*) pMessageHeader;
result = unpack_nr_slot_indication(&pReadPackedMessage, end, msg, config);
}
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
@@ -8137,8 +8480,6 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
msg->pdu_list->pdu = (uint8_t *) malloc(sizeof(uint8_t));
result = unpack_nr_rx_data_indication(&pReadPackedMessage, end, msg, config);
}
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
@@ -8148,8 +8489,6 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
msg->crc_list = (nfapi_nr_crc_t*) malloc(sizeof(nfapi_nr_crc_t));
result = unpack_nr_crc_indication(&pReadPackedMessage,end , msg, config);
}
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
@@ -8158,8 +8497,6 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
msg->uci_list = (nfapi_nr_uci_t*) malloc(sizeof(nfapi_nr_uci_t));
result = unpack_nr_uci_indication(&pReadPackedMessage, end, msg, config);
}
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
@@ -8168,8 +8505,6 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
msg->pdu_list = (nfapi_nr_srs_indication_pdu_t*) malloc(sizeof(nfapi_nr_srs_indication_pdu_t));
result = unpack_nr_srs_indication(&pReadPackedMessage, end, msg, config);
}
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
@@ -8177,36 +8512,26 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
nfapi_nr_rach_indication_t* msg = (nfapi_nr_rach_indication_t*) pMessageHeader;
result = unpack_nr_rach_indication(&pReadPackedMessage, end, msg, config);
}
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, unpackedBufLen))
result = unpack_nr_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC, unpackedBufLen))
result = unpack_nr_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_TIMING_INFO:
if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
result = unpack_nr_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
case NFAPI_UE_RELEASE_RESPONSE:
if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
break;
default:
@@ -8230,8 +8555,9 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
break;
}
- if(result == 0)
- return -1;
- else
- return 0;
+ if (result == 0) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
+ return -1;
+ }
+ return 0;
}
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
index a1be4d0edc..dd91d2fc71 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
@@ -249,18 +249,17 @@ int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_re
return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t));
}
-//NR UPLINK INDICATION
+//NR UPLINK INDICATION
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind)
{
- if(config == NULL || ind == NULL)
- {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
- return -1;
- }
+ if (config == NULL || ind == NULL) {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
+ return -1;
+ }
- pnf_p7_t* _this = (pnf_p7_t*)(config);
- return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
+ pnf_p7_t* _this = (pnf_p7_t*)(config);
+ return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_slot_indication_scf_t));
}
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind)
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 0b4e12ad5d..69070c5544 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -456,7 +456,6 @@ int32_t rate_matching_lte(uint32_t N_coded,
unsigned int crcbit (unsigned char * inputptr, int octetlen, unsigned int poly);
-int16_t reverseBits(int32_t ,int32_t);
void phy_viterbi_dot11(int8_t *,uint8_t *,uint16_t);
int32_t nr_segmentation(unsigned char *input_buffer,
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index ed3fd55079..9cf5e26cc7 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -28,6 +28,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "openair1/PHY/MODULATION/nr_modulation.h"
#include "openair1/PHY/defs_RU.h"
#include "openair1/PHY/CODING/nrLDPC_extern.h"
@@ -525,6 +526,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
init_scrambling_luts();
init_pucch2_luts();
+ nr_init_fde(); // Init array for frequency equalization of transform precoding of PUSCH
+
load_nrLDPClib(NULL);
if (gNB->ldpc_offload_flag)
@@ -683,7 +686,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
int n_buf = Prx*max_ul_mimo_layers;
int nb_re_pusch = N_RB_UL * NR_NB_SC_PER_RB;
- int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
+ int nb_re_pusch2 = (nb_re_pusch + 7) & ~7;
gNB->pusch_vars = (NR_gNB_PUSCH *)malloc16_clear(gNB->max_nb_pusch * sizeof(NR_gNB_PUSCH));
for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
diff --git a/openair1/PHY/NR_ESTIMATION/nr_freq_equalization.c b/openair1/PHY/NR_ESTIMATION/nr_freq_equalization.c
new file mode 100644
index 0000000000..c593c04cc5
--- /dev/null
+++ b/openair1/PHY/NR_ESTIMATION/nr_freq_equalization.c
@@ -0,0 +1,70 @@
+/*
+ * 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 "PHY/defs_eNB.h"
+#include "PHY/sse_intrin.h"
+#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
+
+// Reference of openair1/PHY/LTE_ESTIMATION/freq_equalization.c
+
+// This is 4096/(1:4096) in simde__m128i format
+static simde__m128i nr_inv_ch[4096]; /* = {0, 4096/1, 4096/2, 4096/3, 4096/4...}*/
+
+void nr_init_fde()
+{
+ for (int i = 1;i < 4096; i++)
+ nr_inv_ch[i] = simde_mm_set1_epi16(4096/i);
+}
+
+void nr_freq_equalization (NR_DL_FRAME_PARMS *frame_parms,
+ int32_t *rxdataF_comp,
+ int32_t *ul_ch_mag,
+ int32_t *ul_ch_magb,
+ uint8_t symbol,
+ uint16_t Msc_RS,
+ uint8_t Qm)
+{
+ simde__m128i *rxdataF_comp128 = (simde__m128i *)rxdataF_comp;
+ simde__m128i *ul_ch_mag128 = (simde__m128i *)ul_ch_mag;
+ simde__m128i *ul_ch_magb128 = (simde__m128i *)ul_ch_magb;
+
+ AssertFatal(symbol < frame_parms->symbols_per_slot, "symbol %d >= %d\n",
+ symbol, frame_parms->symbols_per_slot);
+ AssertFatal(Msc_RS <= frame_parms->N_RB_UL*12, "Msc_RS %d >= %d\n",
+ Msc_RS, frame_parms->N_RB_UL*12);
+
+ for (uint16_t re = 0; re < (Msc_RS >> 2); re++) {
+ int16_t amp = (*((int16_t*)&ul_ch_mag128[re]));
+
+ if (amp > 4095)
+ amp = 4095;
+
+ rxdataF_comp128[re] = simde_mm_srai_epi16(simde_mm_mullo_epi16(rxdataF_comp128[re],nr_inv_ch[amp]),3);
+
+ if (Qm == 4)
+ ul_ch_mag128[re] = simde_mm_set1_epi16(324); // this is 512*2/sqrt(10)
+ else if (Qm == 6) {
+ ul_ch_mag128[re] = simde_mm_set1_epi16(316); // this is 512*4/sqrt(42)
+ ul_ch_magb128[re] = simde_mm_set1_epi16(158); // this is 512*2/sqrt(42)
+ } else if(Qm != 2)
+ AssertFatal(1, "nr_freq_equalization(), Qm = %d, should be 2, 4 or 6. symbol=%d, Msc_RS=%d\n", Qm, symbol, Msc_RS);
+ }
+}
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 98606e7f3c..11a316d77e 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -486,6 +486,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
* 2) Interpolate PTRS estimated value in TD after all PTRS symbols
* 3) Compensated DMRS based estimated signal with PTRS estimation for slot
*********************************************************************/
+// #define DEBUG_UL_PTRS
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,
nfapi_nr_pusch_pdu_t *rel15_ul,
@@ -495,7 +496,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
uint32_t nb_re_pusch)
{
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id];
- //#define DEBUG_UL_PTRS 1
int32_t *ptrs_re_symbol = NULL;
int8_t ret = 0;
uint8_t symbInSlot = rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols;
@@ -573,13 +573,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
}
}
-#ifdef DEBUG_UL_PTRS
- LOG_M("ptrsEstUl.m", "est", pusch_vars->ptrs_phase_per_slot[aarx], frame_parms->symbols_per_slot, 1, 1);
- LOG_M("rxdataF_bf_ptrs_comp_ul.m","bf_ptrs_cmp",
- &gNB->pusch_vars[0]->rxdataF_comp[aarx][rel15_ul->start_symbol_index * NR_NB_SC_PER_RB * rel15_ul->rb_size],
- rel15_ul->nr_of_symbols * NR_NB_SC_PER_RB * rel15_ul->rb_size,1,1);
-#endif
-
/*------------------------------------------------------------------------------------------------------- */
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
/*--------------------------------------------------------------------------------------------------------*/
@@ -590,15 +583,15 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
#ifdef DEBUG_UL_PTRS
printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i);
#endif
- rotate_cpx_vector((c16_t *)&pusch_vars->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ rotate_cpx_vector((c16_t *)&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch],
&phase_per_symbol[i],
- (c16_t *)&pusch_vars->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ (c16_t *)&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch],
((*nb_rb) * NR_NB_SC_PER_RB),
15);
- }// if not DMRS Symbol
- }// symbol loop
- }// last symbol check
- }//Antenna loop
+ } // if not DMRS Symbol
+ } // symbol loop
+ } // last symbol check
+ } // Antenna loop
}
uint32_t calc_power(const int16_t *x, const uint32_t size) {
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
index c75b4d4ed7..4934498a4a 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -83,4 +83,15 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int8_t *snr_per_rb,
int8_t *snr);
+
+void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms,
+ int *rxdataF_comp,
+ int *ul_ch_mag,
+ int *ul_ch_mag_b,
+ unsigned char symbol,
+ unsigned short Msc_RS,
+ unsigned char Qm);
+
+void nr_init_fde(void);
+
#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index d244881c32..5f5a9260cd 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -297,7 +297,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
}
int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers*1056;
- if (A > 3824) {
+ int B;
+ if (A > NR_MAX_PDSCH_TBS) {
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,A)>>8;
a[A>>3] = ((uint8_t *)&crc)[2];
@@ -305,7 +306,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
- harq->B = A+24;
+ B = A + 24;
// harq->b = a;
AssertFatal((A / 8) + 4 <= max_bytes,
"A %d is too big (A/8+4 = %d > %d)\n",
@@ -320,7 +321,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
a[1+(A>>3)] = ((uint8_t *)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
- harq->B = A+16;
+ B = A + 16;
// harq->b = a;
AssertFatal((A / 8) + 3 <= max_bytes,
"A %d is too big (A/8+3 = %d > %d)\n",
@@ -333,11 +334,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
impp.BG = rel15->maintenance_parms_v3.ldpcBaseGraph;
start_meas(dlsch_segmentation_stats);
- impp.Kb = nr_segmentation(harq->b, harq->c, harq->B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG);
+ impp.Kb = nr_segmentation(harq->b, harq->c, B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG);
stop_meas(dlsch_segmentation_stats);
if (impp.n_segments>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers) {
- LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",impp.n_segments,harq->B);
+ LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", impp.n_segments, B);
return(-1);
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index 692776b8cb..dd2493984e 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -236,7 +236,6 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
uint16_t M;
uint8_t nushift;
uint32_t unscrambling_mask;
- uint64_t a_reversed=0;
LOG_D(PHY, "PBCH generation started\n");
///Payload generation
NR_gNB_PBCH m_pbch;
@@ -298,8 +297,7 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
#endif
// Encoder reversal
- for (int i=0; ipbch_a_prime>>i)&1)<<(31-i);
+ uint64_t a_reversed = reverse_bits((uint64_t)pbch->pbch_a_prime, NR_POLAR_PBCH_PAYLOAD_BITS);
/// CRC, coding and rate matching
polar_encoder_fast (&a_reversed, (void*)pbch->pbch_e, 0, 0,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c
index 9663b1f3d4..b54a5c2c0c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c
@@ -76,3 +76,21 @@ void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t N
}
#endif
}
+
+void nr_codeword_unscrambling_init(int16_t *s2, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI)
+{
+ uint32_t x1;
+ uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
+ simde__m128i *s128=(simde__m128i *)s2;
+
+ uint32_t s = lte_gold_generic(&x1, &x2, 1);
+ uint8_t *s8=(uint8_t *)&s;
+
+ for (int i = 0; i < (size +31) >> 5; i++) {
+ *s128++ = byte2m128i[s8[0]];
+ *s128++ = byte2m128i[s8[1]];
+ *s128++ = byte2m128i[s8[2]];
+ *s128++ = byte2m128i[s8[3]];
+ s = lte_gold_generic(&x1, &x2, 0);
+ }
+}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index 5437e2e815..64ffc9a36a 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -73,6 +73,7 @@ void nr_codeword_scrambling(uint8_t *in,
uint32_t* out);
void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI);
+void nr_codeword_unscrambling_init(int16_t *s, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI);
/**@}*/
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index 2478748688..2583996b95 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -125,82 +125,11 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
@param slot Slot number
@param harq_pid HARQ process ID
*/
-void nr_rx_pusch(PHY_VARS_gNB *gNB,
- uint8_t UE_id,
- uint32_t frame,
- uint8_t slot,
- unsigned char harq_pid);
-
-/** \brief This function performs RB extraction (signal and channel estimates) (currently signal only until channel estimation and compensation are implemented)
- @param rxdataF pointer to the received frequency domain signal
- @param rxdataF_ext pointer to the extracted frequency domain signal
- @param rb_alloc RB allocation map (used for Resource Allocation Type 0 in NR)
- @param symbol Symbol on which to act (within-in nr_TTI_rx)
- @param start_rb The starting RB in the RB allocation (used for Resource Allocation Type 1 in NR)
- @param nb_rb_pusch The number of RBs allocated (used for Resource Allocation Type 1 in NR)
- @param frame_parms, Pointer to frame descriptor structure
-*/
-void nr_ulsch_extract_rbs(c16_t **rxdataF,
- NR_gNB_PUSCH *pusch_vars,
- int slot,
- unsigned char symbol,
- uint8_t is_dmrs_symbol,
- nfapi_nr_pusch_pdu_t *pusch_pdu,
- NR_DL_FRAME_PARMS *frame_parms);
-
-void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_gNB_ULSCH_t *ulsch_gNB,
- uint8_t symbol,
- uint8_t is_dmrs_symbol,
- uint32_t len,
- uint8_t nrOfLayers,
- uint16_t nb_rb,
- int shift_ch_ext);
-
-/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
- @param ul_ch_estimates_ext Channel estimates in allocated RBs
- @param frame_parms Pointer to frame descriptor
- @param avg Pointer to average signal strength
- @param pilots_flag Flag to indicate pilots in symbol
- @param nb_rb Number of allocated RBs
-*/
-void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- int32_t *avg,
- uint8_t symbol,
- uint32_t len,
- uint8_t nrOfLayers,
- unsigned short nb_rb);
-
-/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
- @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
- @param ul_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
- @param ul_ch_mag First Channel magnitudes (16QAM/64QAM/256QAM)
- @param ul_ch_magb Second weighted Channel magnitudes (64QAM/256QAM)
- @param ul_ch_magc Third weighted Channel magnitudes (256QAM)
- @param rxdataF_comp Compensated received waveform
- @param frame_parms Pointer to frame descriptor
- @param symbol Symbol on which to operate
- @param Qm Modulation order of allocation
- @param nb_rb Number of RBs in allocation
- @param output_shift Rescaling for compensated output (should be energy-normalizing)
-*/
-void nr_ulsch_channel_compensation(int **rxdataF_ext,
- int **ul_ch_estimates_ext,
- int **ul_ch_mag,
- int **ul_ch_magb,
- int **ul_ch_magc,
- int **rxdataF_comp,
- int ***rho,
- NR_DL_FRAME_PARMS *frame_parms,
- unsigned char symbol,
- int length,
- uint8_t is_dmrs_symbol,
- unsigned char mod_order,
- uint8_t nrOfLayers,
- unsigned short nb_rb,
- unsigned char output_shift);
+int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
+ uint8_t ulsch_id,
+ uint32_t frame,
+ uint8_t slot,
+ unsigned char harq_pid);
/*!
\brief This function implements the idft transform precoding in PUSCH
@@ -209,6 +138,28 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
*/
void nr_idft(int32_t *z, uint32_t Msc_PUSCH);
+void nr_ulsch_qpsk_qpsk(c16_t *stream0_in,
+ c16_t *stream1_in,
+ c16_t *stream0_out,
+ c16_t *rho01,
+ uint32_t length);
+
+void nr_ulsch_qam16_qam16(c16_t *stream0_in,
+ c16_t *stream1_in,
+ c16_t *ch_mag,
+ c16_t *ch_mag_i,
+ c16_t *stream0_out,
+ c16_t *rho01,
+ uint32_t length);
+
+void nr_ulsch_qam64_qam64(c16_t *stream0_in,
+ c16_t *stream1_in,
+ c16_t *ch_mag,
+ c16_t *ch_mag_i,
+ c16_t *stream0_out,
+ c16_t *rho01,
+ uint32_t length);
+
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
@param rxdataF_comp Compensated channel output
@param ulsch_llr llr output
@@ -216,7 +167,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH);
@param symbol OFDM symbol index in sub-frame
*/
void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
- int16_t *ulsch_llr,
+ int16_t *ulsch_llr,
uint32_t nb_re,
uint8_t symbol);
@@ -231,11 +182,9 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int16_t *ulsch_llr,
- uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol);
-
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream 64 QAM received waveforms.
@param rxdataF_comp Compensated channel output
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 64
@@ -248,7 +197,6 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int32_t **ul_ch_magb,
int16_t *ulsch_llr,
- uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol);
@@ -266,7 +214,6 @@ void nr_ulsch_256qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_magb,
int32_t **ul_ch_magc,
int16_t *ulsch_llr,
- uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol);
@@ -284,7 +231,6 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
int32_t *ul_ch_magb,
int32_t *ul_ch_magc,
int16_t *ulsch_llr,
- uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol,
uint8_t mod_order);
@@ -292,15 +238,17 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
void reset_active_stats(PHY_VARS_gNB *gNB, int frame);
void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame);
-void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp,
- int32_t **ul_ch_mag,
- int32_t ***rho,
- int16_t **llr_layers,
- uint8_t nb_antennas_rx,
- uint32_t rb_size,
+void nr_ulsch_compute_ML_llr(NR_gNB_PUSCH *pusch_vars,
+ uint32_t symbol,
+ c16_t* rxdataF_comp0,
+ c16_t* rxdataF_comp1,
+ c16_t* ul_ch_mag0,
+ c16_t* ul_ch_mag1,
+ c16_t* llr_layers0,
+ c16_t* llr_layers1,
+ c16_t* rho0,
+ c16_t* rho1,
uint32_t nb_re,
- uint8_t symbol,
- uint32_t rxdataF_ext_offset,
uint8_t mod_order);
void nr_ulsch_shift_llr(int16_t **llr_layers, uint32_t nb_re, uint32_t rxdataF_ext_offset, uint8_t mod_order, int shift);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 69015660d8..1d4e5bf71c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -122,42 +122,25 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
static void nr_processULSegment(void *arg)
{
ldpcDecode_t *rdata = (ldpcDecode_t *)arg;
- PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
- int length_dec;
- int Kr;
- int Kr_bytes;
- int K_bits_F;
- uint8_t crc_type;
- int i;
- int j;
- int r = rdata->segment_r;
- int A = rdata->A;
- int E = rdata->E;
- int Qm = rdata->Qm;
- int rv_index = rdata->rv_index;
- int r_offset = rdata->r_offset;
- uint8_t kc = rdata->Kc;
+ const int Kr = ulsch_harq->K;
+ const int Kr_bytes = Kr >> 3;
+ const int K_bits_F = Kr - ulsch_harq->F;
+ const int r = rdata->segment_r;
+ const int A = rdata->A;
+ const int E = rdata->E;
+ const int Qm = rdata->Qm;
+ const int rv_index = rdata->rv_index;
+ const int r_offset = rdata->r_offset;
+ const uint8_t kc = rdata->Kc;
short *ulsch_llr = rdata->ulsch_llr;
- int max_ldpc_iterations = p_decoderParms->numMaxIter;
+ const int max_ldpc_iterations = p_decoderParms->numMaxIter;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32)));
- int16_t z[68 * 384 + 16] __attribute__((aligned(16)));
- int8_t l[68 * 384 + 16] __attribute__((aligned(16)));
-
- simde__m128i *pv = (simde__m128i *)&z;
- simde__m128i *pl = (simde__m128i *)&l;
-
- Kr = ulsch_harq->K;
- Kr_bytes = Kr >> 3;
- K_bits_F = Kr - ulsch_harq->F;
-
t_nrLDPC_time_stats procTime = {0};
t_nrLDPC_time_stats *p_procTime = &procTime;
- // start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
-
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
@@ -172,7 +155,6 @@ static void nr_processULSegment(void *arg)
// for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset);
- stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
//////////////////////////////////////////////////////////////////////////////////////////
@@ -182,7 +164,6 @@ static void nr_processULSegment(void *arg)
///////////////////////// ulsch_harq->e =====> ulsch_harq->d /////////////////////////
- // start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
if (nr_rate_matching_ldpc_rx(rdata->tbslbrm,
p_decoderParms->BG,
@@ -196,43 +177,35 @@ static void nr_processULSegment(void *arg)
ulsch_harq->F,
Kr - ulsch_harq->F - 2 * (p_decoderParms->Z))
== -1) {
- stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n");
rdata->decodeIterations = max_ldpc_iterations + 1;
return;
- } else {
- stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
}
ulsch_harq->d_to_be_cleared[r] = false;
memset(ulsch_harq->c[r], 0, Kr_bytes);
-
- if (ulsch_harq->C == 1) {
- if (A > 3824)
- crc_type = CRC24_A;
- else
- crc_type = CRC16;
-
- length_dec = ulsch_harq->B;
- } else {
- crc_type = CRC24_B;
- length_dec = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C;
- }
-
+ p_decoderParms->crc_type = crcType(ulsch_harq->C, A);
+ p_decoderParms->block_length = lenWithCrc(ulsch_harq->C, A);
// start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
// set first 2*Z_c bits to zeros
- memset(&z[0], 0, 2 * ulsch_harq->Z * sizeof(int16_t));
+
+ int16_t z[68 * 384 + 16] __attribute__((aligned(16)));
+
+ memset(z, 0, 2 * ulsch_harq->Z * sizeof(*z));
// set Filler bits
- memset((&z[0] + K_bits_F), 127, ulsch_harq->F * sizeof(int16_t));
+ memset(z + K_bits_F, 127, ulsch_harq->F * sizeof(*z));
// Move coded bits before filler bits
- memcpy((&z[0] + 2 * ulsch_harq->Z), ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(int16_t));
+ memcpy(z + 2 * ulsch_harq->Z, ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(*z));
// skip filler bits
- memcpy((&z[0] + Kr), ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(int16_t));
+ memcpy(z + Kr, ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(*z));
// Saturate coded bits before decoding into 8 bits values
- for (i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) {
+ simde__m128i *pv = (simde__m128i *)&z;
+ int8_t l[68 * 384 + 16] __attribute__((aligned(16)));
+ simde__m128i *pl = (simde__m128i *)&l;
+ for (int i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) {
pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -242,74 +215,167 @@ static void nr_processULSegment(void *arg)
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
- p_decoderParms->block_length = length_dec;
- p_decoderParms->crc_type = crc_type;
- rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)pl, llrProcBuf, p_procTime, &ulsch_harq->abort_decode);
+ rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, l, llrProcBuf, p_procTime, &ulsch_harq->abort_decode);
if (rdata->decodeIterations <= p_decoderParms->numMaxIter)
memcpy(ulsch_harq->c[r],llrProcBuf, Kr>>3);
- //stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
+}
+
+int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
+ uint8_t ULSCH_id,
+ short *ulsch_llr,
+ nfapi_nr_pusch_pdu_t *pusch_pdu,
+ t_nrLDPC_dec_params *decParams,
+ uint8_t harq_pid,
+ uint32_t G)
+{
+ NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
+ NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
+ int8_t llrProcBuf[22 * 384] __attribute__((aligned(32)));
+ int16_t z_ol[68 * 384] __attribute__((aligned(32)));
+ int8_t l_ol[68 * 384] __attribute__((aligned(32)));
+ uint8_t Qm = pusch_pdu->qam_mod_order;
+ uint8_t n_layers = pusch_pdu->nrOfLayers;
+ const int Kr = harq_process->K;
+ const int Kr_bytes = Kr >> 3;
+ const int kc = decParams->BG == 2 ? 52 : 68;
+ const uint32_t A = (harq_process->TBS) << 3;
+ int decodeIterations = 2;
+ int dtx_det = 0;
+ int r_offset = 0, offset = 0;
+ for (int r = 0; r < harq_process->C; r++) {
+ int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
+ memset(harq_process->c[r], 0, Kr_bytes);
+
+ decParams->R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index,
+ E,
+ decParams->BG,
+ decParams->Z,
+ &harq_process->llrLen,
+ harq_process->round);
+
+ if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) {
+ memcpy(z_ol, ulsch_llr + r_offset, E * sizeof(short));
+ simde__m128i *pv_ol128 = (simde__m128i *)&z_ol;
+ simde__m128i *pl_ol128 = (simde__m128i *)&l_ol;
+ for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) {
+ pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
+ }
+
+ int ret = nrLDPC_decoder_offload(decParams,
+ harq_pid,
+ ULSCH_id,
+ r,
+ pusch_pdu->pusch_data.rv_index,
+ harq_process->F,
+ E,
+ Qm,
+ (int8_t *)&pl_ol128[0],
+ llrProcBuf,
+ 1);
+ if (ret < 0) {
+ LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
+
+ decodeIterations = ulsch->max_ldpc_iterations + 1;
+ return -1;
+ }
+ for (int m = 0; m < Kr >> 3; m++) {
+ harq_process->c[r][m] = (uint8_t)llrProcBuf[m];
+ }
+
+ if (check_crc((uint8_t *)llrProcBuf, lenWithCrc(harq_process->C, A), crcType(harq_process->C, A))) {
+ PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r));
+ decodeIterations = 2;
+ } else {
+ PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r));
+ decodeIterations = ulsch->max_ldpc_iterations + 1;
+ }
+
+ r_offset += E;
+ } else {
+ dtx_det = 0;
+ decodeIterations = ulsch->max_ldpc_iterations + 1;
+ }
+ bool decodeSuccess = (decodeIterations <= ulsch->max_ldpc_iterations);
+ if (decodeSuccess) {
+ memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
+ offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
+ harq_process->processedSegments++;
+ } else {
+ LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
+ LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
+ break; // don't even attempt to decode other segments
+ }
+ }
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 0);
+
+ if (harq_process->processedSegments == harq_process->C) {
+ LOG_D(PHY, "ULSCH: Setting ACK for slot %d TBS %d\n", ulsch->slot, harq_process->TBS);
+ ulsch->active = false;
+ harq_process->round = 0;
+
+ LOG_D(PHY, "ULSCH received ok \n");
+ nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 0, 0);
+
+ } else {
+ LOG_D(PHY,
+ "[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d)\n",
+ phy_vars_gNB->Mod_id,
+ ulsch->frame,
+ ulsch->slot,
+ harq_pid,
+ ulsch->active,
+ harq_process->round,
+ harq_process->TBS);
+ ulsch->handled = 1;
+ decodeIterations = ulsch->max_ldpc_iterations + 1;
+ LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
+ nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 1, 0);
+ }
+ ulsch->last_iteration_cnt = decodeIterations;
+ return 0;
}
int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
- uint8_t ULSCH_id,
- short *ulsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- nfapi_nr_pusch_pdu_t *pusch_pdu,
- uint32_t frame,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint32_t G)
- {
- if (!ulsch_llr) {
- LOG_E(PHY, "ulsch_decoding.c: NULL ulsch_llr pointer\n");
- return -1;
- }
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1);
-
- NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
- NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id];
- NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
-
- if (!harq_process) {
- LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n");
- return -1;
+ uint8_t ULSCH_id,
+ short *ulsch_llr,
+ NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t *pusch_pdu,
+ uint32_t frame,
+ uint8_t nr_tti_rx,
+ uint8_t harq_pid,
+ uint32_t G)
+{
+ if (!ulsch_llr) {
+ LOG_E(PHY, "ulsch_decoding.c: NULL ulsch_llr pointer\n");
+ return -1;
}
- uint8_t dtx_det = 0;
- int Kr;
- int Kr_bytes;
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1);
+
+ NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
+ NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id];
+ NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
+
+ if (!harq_process) {
+ LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n");
+ return -1;
+ }
+
+ // ------------------------------------------------------------------
+ const uint16_t nb_rb = pusch_pdu->rb_size;
+ const uint8_t Qm = pusch_pdu->qam_mod_order;
+ const uint8_t mcs = pusch_pdu->mcs_index;
+ const uint8_t n_layers = pusch_pdu->nrOfLayers;
+ // ------------------------------------------------------------------
harq_process->processedSegments = 0;
-
- // ------------------------------------------------------------------
- uint16_t nb_rb = pusch_pdu->rb_size;
- uint8_t Qm = pusch_pdu->qam_mod_order;
- uint8_t mcs = pusch_pdu->mcs_index;
- uint8_t n_layers = pusch_pdu->nrOfLayers;
- // ------------------------------------------------------------------
-
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
- dtx_det = 0;
-
- uint32_t A = (harq_process->TBS) << 3;
-
- // target_code_rate is in 0.1 units
- float Coderate = (float) pusch_pdu->target_code_rate / 10240.0f;
-
- LOG_D(PHY,"ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n",
- harq_pid, ulsch->rnti, A, G, mcs, n_layers, nb_rb, Qm, Coderate, pusch_pdu->pusch_data.rv_index, harq_process->round, harq_process->harq_to_be_cleared);
t_nrLDPC_dec_params decParams = {0};
decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
- int kc;
- if (decParams.BG == 2) {
- kc = 52;
- } else {
- kc = 68;
- }
-
+ const uint32_t A = (harq_process->TBS) << 3;
NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti);
if (stats) {
stats->frame = frame;
@@ -324,219 +390,101 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
stats->ulsch_stats.total_bytes_tx += harq_process->TBS;
}
}
- if (A > 3824)
- harq_process->B = A+24;
- else
- harq_process->B = A+16;
- // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
+ LOG_D(PHY,
+ "ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n",
+ harq_pid,
+ ulsch->rnti,
+ A,
+ G,
+ mcs,
+ n_layers,
+ nb_rb,
+ Qm,
+ pusch_pdu->target_code_rate / 10240.0f,
+ pusch_pdu->pusch_data.rv_index,
+ harq_process->round,
+ harq_process->harq_to_be_cleared);
+
+ // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (C, K, Z, F)
nr_segmentation(NULL,
NULL,
- harq_process->B,
+ lenWithCrc(1, A), // size in case of 1 segment
&harq_process->C,
&harq_process->K,
&harq_process->Z, // [hna] Z is Zc
&harq_process->F,
decParams.BG);
- if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*n_layers) {
- LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B);
+ uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * n_layers; // number of segments to be allocated
+ if (harq_process->C > a_segments) {
+ LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, A);
return(-1);
}
-
-
-#ifdef DEBUG_ULSCH_DECODING
- printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
- if (!frame%100)
- printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
-#endif
- decParams.Z = harq_process->Z;
-
- decParams.numMaxIter = ulsch->max_ldpc_iterations;
- decParams.outMode = 0;
-
- uint32_t r_offset = 0;
-
- uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*n_layers; //number of segments to be allocated
-
if (nb_rb != 273) {
a_segments = a_segments*nb_rb;
a_segments = a_segments/273 +1;
}
-
if (harq_process->C > a_segments) {
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
return -1;
}
+
#ifdef DEBUG_ULSCH_DECODING
+ printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
+ if (!frame % 100)
+ printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
#endif
+ decParams.Z = harq_process->Z;
+ decParams.numMaxIter = ulsch->max_ldpc_iterations;
+ decParams.outMode = 0;
+
if (harq_process->harq_to_be_cleared) {
for (int r = 0; r < harq_process->C; r++)
harq_process->d_to_be_cleared[r] = true;
harq_process->harq_to_be_cleared = false;
}
- Kr = harq_process->K;
- Kr_bytes = Kr >> 3;
+ if (phy_vars_gNB->ldpc_offload_flag && mcs > 9)
+ return decode_offload(phy_vars_gNB, ULSCH_id, ulsch_llr, pusch_pdu, &decParams, harq_pid, G);
- uint32_t offset = 0;
- if (phy_vars_gNB->ldpc_offload_flag && mcs > 9) {
- int8_t llrProcBuf[22 * 384];
- // if (dtx_det==0) {
- int16_t z_ol[68 * 384];
- int8_t l_ol[68 * 384];
- int crc_type;
- int length_dec;
-
- if (harq_process->C == 1) {
- if (A > 3824)
- crc_type = CRC24_A;
- else
- crc_type = CRC16;
-
- length_dec = harq_process->B;
- } else {
- crc_type = CRC24_B;
- length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C;
- }
- int decodeIterations = 2;
- for (int r = 0; r < harq_process->C; r++) {
- int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
- memset(harq_process->c[r], 0, Kr_bytes);
-
- decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->round);
-
- if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) {
- // if (dtx_det==0){
- memcpy((&z_ol[0]), ulsch_llr + r_offset, E * sizeof(short));
- simde__m128i *pv_ol128 = (simde__m128i *)&z_ol;
- simde__m128i *pl_ol128 = (simde__m128i *)&l_ol;
- for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) {
- pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
- }
-
- int ret = nrLDPC_decoder_offload(&decParams, harq_pid, ULSCH_id, r, pusch_pdu->pusch_data.rv_index, harq_process->F, E, Qm, (int8_t *)&pl_ol128[0], llrProcBuf, 1);
- if (ret < 0) {
- LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
-
- decodeIterations = ulsch->max_ldpc_iterations + 1;
- return -1;
- }
- for (int m = 0; m < Kr >> 3; m++) {
- harq_process->c[r][m] = (uint8_t)llrProcBuf[m];
- }
-
- if (check_crc((uint8_t *)llrProcBuf, length_dec, crc_type)) {
- PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r));
- decodeIterations = 2;
- } else {
- PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r));
- decodeIterations = ulsch->max_ldpc_iterations + 1;
- }
- //}
-
- r_offset += E;
-
- /*for (int k=0;k<8;k++)
- {
- printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
- printf("llrprocbuf [%d] = %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k);
- }
- */
- } else {
- dtx_det = 0;
- decodeIterations = ulsch->max_ldpc_iterations + 1;
- }
- bool decodeSuccess = (decodeIterations <= ulsch->max_ldpc_iterations);
- if (decodeSuccess) {
- memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
- offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
- harq_process->processedSegments++;
- } else {
- LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
- LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
- break; // don't even attempt to decode other segments
- }
- }
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 0);
-
- bool crc_valid = false;
- if (harq_process->processedSegments == harq_process->C) {
- // When the number of code blocks is 1 (C = 1) and ulsch_harq->processedSegments = 1, we can assume a good TB because of the
- // CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block
- crc_valid = true;
- if (harq_process->C > 1) {
- // Check ULSCH transport block CRC
- crc_type = CRC16;
- if (A > 3824) {
- crc_type = CRC24_A;
- }
- crc_valid = check_crc(harq_process->b, harq_process->B, crc_type);
- }
- }
-
- if (crc_valid) {
- LOG_D(PHY, "[gNB %d] ULSCH: Setting ACK for slot %d TBS %d\n", phy_vars_gNB->Mod_id, ulsch->slot, harq_process->TBS);
- ulsch->active = false;
- harq_process->round = 0;
-
- LOG_D(PHY, "ULSCH received ok \n");
- nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 0, 0);
-
- } else {
- LOG_D(PHY,
- "[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d)\n",
- phy_vars_gNB->Mod_id,
- ulsch->frame,
- ulsch->slot,
- harq_pid,
- ulsch->active,
- harq_process->round,
- harq_process->TBS);
- ulsch->handled = 1;
- decodeIterations = ulsch->max_ldpc_iterations + 1;
- LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
- nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 1, 0);
- }
- ulsch->last_iteration_cnt = decodeIterations;
- }
-
- else {
- dtx_det = 0;
- set_abort(&harq_process->abort_decode, false);
- for (int r = 0; r < harq_process->C; r++) {
- int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
- union ldpcReqUnion id = {.s = {ulsch->rnti, frame, nr_tti_rx, 0, 0}};
- notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, &phy_vars_gNB->respDecode, &nr_processULSegment);
- ldpcDecode_t *rdata = (ldpcDecode_t *)NotifiedFifoData(req);
- decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->round);
- rdata->gNB = phy_vars_gNB;
- rdata->ulsch_harq = harq_process;
- rdata->decoderParms = decParams;
- rdata->ulsch_llr = ulsch_llr;
- rdata->Kc = kc;
- rdata->harq_pid = harq_pid;
- rdata->segment_r = r;
- rdata->nbSegments = harq_process->C;
- rdata->E = E;
- rdata->A = A;
- rdata->Qm = Qm;
- rdata->r_offset = r_offset;
- rdata->Kr_bytes = Kr_bytes;
- rdata->rv_index = pusch_pdu->pusch_data.rv_index;
- rdata->offset = offset;
- rdata->ulsch = ulsch;
- rdata->ulsch_id = ULSCH_id;
- rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
- pushTpool(&phy_vars_gNB->threadPool, req);
- LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r);
- r_offset += E;
- offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
- //////////////////////////////////////////////////////////////////////////////////////////
- }
+ uint32_t offset = 0, r_offset = 0;
+ set_abort(&harq_process->abort_decode, false);
+ for (int r = 0; r < harq_process->C; r++) {
+ int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
+ union ldpcReqUnion id = {.s = {ulsch->rnti, frame, nr_tti_rx, 0, 0}};
+ notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, &phy_vars_gNB->respDecode, &nr_processULSegment);
+ ldpcDecode_t *rdata = (ldpcDecode_t *)NotifiedFifoData(req);
+ decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index,
+ E,
+ decParams.BG,
+ decParams.Z,
+ &harq_process->llrLen,
+ harq_process->round);
+ rdata->gNB = phy_vars_gNB;
+ rdata->ulsch_harq = harq_process;
+ rdata->decoderParms = decParams;
+ rdata->ulsch_llr = ulsch_llr;
+ rdata->Kc = decParams.BG == 2 ? 52 : 68;
+ rdata->harq_pid = harq_pid;
+ rdata->segment_r = r;
+ rdata->nbSegments = harq_process->C;
+ rdata->E = E;
+ rdata->A = A;
+ rdata->Qm = Qm;
+ rdata->r_offset = r_offset;
+ rdata->Kr_bytes = harq_process->K >> 3;
+ rdata->rv_index = pusch_pdu->pusch_data.rv_index;
+ rdata->offset = offset;
+ rdata->ulsch = ulsch;
+ rdata->ulsch_id = ULSCH_id;
+ rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
+ pushTpool(&phy_vars_gNB->threadPool, req);
+ LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r);
+ r_offset += E;
+ offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
}
return harq_process->C;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 6f491ffafa..18aea849f7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -11,11 +11,6 @@
#include
#include "PHY/sse_intrin.h"
-//#define DEBUG_CH_COMP
-//#define DEBUG_RB_EXT
-//#define DEBUG_CH_MAG
-//#define ML_DEBUG
-
#define INVALID_VALUE 255
void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
@@ -281,109 +276,117 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
}
+static void nr_ulsch_extract_rbs (c16_t* const rxdataF,
+ c16_t* const chF,
+ c16_t *rxFext,
+ c16_t *chFext,
+ int rxoffset,
+ int choffset,
+ int aarx,
+ int is_dmrs_symbol,
+ nfapi_nr_pusch_pdu_t *pusch_pdu,
+ NR_DL_FRAME_PARMS *frame_parms)
+{
+ uint8_t delta = 0;
-void nr_ulsch_extract_rbs(c16_t **rxdataF,
- NR_gNB_PUSCH *pusch_vars,
- int slot,
- unsigned char symbol,
- uint8_t is_dmrs_symbol,
- nfapi_nr_pusch_pdu_t *pusch_pdu,
- NR_DL_FRAME_PARMS *frame_parms) {
+ int start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size;
+ int nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
- unsigned short start_re, re, nb_re_pusch;
- unsigned char aarx, aatx;
- uint32_t rxF_ext_index = 0;
- uint32_t ul_ch0_ext_index = 0;
- uint32_t ul_ch0_index = 0;
- int16_t *rxF,*rxF_ext;
- int *ul_ch0,*ul_ch0_ext;
- int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
-#ifdef DEBUG_RB_EXT
- printf("--------------------symbol = %d-----------------------\n", symbol);
- printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size);
-#endif
+ c16_t *rxF = &rxdataF[rxoffset];
+ c16_t *rxF_ext = &rxFext[0];
+ c16_t *ul_ch0 = &chF[choffset];
+ c16_t *ul_ch0_ext = &chFext[0];
- uint8_t is_data_re;
- start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size;
- nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
-
- int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
-
- for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
-
- rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol * frame_parms->ofdm_symbol_size)];
- rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
-
- if (is_dmrs_symbol == 0) {
- if (start_re + nb_re_pusch <= frame_parms->ofdm_symbol_size) {
- memcpy((void*)rxF_ext, (void*)&rxF[start_re*2], nb_re_pusch*sizeof(int32_t));
- } else {
- int neg_length = frame_parms->ofdm_symbol_size-start_re;
- int pos_length = nb_re_pusch-neg_length;
- memcpy((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t));
- memcpy((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t));
+ if (is_dmrs_symbol == 0) {
+ if (start_re + nb_re_pusch <= frame_parms->ofdm_symbol_size)
+ memcpy(rxF_ext, &rxF[start_re], nb_re_pusch * sizeof(c16_t));
+ else
+ {
+ int neg_length = frame_parms->ofdm_symbol_size - start_re;
+ int pos_length = nb_re_pusch - neg_length;
+ memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(c16_t));
+ memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(c16_t));
+ }
+ memcpy(ul_ch0_ext, ul_ch0, nb_re_pusch * sizeof(c16_t));
+ }
+ else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) // 6 REs / PRB
+ {
+ AssertFatal(delta == 0 || delta == 1, "Illegal delta %d\n",delta);
+ c16_t *rxF32 = &rxF[start_re];
+ if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) {
+ for (int idx = 1 - delta; idx < nb_re_pusch; idx += 2)
+ {
+ *rxF_ext++ = rxF32[idx];
+ *ul_ch0_ext++ = ul_ch0[idx];
}
-
- for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) {
- ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
- ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2];
- memcpy((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t));
+ }
+ else // handle the two pieces around DC
+ {
+ int neg_length = frame_parms->ofdm_symbol_size - start_re;
+ int pos_length = nb_re_pusch - neg_length;
+ int idx, idx2;
+ for (idx = 1 - delta; idx < neg_length; idx += 2)
+ {
+ *rxF_ext++ = rxF32[idx];
+ *ul_ch0_ext++= ul_ch0[idx];
}
-
- } else {
-
- for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) {
- ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
- ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2];
-
- rxF_ext_index = 0;
- ul_ch0_ext_index = 0;
- ul_ch0_index = 0;
- for (re = 0; re < nb_re_pusch; re++) {
- uint16_t k = start_re + re;
- is_data_re = allowed_xlsch_re_in_dmrs_symbol(k, start_re, frame_parms->ofdm_symbol_size, pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type);
- if (++k >= frame_parms->ofdm_symbol_size) {
- k -= frame_parms->ofdm_symbol_size;
- }
-
- #ifdef DEBUG_RB_EXT
- printf("re = %d, is_dmrs_symbol = %d, symbol = %d\n", re, is_dmrs_symbol, symbol);
- #endif
-
- // save only data and respective channel estimates
- if (is_data_re == 1) {
- if (aatx == 0) {
- rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
- rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
- rxF_ext_index +=2;
- }
-
- ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
- ul_ch0_ext_index++;
-
- #ifdef DEBUG_RB_EXT
- printf("dmrs symb %d: rxF_ext[%u] = (%d,%d), ul_ch0_ext[%u] = (%d,%d)\n",
- is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1],
- ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]);
- #endif
- }
- ul_ch0_index++;
- }
+ rxF32 = rxF;
+ idx2 = idx;
+ for (idx = 1 - delta; idx < pos_length; idx += 2, idx2 += 2)
+ {
+ *rxF_ext++ = rxF32[idx];
+ *ul_ch0_ext++ = ul_ch0[idx2];
+ }
+ }
+ }
+ else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2) // 8 REs / PRB
+ {
+ AssertFatal(delta==0||delta==2||delta==4,"Illegal delta %d\n",delta);
+ if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size)
+ {
+ for (int idx = 0; idx < nb_re_pusch; idx ++)
+ {
+ if (idx % 6 == 2 * delta || idx % 6 == 2 * delta + 1)
+ continue;
+ *rxF_ext++ = rxF[idx];
+ *ul_ch0_ext++ = ul_ch0[idx];
+ }
+ }
+ else
+ {
+ int neg_length = frame_parms->ofdm_symbol_size - start_re;
+ int pos_length = nb_re_pusch - neg_length;
+ c16_t *rxF64 = &rxF[start_re];
+ int idx, idx2;
+ for (idx = 0; idx < neg_length; idx ++)
+ {
+ if (idx % 6 == 2 * delta || idx % 6 == 2 * delta + 1)
+ continue;
+ *rxF_ext++ = rxF64[idx];
+ *ul_ch0_ext++ = ul_ch0[idx];
+ }
+ rxF64 = rxF;
+ idx2 = idx;
+ for (idx = 0; idx < pos_length; idx++, idx2++)
+ {
+ if (idx % 6 == 2 * delta || idx % 6 == 2 * delta + 1)
+ continue;
+ *rxF_ext++ = rxF64[idx];
+ *ul_ch0_ext++ = ul_ch0[idx2];
}
}
}
}
-void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_gNB_ULSCH_t *ulsch_gNB,
- uint8_t symbol,
- uint8_t is_dmrs_symbol,
- uint32_t len,
- uint8_t nrOfLayers,
- unsigned short nb_rb,
- int shift_ch_ext)
+static void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t symbol,
+ uint8_t is_dmrs_symbol,
+ uint32_t len,
+ uint8_t nrOfLayers,
+ unsigned short nb_rb,
+ int shift_ch_ext)
{
// Determine scaling amplitude based the symbol
int b = 3;
@@ -400,60 +403,55 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
simde__m128i ch_amp128 = simde_mm_set1_epi16(ch_amp); // Q3.13
LOG_D(PHY, "Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, is_dmrs_symbol, nb_rb, frame_parms->Ncp, symbol);
- uint32_t nb_rb_0 = len / 12 + ((len % 12) ? 1 : 0);
- int off = ((nb_rb & 1) == 1) ? 4 : 0;
for (int aatx = 0; aatx < nrOfLayers; aatx++) {
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
- simde__m128i *ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aatx * frame_parms->nb_antennas_rx + aarx][symbol * (off + (nb_rb * NR_NB_SC_PER_RB))];
- for (int rb = 0; rb < nb_rb_0; rb++) {
- ul_ch128[0] = simde_mm_mulhi_epi16(ul_ch128[0], ch_amp128);
- ul_ch128[0] = simde_mm_slli_epi16(ul_ch128[0], b);
-
- ul_ch128[1] = simde_mm_mulhi_epi16(ul_ch128[1], ch_amp128);
- ul_ch128[1] = simde_mm_slli_epi16(ul_ch128[1], b);
-
- ul_ch128[2] = simde_mm_mulhi_epi16(ul_ch128[2], ch_amp128);
- ul_ch128[2] = simde_mm_slli_epi16(ul_ch128[2], b);
- ul_ch128 += 3;
+ simde__m128i *ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aatx * frame_parms->nb_antennas_rx + aarx][symbol * len];
+ for (int i = 0; i < len >> 2; i++) {
+ ul_ch128[i] = simde_mm_mulhi_epi16(ul_ch128[i], ch_amp128);
+ ul_ch128[i] = simde_mm_slli_epi16(ul_ch128[i], b);
}
}
}
}
-//compute average channel_level on each (TX,RX) antenna pair
-void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- int32_t *avg,
- uint8_t symbol,
- uint32_t len,
- uint8_t nrOfLayers,
- unsigned short nb_rb)
+static int get_nb_re_pusch (NR_DL_FRAME_PARMS *frame_parms, nfapi_nr_pusch_pdu_t *rel15_ul,int symbol)
{
+ uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
+ if (dmrs_symbol_flag == 1) {
+ if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01)
+ AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
+ if (rel15_ul->dmrs_config_type == 0) {
+ // if no data in dmrs cdm group is 1 only even REs have no data
+ // if no data in dmrs cdm group is 2 both odd and even REs have no data
+ return(rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6)));
+ }
+ else return(rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4)));
+ } else return(rel15_ul->rb_size * NR_NB_SC_PER_RB);
+}
- short rb;
- unsigned char aatx, aarx;
+// compute average channel_level on each (TX,RX) antenna pair
+static void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ int32_t *avg,
+ uint8_t symbol,
+ uint32_t len,
+ uint8_t nrOfLayers)
+{
simde__m128i *ul_ch128, avg128U;
int16_t x = factor2(len);
int16_t y = (len)>>x;
-
- uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
- int off = ((nb_rb&1) == 1)? 4:0;
-
- for (aatx = 0; aatx < nrOfLayers; aatx++) {
- for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+ for (int aatx = 0; aatx < nrOfLayers; aatx++) {
+ for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
//clear average level
avg128U = simde_mm_setzero_si128();
- ul_ch128=(simde__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
+ ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol * len];
- for (rb = 0; rb < nb_rb_0; rb++) {
- avg128U = simde_mm_add_epi32(avg128U, simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x));
- avg128U = simde_mm_add_epi32(avg128U, simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x));
- avg128U = simde_mm_add_epi32(avg128U, simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x));
- ul_ch128+=3;
+ for (int i = 0; i < len >> 2; i++) {
+ avg128U = simde_mm_add_epi32(avg128U, simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[i], ul_ch128[i]), x));
}
avg[aatx*frame_parms->nb_antennas_rx+aarx] = (((int32_t*)&avg128U)[0] +
@@ -465,298 +463,109 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
simde_mm_empty();
simde_m_empty();
-
}
-static simde__m128i a_mult_conjb(simde__m128i a, simde__m128i b, unsigned char output_shift)
+static void nr_ulsch_channel_compensation(c16_t *rxFext,
+ c16_t *chFext,
+ c16_t *ul_ch_maga,
+ c16_t *ul_ch_magb,
+ c16_t *ul_ch_magc,
+ int32_t **rxComp,
+ c16_t *rho,
+ NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t* rel15_ul,
+ uint32_t symbol,
+ uint32_t buffer_length,
+ uint32_t output_shift)
{
- simde__m128i mmtmpD0 = simde_mm_madd_epi16(b, a);
- simde__m128i mmtmpD1 = simde_mm_shufflelo_epi16(b, SIMDE_MM_SHUFFLE(2, 3, 0, 1));
- mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2, 3, 0, 1));
- mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)&conjugate[0]);
- mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, a);
- mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift);
- mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift);
- simde__m128i mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1);
- simde__m128i mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1);
- return simde_mm_packs_epi32(mmtmpD2, mmtmpD3);
-}
+ int mod_order = rel15_ul->qam_mod_order;
+ int nrOfLayers = rel15_ul->nrOfLayers;
+ int nb_rx_ant = frame_parms->nb_antennas_rx;
-//==============================================================================================
-// Pre-processing for LLR computation
-//==============================================================================================
-void nr_ulsch_channel_compensation(int **rxdataF_ext,
- int **ul_ch_estimates_ext,
- int **ul_ch_mag,
- int **ul_ch_magb,
- int **ul_ch_magc,
- int **rxdataF_comp,
- int ***rho,
- NR_DL_FRAME_PARMS *frame_parms,
- unsigned char symbol,
- int length,
- uint8_t is_dmrs_symbol,
- unsigned char mod_order,
- uint8_t nrOfLayers,
- unsigned short nb_rb,
- unsigned char output_shift) {
+ simde__m256i QAM_ampa_256 = simde_mm256_setzero_si256();
+ simde__m256i QAM_ampb_256 = simde_mm256_setzero_si256();
+ simde__m256i QAM_ampc_256 = simde_mm256_setzero_si256();
- int off = ((nb_rb&1) == 1)? 4:0;
+ if (mod_order == 4) {
+ QAM_ampa_256 = simde_mm256_set1_epi16(QAM16_n1);
+ QAM_ampb_256 = simde_mm256_setzero_si256();
+ QAM_ampc_256 = simde_mm256_setzero_si256();
+ }
+ else if (mod_order == 6) {
+ QAM_ampa_256 = simde_mm256_set1_epi16(QAM64_n1);
+ QAM_ampb_256 = simde_mm256_set1_epi16(QAM64_n2);
+ QAM_ampc_256 = simde_mm256_setzero_si256();
+ }
+ else if (mod_order == 8) {
+ QAM_ampa_256 = simde_mm256_set1_epi16(QAM256_n1);
+ QAM_ampb_256 = simde_mm256_set1_epi16(QAM256_n2);
+ QAM_ampc_256 = simde_mm256_set1_epi16(QAM256_n3);
+ }
-#ifdef DEBUG_CH_COMP
- int16_t *rxF, *ul_ch;
- int prnt_idx;
- for (int nl=0; nlnb_antennas_rx; aarx++) {
- rxF = (int16_t *) &rxdataF_ext[aarx][symbol * (off + (nb_rb * 12))];
- ul_ch = (int16_t *) &ul_ch_estimates_ext[nl * frame_parms->nb_antennas_rx + aarx][symbol * (off + (nb_rb * 12))];
+ simde__m256i xmmp0, xmmp1, xmmp2, xmmp3, xmmp4;
+ simde__m256i complex_shuffle256 = simde_mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
+ simde__m256i conj256 = simde_mm256_set_epi16(1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1);
- printf("--------symbol = %d, mod_order = %d, output_shift = %d, layer %i, antenna rx = %d -----------\n",
- symbol, mod_order, output_shift, nl, aarx);
- printf("----------------Before compensation------------------\n");
+ for (int aatx = 0; aatx < nrOfLayers; aatx++) {
+ simde__m256i *rxComp_256 = (simde__m256i*) &rxComp[aatx * nb_rx_ant][symbol * buffer_length];
+ simde__m256i *rxF_ch_maga_256 = (simde__m256i*)&ul_ch_maga[aatx * buffer_length];
+ simde__m256i *rxF_ch_magb_256 = (simde__m256i*)&ul_ch_magb[aatx * buffer_length];
+ simde__m256i *rxF_ch_magc_256 = (simde__m256i*)&ul_ch_magc[aatx * buffer_length];
+ for (int aarx = 0; aarx < nb_rx_ant; aarx++) {
+ simde__m256i *rxF_256 = (simde__m256i*) &rxFext[aarx * buffer_length];
+ simde__m256i *chF_256 = (simde__m256i*) &chFext[(aatx * nb_rx_ant + aarx) * buffer_length];
- for (prnt_idx = 0; prnt_idx < 12 * 5 * 2; prnt_idx += 2) {
- printf("rxF[%d] = (%d,%d)\n", prnt_idx >> 1, rxF[prnt_idx], rxF[prnt_idx + 1]);
- printf("ul_ch[%d] = (%d,%d)\n", prnt_idx >> 1, ul_ch[prnt_idx], ul_ch[prnt_idx + 1]);
+ for (int i = 0; i < buffer_length >> 3; i++)
+ {
+ xmmp0 = simde_mm256_madd_epi16(chF_256[i], rxF_256[i]);
+ // xmmp0 contains real part of 4 consecutive outputs (32-bit) of conj(H_m[i])*R_m[i]
+ xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256);
+ xmmp1 = simde_mm256_sign_epi16(xmmp1, conj256);
+ xmmp1 = simde_mm256_madd_epi16(xmmp1, rxF_256[i]);
+ // xmmp1 contains imag part of 4 consecutive outputs (32-bit) of conj(H_m[i])*R_m[i]
+ xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift);
+ xmmp1 = simde_mm256_srai_epi32(xmmp1, output_shift);
+ xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1);
+ xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1);
+ xmmp4 = simde_mm256_packs_epi32(xmmp2, xmmp3);
+
+ xmmp0 = simde_mm256_madd_epi16(chF_256[i], chF_256[i]); // |h|^2
+ xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift);
+ xmmp0 = simde_mm256_packs_epi32(xmmp0, xmmp0);
+ xmmp1 = simde_mm256_unpacklo_epi16(xmmp0, xmmp0);
+
+ xmmp2 = simde_mm256_mulhrs_epi16(xmmp1, QAM_ampa_256);
+ xmmp3 = simde_mm256_mulhrs_epi16(xmmp1, QAM_ampb_256);
+ xmmp1 = simde_mm256_mulhrs_epi16(xmmp1, QAM_ampc_256);
+
+ // MRC
+ rxComp_256[i] = simde_mm256_add_epi16(rxComp_256[i], xmmp4);
+ if (mod_order > 2)
+ rxF_ch_maga_256[i] = simde_mm256_add_epi16(rxF_ch_maga_256[i], xmmp2);
+ if (mod_order > 4)
+ rxF_ch_magb_256[i] = simde_mm256_add_epi16(rxF_ch_magb_256[i], xmmp3);
+ if (mod_order > 6)
+ rxF_ch_magc_256[i] = simde_mm256_add_epi16(rxF_ch_magc_256[i], xmmp1);
}
- }
- }
-#endif
-
-#ifdef DEBUG_CH_MAG
- int16_t *ch_mag;
- int print_idx;
-
-
- for (int ant=0; antnb_antennas_rx; ant++) {
- ch_mag = (int16_t *)&ul_ch_mag[ant][symbol*(off+(nb_rb*12))];
-
- printf("--------------------symbol = %d, mod_order = %d-----------------------\n", symbol, mod_order);
- printf("----------------Before computation------------------\n");
-
- for (print_idx=0;print_idx<5;print_idx++){
-
- printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]);
-
- }
- }
-
-#endif
-
-
- unsigned short rb;
- unsigned char aatx,aarx;
- simde__m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*ul_ch_mag128c,*rxdataF128,*rxdataF_comp128,*rho128;
- simde__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0},QAM_amp128c={0};
- QAM_amp128b = simde_mm_setzero_si128();
-
- uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
- for (aatx=0; aatxnb_antennas_rx; aarx++) {
- ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
- ul_ch_mag128 = (simde__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
- ul_ch_mag128b = (simde__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
- ul_ch_mag128c = (simde__m128i *)&ul_ch_magc[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
- rxdataF128 = (simde__m128i *)&rxdataF_ext[aarx][symbol*(off+(nb_rb*12))];
- rxdataF_comp128 = (simde__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
-
-
- for (rb=0; rb2) {
- // get channel amplitude if not QPSK
-
- //print_shorts("ch:",(int16_t*)&ul_ch128[0]);
-
- mmtmpD0 = simde_mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
- mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift);
-
- mmtmpD1 = simde_mm_madd_epi16(ul_ch128[1],ul_ch128[1]);
- mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift);
-
- mmtmpD0 = simde_mm_packs_epi32(mmtmpD0,mmtmpD1);
-
- // store channel magnitude here in a new field of ulsch
-
- ul_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
- ul_ch_mag128b[0] = ul_ch_mag128[0];
- ul_ch_mag128c[0] = ul_ch_mag128[0];
- ul_ch_mag128[0] = simde_mm_mulhrs_epi16(ul_ch_mag128[0],QAM_amp128);
- ul_ch_mag128b[0] = simde_mm_mulhrs_epi16(ul_ch_mag128b[0],QAM_amp128b);
- ul_ch_mag128c[0] = simde_mm_mulhrs_epi16(ul_ch_mag128c[0],QAM_amp128c);
- // print_ints("ch: = ",(int32_t*)&mmtmpD0);
- // print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
- // print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]);
-
- ul_ch_mag128[1] = simde_mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
- ul_ch_mag128b[1] = ul_ch_mag128[1];
- ul_ch_mag128c[1] = ul_ch_mag128[1];
- ul_ch_mag128[1] = simde_mm_mulhrs_epi16(ul_ch_mag128[1],QAM_amp128);
- ul_ch_mag128b[1] = simde_mm_mulhrs_epi16(ul_ch_mag128b[1],QAM_amp128b);
- ul_ch_mag128c[1] = simde_mm_mulhrs_epi16(ul_ch_mag128c[1],QAM_amp128c);
-
- mmtmpD0 = simde_mm_madd_epi16(ul_ch128[2],ul_ch128[2]);
- mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift);
- mmtmpD1 = simde_mm_packs_epi32(mmtmpD0,mmtmpD0);
-
- ul_ch_mag128[2] = simde_mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
- ul_ch_mag128b[2] = ul_ch_mag128[2];
- ul_ch_mag128c[2] = ul_ch_mag128[2];
-
- ul_ch_mag128[2] = simde_mm_mulhrs_epi16(ul_ch_mag128[2],QAM_amp128);
- ul_ch_mag128b[2] = simde_mm_mulhrs_epi16(ul_ch_mag128b[2],QAM_amp128b);
- ul_ch_mag128c[2] = simde_mm_mulhrs_epi16(ul_ch_mag128c[2],QAM_amp128c);
- }
-
- // Multiply received data by conjugated channel
- rxdataF_comp128[0] = a_mult_conjb(rxdataF128[0], ul_ch128[0], output_shift);
- rxdataF_comp128[1] = a_mult_conjb(rxdataF128[1], ul_ch128[1], output_shift);
- rxdataF_comp128[2] = a_mult_conjb(rxdataF128[2], ul_ch128[2], output_shift);
-
- ul_ch128 += 3;
- ul_ch_mag128 += 3;
- ul_ch_mag128b += 3;
- ul_ch_mag128c += 3;
- rxdataF128 += 3;
- rxdataF_comp128 += 3;
- }
- }
- }
-
- if (rho) {
- //we compute the Tx correlation matrix for each Rx antenna
- //As an example the 2x2 MIMO case requires
- //rho[aarx][nb_aatx*nb_aatx] = [cov(H_aarx_0,H_aarx_0) cov(H_aarx_0,H_aarx_1)
- // cov(H_aarx_1,H_aarx_0) cov(H_aarx_1,H_aarx_1)], aarx=0,...,nb_antennas_rx-1
-
- int avg_rho_re[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers];
- int avg_rho_im[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers];
-
- for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
- for (aatx=0; aatx < nrOfLayers; aatx++) {
- for (int atx=0; atx< nrOfLayers; atx++) {
-
- avg_rho_re[aarx][aatx*nrOfLayers+atx] = 0;
- avg_rho_im[aarx][aatx*nrOfLayers+atx] = 0;
- rho128 = (simde__m128i *)&rho[aarx][aatx*nrOfLayers+atx][symbol*(off+(nb_rb*12))];
- ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
- ul_ch128_2 = (simde__m128i *)&ul_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))];
-
- for (rb=0; rb> 3; i++) {
// multiply by conjugated channel
- mmtmpD0 = simde_mm_madd_epi16(ul_ch128[0],ul_ch128_2[0]);
- // print_ints("re",&mmtmpD0);
+ xmmp0 = simde_mm256_madd_epi16(chF_256[i], chF2_256[i]);
+ // xmmp0 contains real part of 4 consecutive outputs (32-bit)
+ xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256);
+ xmmp1 = simde_mm256_sign_epi16(xmmp1, conj256);
+ xmmp1 = simde_mm256_madd_epi16(xmmp1, chF2_256[i]);
+ // xmmp0 contains imag part of 4 consecutive outputs (32-bit)
+ xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift);
+ xmmp1 = simde_mm256_srai_epi32(xmmp1, output_shift);
+ xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1);
+ xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1);
- // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
- mmtmpD1 = simde_mm_shufflelo_epi16(ul_ch128[0], SIMDE_MM_SHUFFLE(2,3,0,1));
- mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1));
- mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i*)&conjugate[0]);
- // print_ints("im",&mmtmpD1);
- mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,ul_ch128_2[0]);
- // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
- mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift);
- // print_ints("re(shift)",&mmtmpD0);
- mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift);
- // print_ints("im(shift)",&mmtmpD1);
- mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
- mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
- // print_ints("c0",&mmtmpD2);
- // print_ints("c1",&mmtmpD3);
- rho128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3);
-
- //print_shorts("rx:",ul_ch128_2);
- //print_shorts("ch:",ul_ch128);
- //print_shorts("pack:",rho128);
-
- avg_rho_re[aarx][aatx*nrOfLayers+atx] +=(((int16_t*)&rho128[0])[0]+
- ((int16_t*)&rho128[0])[2] +
- ((int16_t*)&rho128[0])[4] +
- ((int16_t*)&rho128[0])[6])/16;//
-
- avg_rho_im[aarx][aatx*nrOfLayers+atx] +=(((int16_t*)&rho128[0])[1]+
- ((int16_t*)&rho128[0])[3] +
- ((int16_t*)&rho128[0])[5] +
- ((int16_t*)&rho128[0])[7])/16;//
- // multiply by conjugated channel
- mmtmpD0 = simde_mm_madd_epi16(ul_ch128[1],ul_ch128_2[1]);
- // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
- mmtmpD1 = simde_mm_shufflelo_epi16(ul_ch128[1], SIMDE_MM_SHUFFLE(2,3,0,1));
- mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1));
- mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i*)conjugate);
- mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,ul_ch128_2[1]);
- // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
- mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift);
- mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift);
- mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
- mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
- rho128[1] =simde_mm_packs_epi32(mmtmpD2,mmtmpD3);
- //print_shorts("rx:",ul_ch128_2+1);
- //print_shorts("ch:",ul_ch128+1);
- //print_shorts("pack:",rho128+1);
-
- // multiply by conjugated channel
- avg_rho_re[aarx][aatx*nrOfLayers+atx] +=(((int16_t*)&rho128[1])[0]+
- ((int16_t*)&rho128[1])[2] +
- ((int16_t*)&rho128[1])[4] +
- ((int16_t*)&rho128[1])[6])/16;
-
- avg_rho_im[aarx][aatx*nrOfLayers+atx] +=(((int16_t*)&rho128[1])[1]+
- ((int16_t*)&rho128[1])[3] +
- ((int16_t*)&rho128[1])[5] +
- ((int16_t*)&rho128[1])[7])/16;
-
- mmtmpD0 = simde_mm_madd_epi16(ul_ch128[2],ul_ch128_2[2]);
- // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
- mmtmpD1 = simde_mm_shufflelo_epi16(ul_ch128[2], SIMDE_MM_SHUFFLE(2,3,0,1));
- mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1));
- mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i*)conjugate);
- mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,ul_ch128_2[2]);
- // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
- mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift);
- mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift);
- mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
- mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-
- rho128[2] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3);
- //print_shorts("rx:",ul_ch128_2+2);
- //print_shorts("ch:",ul_ch128+2);
- //print_shorts("pack:",rho128+2);
- avg_rho_re[aarx][aatx*nrOfLayers+atx] +=(((int16_t*)&rho128[2])[0]+
- ((int16_t*)&rho128[2])[2] +
- ((int16_t*)&rho128[2])[4] +
- ((int16_t*)&rho128[2])[6])/16;
-
- avg_rho_im[aarx][aatx*nrOfLayers+atx] +=(((int16_t*)&rho128[2])[1]+
- ((int16_t*)&rho128[2])[3] +
- ((int16_t*)&rho128[2])[5] +
- ((int16_t*)&rho128[2])[7])/16;
-
- ul_ch128+=3;
- ul_ch128_2+=3;
- rho128+=3;
- }
- if (is_dmrs_symbol==1) {
- //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12);
- avg_rho_re[aarx][aatx*nrOfLayers+atx] = 16*avg_rho_re[aarx][aatx*nrOfLayers+atx]/(nb_rb*12);
- avg_rho_im[aarx][aatx*nrOfLayers+atx] = 16*avg_rho_im[aarx][aatx*nrOfLayers+atx]/(nb_rb*12);
- //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]);
+ rho_256[i] = simde_mm256_adds_epi16(rho_256[i], simde_mm256_packs_epi32(xmmp2, xmmp3));
}
}
}
@@ -765,114 +574,17 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
simde_mm_empty();
simde_m_empty();
-
-
-#ifdef DEBUG_CH_COMP
- for (int nl2=0; nl2nb_antennas_rx; aarx2++) {
- rxF = (int16_t *)&rxdataF_comp[nl2*frame_parms->nb_antennas_rx+aarx2][(symbol*(off+(nb_rb*12)))];
-
- printf("--------After compansation, layer %i, antenna rx %i----------\n", nl2, aarx2);
-
- for (prnt_idx=0;prnt_idx<12*5*2;prnt_idx+=2){
- printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]);
- }
- }
- }
-#endif
-
-#ifdef DEBUG_CH_MAG
-
-
- for (int ant=0; antnb_antennas_rx; ant++) {
- ch_mag = (int16_t *)&ul_ch_mag[ant][(symbol*(off+(nb_rb*12)))];
-
- printf("----------------After computation------------------\n");
-
- for (print_idx=0;print_idx<12*5*2;print_idx+=2){
-
- printf("ch_mag[%d] = (%d,%d)\n", print_idx>>1, ch_mag[print_idx],ch_mag[print_idx+1]);
-
- }
- }
-
-#endif
-
}
-void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **ul_ch_mag,
- int32_t **ul_ch_magb,
- int32_t **ul_ch_magc,
- int32_t ***rho,
- uint8_t nrOfLayers,
- uint8_t symbol,
- uint16_t nb_rb,
- int length) {
- int n_rx = frame_parms->nb_antennas_rx;
- simde__m128i *rxdataF_comp128[2],*ul_ch_mag128[2],*ul_ch_mag128b[2],*ul_ch_mag128c[2];
- int32_t i;
- uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
-
- int off = ((nb_rb&1) == 1)? 4:0;
-
- if (n_rx > 1) {
-
- int nb_re = nb_rb * 12;
-
- for (int aatx = 0; aatx < nrOfLayers; aatx++) {
-
- rxdataF_comp128[0] = (simde__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))];
- ul_ch_mag128[0] = (simde__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))];
- ul_ch_mag128b[0] = (simde__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))];
- ul_ch_mag128c[0] = (simde__m128i *)&ul_ch_magc[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))];
-
- for (int aa=1;aa < n_rx;aa++) {
- rxdataF_comp128[1] = (simde__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))];
- ul_ch_mag128[1] = (simde__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))];
- ul_ch_mag128b[1] = (simde__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))];
- ul_ch_mag128c[1] = (simde__m128i *)&ul_ch_magc[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))];
-
- // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
- for (i=0; i 2) {
if (mod_order == 4) {
@@ -1487,16 +1160,16 @@ uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
QAM_amp128b = simde_mm_set1_epi16(QAM64_n2); // 2/sqrt{42}
QAM_amp128c = simde_mm_setzero_si128();
} else if (mod_order == 8) {
- QAM_amp128 = simde_mm_set1_epi16(QAM256_n1);
+ QAM_amp128 = simde_mm_set1_epi16(QAM256_n1);
QAM_amp128b = simde_mm_set1_epi16(QAM256_n2);
QAM_amp128c = simde_mm_set1_epi16(QAM256_n3);
}
- ul_ch_mag128_0 = (simde__m128i *)&ul_ch_mag[0][symbol * (off + nb_rb * 12)];
- ul_ch_mag128b_0 = (simde__m128i *)&ul_ch_magb[0][symbol * (off + nb_rb * 12)];
- ul_ch_mag128c_0 = (simde__m128i *)&ul_ch_magc[0][symbol * (off + nb_rb * 12)];
- ul_ch_mag128_1 = (simde__m128i *)&ul_ch_mag[frame_parms->nb_antennas_rx][symbol * (off + nb_rb * 12)];
- ul_ch_mag128b_1 = (simde__m128i *)&ul_ch_magb[frame_parms->nb_antennas_rx][symbol * (off + nb_rb * 12)];
- ul_ch_mag128c_1 = (simde__m128i *)&ul_ch_magc[frame_parms->nb_antennas_rx][symbol * (off + nb_rb * 12)];
+ ul_ch_mag128_0 = (simde__m128i *) &ul_ch_mag[0];
+ ul_ch_mag128b_0 = (simde__m128i *)&ul_ch_magb[0];
+ ul_ch_mag128c_0 = (simde__m128i *)&ul_ch_magc[0];
+ ul_ch_mag128_1 = (simde__m128i *) &((int *)ul_ch_mag)[1 * buffer_length];
+ ul_ch_mag128b_1 = (simde__m128i *)&((int *)ul_ch_magb)[1 * buffer_length];
+ ul_ch_mag128c_1 = (simde__m128i *)&((int *)ul_ch_magc)[1 * buffer_length];
}
for (int rb = 0; rb < 3 * nb_rb_0; rb++) {
@@ -1586,38 +1259,212 @@ uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
return(0);
}
-//==============================================================================================
-
-/* Main Function */
-void nr_rx_pusch(PHY_VARS_gNB *gNB,
- uint8_t ulsch_id,
- uint32_t frame,
- uint8_t slot,
- unsigned char harq_pid)
+static void inner_rx (PHY_VARS_gNB *gNB,
+ int ulsch_id,
+ int slot,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_gNB_PUSCH *pusch_vars,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ c16_t **rxF,
+ c16_t **ul_ch,
+ int16_t **llr,
+ int soffset,
+ int length,
+ int symbol,
+ int output_shift,
+ uint32_t nvar)
{
+ int nb_layer = rel15_ul->nrOfLayers;
+ int nb_rx_ant = frame_parms->nb_antennas_rx;
+ int dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
+ int buffer_length = (rel15_ul->rb_size * NR_NB_SC_PER_RB + 7) & ~7;
+ c16_t rxFext[nb_rx_ant][buffer_length] __attribute__((aligned(32)));
+ c16_t chFext[nb_layer][nb_rx_ant][buffer_length] __attribute__((aligned(32)));
- uint8_t aarx, aatx;
- uint32_t nb_re_pusch, bwp_start_subcarrier;
- int avgs = 0;
+ memset(rxFext, 0, sizeof(c16_t) * nb_rx_ant * buffer_length);
+ memset(chFext, 0, sizeof(c16_t) * nb_layer * nb_rx_ant* buffer_length);
+
+ for (int aarx = 0; aarx < nb_rx_ant; aarx++) {
+ for (int aatx = 0; aatx < nb_layer; aatx++) {
+ nr_ulsch_extract_rbs(rxF[aarx],
+ (c16_t *)pusch_vars->ul_ch_estimates[aatx * nb_rx_ant + aarx],
+ rxFext[aarx],
+ chFext[aatx][aarx],
+ soffset+(symbol * frame_parms->ofdm_symbol_size),
+ pusch_vars->dmrs_symbol * frame_parms->ofdm_symbol_size,
+ aarx,
+ dmrs_symbol_flag,
+ rel15_ul,
+ frame_parms);
+ }
+ }
+ c16_t rho[nb_layer][nb_layer][buffer_length] __attribute__((aligned(32)));
+ c16_t rxF_ch_maga [nb_layer][buffer_length] __attribute__((aligned(32)));
+ c16_t rxF_ch_magb [nb_layer][buffer_length] __attribute__((aligned(32)));
+ c16_t rxF_ch_magc [nb_layer][buffer_length] __attribute__((aligned(32)));
+
+ memset(rho, 0, sizeof(c16_t) * nb_layer * nb_layer* buffer_length);
+ memset(rxF_ch_maga, 0, sizeof(c16_t) * nb_layer * buffer_length);
+ memset(rxF_ch_magb, 0, sizeof(c16_t) * nb_layer * buffer_length);
+ memset(rxF_ch_magc, 0, sizeof(c16_t) * nb_layer * buffer_length);
+ for (int i = 0; i < nb_layer; i++)
+ memset(&pusch_vars->rxdataF_comp[i*nb_rx_ant][symbol * buffer_length], 0, sizeof(int32_t) * buffer_length);
+
+ nr_ulsch_channel_compensation((c16_t*)rxFext,
+ (c16_t*)chFext,
+ (c16_t*)rxF_ch_maga,
+ (c16_t*)rxF_ch_magb,
+ (c16_t*)rxF_ch_magc,
+ pusch_vars->rxdataF_comp,
+ (nb_layer == 1) ? NULL : (c16_t*)rho,
+ frame_parms,
+ rel15_ul,
+ symbol,
+ buffer_length,
+ output_shift);
+
+ if (nb_layer == 1 && rel15_ul->transform_precoding == transformPrecoder_enabled && rel15_ul->qam_mod_order <= 6) {
+ if (rel15_ul->qam_mod_order > 2)
+ nr_freq_equalization(frame_parms,
+ &pusch_vars->rxdataF_comp[0][symbol * buffer_length],
+ (int *)rxF_ch_maga,
+ (int *)rxF_ch_magb,
+ symbol,
+ pusch_vars->ul_valid_re_per_slot[symbol],
+ rel15_ul->qam_mod_order);
+ nr_idft(&pusch_vars->rxdataF_comp[0][symbol * buffer_length], pusch_vars->ul_valid_re_per_slot[symbol]);
+ }
+ if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+ nr_pusch_ptrs_processing(gNB,
+ frame_parms,
+ rel15_ul,
+ ulsch_id,
+ slot,
+ symbol,
+ buffer_length);
+ pusch_vars->ul_valid_re_per_slot[symbol] -= pusch_vars->ptrs_re_per_slot;
+ }
+
+ if (nb_layer == 2) {
+ if (rel15_ul->qam_mod_order < 6) {
+ nr_ulsch_compute_ML_llr(pusch_vars,
+ symbol,
+ (c16_t*)&pusch_vars->rxdataF_comp[0][symbol * buffer_length],
+ (c16_t*)&pusch_vars->rxdataF_comp[nb_rx_ant][symbol * buffer_length],
+ rxF_ch_maga[0],
+ rxF_ch_maga[1],
+ (c16_t*)&llr[0][pusch_vars->llr_offset[symbol]],
+ (c16_t*)&llr[1][pusch_vars->llr_offset[symbol]],
+ rho[0][1],
+ rho[1][0],
+ pusch_vars->ul_valid_re_per_slot[symbol],
+ rel15_ul->qam_mod_order);
+ }
+ else {
+ nr_ulsch_mmse_2layers(frame_parms,
+ (int32_t **)pusch_vars->rxdataF_comp,
+ (int **)rxF_ch_maga,
+ (int **)rxF_ch_magb,
+ (int **)rxF_ch_magc,
+ (int **)chFext,
+ rel15_ul->rb_size,
+ frame_parms->nb_antennas_rx,
+ rel15_ul->qam_mod_order,
+ pusch_vars->log2_maxh,
+ symbol,
+ pusch_vars->ul_valid_re_per_slot[symbol],
+ nvar,
+ buffer_length);
+ }
+ }
+ if (nb_layer != 2 || rel15_ul->qam_mod_order >= 6)
+ for (int aatx = 0; aatx < nb_layer; aatx++)
+ nr_ulsch_compute_llr((int32_t*)&pusch_vars->rxdataF_comp[aatx * nb_rx_ant][symbol * buffer_length],
+ (int32_t*)rxF_ch_maga[aatx],
+ (int32_t*)rxF_ch_magb[aatx],
+ (int32_t*)rxF_ch_magc[aatx],
+ &llr[aatx][pusch_vars->llr_offset[symbol]],
+ pusch_vars->ul_valid_re_per_slot[symbol],
+ symbol,
+ rel15_ul->qam_mod_order);
+}
+
+static void nr_pusch_symbol_processing(void *arg)
+{
+ puschSymbolProc_t *rdata=(puschSymbolProc_t*)arg;
+
+ PHY_VARS_gNB *gNB = rdata->gNB;
+ NR_DL_FRAME_PARMS *frame_parms = rdata->frame_parms;
+ nfapi_nr_pusch_pdu_t *rel15_ul = rdata->rel15_ul;
+ int ulsch_id = rdata->ulsch_id;
+ int slot = rdata->slot;
+ NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id];
+ for (int symbol = rdata->startSymbol; symbol < rdata->startSymbol+rdata->numSymbols; symbol++) {
+ int dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
+ if (dmrs_symbol_flag == 1)
+ {
+ if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01)
+ AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
+ gNB->pusch_vars[ulsch_id].dmrs_symbol = symbol;
+ }
+
+ if (gNB->pusch_vars[ulsch_id].ul_valid_re_per_slot[symbol] == 0)
+ continue;
+ int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
+ inner_rx(gNB,
+ ulsch_id,
+ slot,
+ frame_parms,
+ pusch_vars,
+ rel15_ul,
+ gNB->common_vars.rxdataF,
+ (c16_t**)gNB->pusch_vars[ulsch_id].ul_ch_estimates,
+ rdata->llr_layers,
+ soffset,
+ gNB->pusch_vars[ulsch_id].ul_valid_re_per_slot[symbol],
+ symbol,
+ gNB->pusch_vars[ulsch_id].log2_maxh,
+ rdata->nvar);
+
+ int nb_re_pusch = gNB->pusch_vars[ulsch_id].ul_valid_re_per_slot[symbol];
+ // layer de-mapping
+ int16_t* llr_ptr = &rdata->llr_layers[0][pusch_vars->llr_offset[symbol]];
+ if (rel15_ul->nrOfLayers != 1) {
+ llr_ptr = &rdata->llr[pusch_vars->llr_offset[symbol] * rel15_ul->nrOfLayers];
+ for (int i = 0; i < (nb_re_pusch); i++)
+ for (int l = 0; l < rel15_ul->nrOfLayers; l++)
+ for (int m = 0; m < rel15_ul->qam_mod_order; m++)
+ llr_ptr[i*rel15_ul->nrOfLayers*rel15_ul->qam_mod_order+l*rel15_ul->qam_mod_order+m] = rdata->llr_layers[l][pusch_vars->llr_offset[symbol] + i*rel15_ul->qam_mod_order+m];
+ }
+ // unscrambling
+ int16_t *llr16 = (int16_t*)&rdata->llr[pusch_vars->llr_offset[symbol] * rel15_ul->nrOfLayers];
+ for (int i = 0; i < (nb_re_pusch * rel15_ul->qam_mod_order * rel15_ul->nrOfLayers); i++)
+ llr16[i] = llr_ptr[i] * rdata->s[i];
+ }
+}
+
+
+int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
+ uint8_t ulsch_id,
+ uint32_t frame,
+ uint8_t slot,
+ unsigned char harq_pid)
+{
+ uint8_t aarx;
+ uint32_t bwp_start_subcarrier;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
- NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ulsch_id];
- nfapi_nr_pusch_pdu_t *rel15_ul = &ulsch->harq_process->ulsch_pdu;
- int avg[frame_parms->nb_antennas_rx*rel15_ul->nrOfLayers];
+ nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id].harq_process->ulsch_pdu;
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id];
pusch_vars->dmrs_symbol = INVALID_VALUE;
- pusch_vars->cl_done = 0;
-
+ gNB->nbSymb=0;
bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
LOG_D(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset);
LOG_D(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos);
- LOG_D(PHY,"ulsch RX %x : start_rb %d nb_rb %d mcs %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_ports %d\n",
- rel15_ul->rnti,rel15_ul->rb_start,rel15_ul->rb_size,rel15_ul->mcs_index,
- rel15_ul->nrOfLayers,0,rel15_ul->bwp_start,0,rel15_ul->start_symbol_index,rel15_ul->nr_of_symbols,
- rel15_ul->num_dmrs_cdm_grps_no_data,rel15_ul->ul_dmrs_symb_pos,rel15_ul->dmrs_ports);
+
//----------------------------------------------------------
- //--------------------- Channel estimation ---------------------
+ //------------------- Channel estimation -------------------
//----------------------------------------------------------
start_meas(&gNB->ulsch_channel_estimation_stats);
int max_ch = 0;
@@ -1643,279 +1490,199 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
&nvar_tmp);
nvar += nvar_tmp;
}
-
- nr_gnb_measurements(gNB, ulsch, pusch_vars, symbol, rel15_ul->nrOfLayers);
+ // measure the SNR from the channel estimation
+ nr_gnb_measurements(gNB,
+ &gNB->ulsch[ulsch_id],
+ pusch_vars,
+ symbol,
+ rel15_ul->nrOfLayers);
allocCast2D(n0_subband_power,
unsigned int,
gNB->measurements.n0_subband_power,
frame_parms->nb_antennas_rx,
frame_parms->N_RB_UL,
false);
- for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
- if (symbol == rel15_ul->start_symbol_index) {
+ for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
+ {
+ if (symbol == rel15_ul->start_symbol_index)
+ {
pusch_vars->ulsch_power[aarx] = 0;
pusch_vars->ulsch_noise_power[aarx] = 0;
}
- for (aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) {
+ for (int aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) {
pusch_vars->ulsch_power[aarx] += signal_energy_nodc(
&pusch_vars->ul_ch_estimates[aatx * gNB->frame_parms.nb_antennas_rx + aarx][symbol * frame_parms->ofdm_symbol_size],
rel15_ul->rb_size * 12);
}
- for (int rb = 0; rb < rel15_ul->rb_size; rb++) {
- pusch_vars->ulsch_noise_power[aarx] +=
- n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start + rb] / rel15_ul->rb_size;
- }
- LOG_D(PHY,
- "aa %d, bwp_start%d, rb_start %d, rb_size %d: ulsch_power %d, ulsch_noise_power %d\n",
- aarx,
- rel15_ul->bwp_start,
- rel15_ul->rb_start,
- rel15_ul->rb_size,
- pusch_vars->ulsch_power[aarx],
- pusch_vars->ulsch_noise_power[aarx]);
+ for (int rb = 0; rb < rel15_ul->rb_size; rb++)
+ pusch_vars->ulsch_noise_power[aarx] +=
+ n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start + rb] / rel15_ul->rb_size;
}
}
}
nvar /= (rel15_ul->nr_of_symbols * rel15_ul->nrOfLayers * frame_parms->nb_antennas_rx);
- if (gNB->chest_time == 1) { // averaging time domain channel estimates
+ // averaging time domain channel estimates
+ if (gNB->chest_time == 1)
+ {
nr_chest_time_domain_avg(frame_parms,
pusch_vars->ul_ch_estimates,
rel15_ul->nr_of_symbols,
rel15_ul->start_symbol_index,
rel15_ul->ul_dmrs_symb_pos,
rel15_ul->rb_size);
-
- pusch_vars->dmrs_symbol =
- get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, rel15_ul->nr_of_symbols);
+ pusch_vars->dmrs_symbol = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos,
+ rel15_ul->start_symbol_index,
+ rel15_ul->nr_of_symbols);
}
+
stop_meas(&gNB->ulsch_channel_estimation_stats);
- int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
- uint32_t rxdataF_ext_offset = 0;
+ start_meas(&gNB->rx_pusch_init_stats);
+
+ // Scrambling initialization
+ int number_dmrs_symbols = 0;
+ for (int l = rel15_ul->start_symbol_index; l < rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols; l++)
+ number_dmrs_symbols += ((rel15_ul->ul_dmrs_symb_pos)>>l) & 0x01;
+ int nb_re_dmrs;
+ if (rel15_ul->dmrs_config_type == pusch_dmrs_type1)
+ nb_re_dmrs = 6*rel15_ul->num_dmrs_cdm_grps_no_data;
+ else
+ nb_re_dmrs = 4*rel15_ul->num_dmrs_cdm_grps_no_data;
+
+ // get how many bit in a slot //
+ int G = nr_get_G(rel15_ul->rb_size,
+ rel15_ul->nr_of_symbols,
+ nb_re_dmrs,
+ number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
+ rel15_ul->qam_mod_order,
+ rel15_ul->nrOfLayers);
+ // initialize scrambling sequence //
+ int16_t s[G+96] __attribute__((aligned(32)));
+
+ nr_codeword_unscrambling_init(s, G, 0, rel15_ul->data_scrambling_id, rel15_ul->rnti);
+
+ // first the computation of channel levels
+
+ int nb_re_pusch = 0, meas_symbol = -1;
+ for(meas_symbol = rel15_ul->start_symbol_index;
+ meas_symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);
+ meas_symbol++)
+ if ((nb_re_pusch = get_nb_re_pusch(frame_parms,rel15_ul,meas_symbol)) > 0)
+ break;
+
+ AssertFatal(nb_re_pusch>0 && meas_symbol>=0,"nb_re_pusch %d cannot be 0 or meas_symbol %d cannot be negative here\n",nb_re_pusch,meas_symbol);
+
+ // extract the first dmrs for the channel level computation
+ // extract the data in the OFDM frame, to the start of the array
+ int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
+
+ if (nb_re_pusch & 7)
+ nb_re_pusch += 8 - (nb_re_pusch & 7);
+
+ for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
+ for (int aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++)
+ nr_ulsch_extract_rbs(gNB->common_vars.rxdataF[aarx],
+ (c16_t *)pusch_vars->ul_ch_estimates[aatx * frame_parms->nb_antennas_rx + aarx],
+ (c16_t*)&pusch_vars->rxdataF_ext[aarx][meas_symbol * nb_re_pusch],
+ (c16_t*)&pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][meas_symbol * nb_re_pusch],
+ soffset + meas_symbol * frame_parms->ofdm_symbol_size,
+ pusch_vars->dmrs_symbol * frame_parms->ofdm_symbol_size,
+ aarx,
+ (rel15_ul->ul_dmrs_symb_pos >> meas_symbol) & 0x01,
+ rel15_ul,
+ frame_parms);
+
+ int avgs = 0;
+ int avg[frame_parms->nb_antennas_rx*rel15_ul->nrOfLayers];
uint8_t shift_ch_ext = rel15_ul->nrOfLayers > 1 ? log2_approx(max_ch >> 11) : 0;
- // Flag to select the receiver: (true) Nonlinear ML receiver, (false) Linear MMSE receiver
- // By default, we are using the Nonlinear ML receiver, except
- // - for 256QAM as Nonlinear ML receiver is not implemented for 256QAM
- // - for 64QAM as Nonlinear ML receiver requires more processing time than MMSE, and many machines are not powerful enough
- bool ml_rx = true;
- if (rel15_ul->nrOfLayers != 2 || rel15_ul->qam_mod_order >= 6) {
- ml_rx = false;
- }
+ //----------------------------------------------------------
+ //--------------------- Channel Scaling --------------------
+ //----------------------------------------------------------
+ nr_ulsch_scale_channel(pusch_vars->ul_ch_estimates_ext,
+ frame_parms,
+ meas_symbol,
+ (rel15_ul->ul_dmrs_symb_pos >> meas_symbol) & 0x01,
+ nb_re_pusch,
+ rel15_ul->nrOfLayers,
+ rel15_ul->rb_size,
+ shift_ch_ext);
+
+ nr_ulsch_channel_level(pusch_vars->ul_ch_estimates_ext,
+ frame_parms,
+ avg,
+ meas_symbol, // index of the start symbol
+ nb_re_pusch, // number of the re in pusch
+ rel15_ul->nrOfLayers);
- int ad_shift = 0;
- if (rel15_ul->nrOfLayers == 1) {
- ad_shift = 1 + log2_approx(frame_parms->nb_antennas_rx >> 2);
- } else if (ml_rx == false) {
- ad_shift = -3; // For 2-layers, we are already doing a bit shift in the nr_ulsch_mmse_2layers() function, so we can use more bits
- }
+ for (int aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++)
+ for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
+ avgs = cmax(avgs, avg[aatx*frame_parms->nb_antennas_rx+aarx]);
+
+ pusch_vars->log2_maxh = (log2_approx(avgs) >> 1);
- int num_re_total = 0;
- for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) {
- uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
- if (dmrs_symbol_flag == 1) {
- if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01)
- AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
+ if (rel15_ul->nrOfLayers == 2 && rel15_ul->qam_mod_order >= 6)
+ pusch_vars->log2_maxh = (log2_approx(avgs) >> 1) - 3; // for MMSE
+ else if (rel15_ul->nrOfLayers == 1)
+ pusch_vars->log2_maxh = (log2_approx(avgs) >> 1) + 1 + log2_approx(frame_parms->nb_antennas_rx >> 2);
+
+ if (pusch_vars->log2_maxh < 0)
+ pusch_vars->log2_maxh = 0;
- if (gNB->chest_time == 0) // Non averaging time domain channel estimates
- pusch_vars->dmrs_symbol = symbol;
+ stop_meas(&gNB->rx_pusch_init_stats);
- if (rel15_ul->dmrs_config_type == 0) {
- // if no data in dmrs cdm group is 1 only even REs have no data
- // if no data in dmrs cdm group is 2 both odd and even REs have no data
- nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6));
- }
- else {
- nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4));
- }
- }
- else {
- nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
+ start_meas(&gNB->rx_pusch_symbol_processing_stats);
+ int numSymbols = gNB->num_pusch_symbols_per_thread;
+
+ for(uint8_t symbol = rel15_ul->start_symbol_index;
+ symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);
+ symbol += numSymbols)
+ {
+ int total_res = 0;
+ for (int s = 0; s < numSymbols;s++) {
+ pusch_vars->ul_valid_re_per_slot[symbol+s] = get_nb_re_pusch(frame_parms,rel15_ul,symbol+s);
+ pusch_vars->llr_offset[symbol+s] = ((symbol+s) == rel15_ul->start_symbol_index) ?
+ 0 :
+ pusch_vars->llr_offset[symbol+s-1] + pusch_vars->ul_valid_re_per_slot[symbol+s-1] * rel15_ul->qam_mod_order;
+ total_res+=pusch_vars->ul_valid_re_per_slot[symbol+s];
}
+ if (total_res > 0) {
+ union puschSymbolReqUnion id = {.s={ulsch_id,frame,slot,0}};
+ id.p=1+symbol;
+ notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(puschSymbolProc_t), id.p, &gNB->respPuschSymb, &nr_pusch_symbol_processing); // create a job for Tpool
+ puschSymbolProc_t *rdata = (puschSymbolProc_t*)NotifiedFifoData(req); // data for the job
- num_re_total += nb_re_pusch;
- pusch_vars->ul_valid_re_per_slot[symbol] = nb_re_pusch;
- LOG_D(PHY, "symbol %d: nb_re_pusch %d, DMRS symbl used for Chest :%d \n", symbol, nb_re_pusch, pusch_vars->dmrs_symbol);
+ rdata->gNB = gNB;
+ rdata->frame_parms = frame_parms;
+ rdata->rel15_ul = rel15_ul;
+ rdata->slot = slot;
+ rdata->startSymbol = symbol;
+ rdata->numSymbols = numSymbols;
+ rdata->ulsch_id = ulsch_id;
+ rdata->llr = pusch_vars->llr;
+ rdata->llr_layers = pusch_vars->llr_layers;
+ rdata->s = &s[pusch_vars->llr_offset[symbol]*rel15_ul->nrOfLayers];
+ rdata->nvar = nvar;
- //----------------------------------------------------------
- //--------------------- RBs extraction ---------------------
- //----------------------------------------------------------
- if (nb_re_pusch > 0) {
- start_meas(&gNB->ulsch_rbs_extraction_stats);
- nr_ulsch_extract_rbs(gNB->common_vars.rxdataF, pusch_vars, slot, symbol, dmrs_symbol_flag, rel15_ul, frame_parms);
- stop_meas(&gNB->ulsch_rbs_extraction_stats);
-
- //----------------------------------------------------------
- //--------------------- Channel Scaling --------------------
- //----------------------------------------------------------
- nr_ulsch_scale_channel(pusch_vars->ul_ch_estimates_ext,
- frame_parms,
- ulsch,
- symbol,
- dmrs_symbol_flag,
- nb_re_pusch,
- rel15_ul->nrOfLayers,
- rel15_ul->rb_size,
- shift_ch_ext);
-
- if (pusch_vars->cl_done == 0) {
- nr_ulsch_channel_level(pusch_vars->ul_ch_estimates_ext,
- frame_parms,
- avg,
- symbol,
- nb_re_pusch,
- rel15_ul->nrOfLayers,
- rel15_ul->rb_size);
-
- avgs = 0;
-
- for (aatx=0;aatxnrOfLayers;aatx++)
- for (aarx=0;aarxnb_antennas_rx;aarx++)
- avgs = cmax(avgs,avg[aatx*frame_parms->nb_antennas_rx+aarx]);
-
- pusch_vars->log2_maxh = (log2_approx(avgs) >> 1) + ad_shift;
- if (pusch_vars->log2_maxh < 0) {
- pusch_vars->log2_maxh = 0;
- }
- pusch_vars->cl_done = 1;
- }
-
- //----------------------------------------------------------
- //--------------------- Channel Compensation ---------------
- //----------------------------------------------------------
- start_meas(&gNB->ulsch_channel_compensation_stats);
- LOG_D(PHY, "Doing channel compensations log2_maxh %d, avgs %d (%d,%d)\n" ,pusch_vars->log2_maxh, avgs,avg[0], avg[1]);
- nr_ulsch_channel_compensation(pusch_vars->rxdataF_ext,
- pusch_vars->ul_ch_estimates_ext,
- pusch_vars->ul_ch_mag0,
- pusch_vars->ul_ch_magb0,
- pusch_vars->ul_ch_magc0,
- pusch_vars->rxdataF_comp,
- (rel15_ul->nrOfLayers > 1) ? pusch_vars->rho : NULL,
- frame_parms,
- symbol,
- nb_re_pusch,
- dmrs_symbol_flag,
- rel15_ul->qam_mod_order,
- rel15_ul->nrOfLayers,
- rel15_ul->rb_size,
- pusch_vars->log2_maxh);
- stop_meas(&gNB->ulsch_channel_compensation_stats);
-
- start_meas(&gNB->ulsch_mrc_stats);
- nr_ulsch_detection_mrc(frame_parms,
- pusch_vars->rxdataF_comp,
- pusch_vars->ul_ch_mag0,
- pusch_vars->ul_ch_magb0,
- pusch_vars->ul_ch_magc0,
- (rel15_ul->nrOfLayers > 1) ? pusch_vars->rho : NULL,
- rel15_ul->nrOfLayers,
- symbol,
- rel15_ul->rb_size,
- nb_re_pusch);
-
- // Apply MMSE for 2 Tx layers
- if (ml_rx == false && rel15_ul->nrOfLayers == 2) {
- nr_ulsch_mmse_2layers(frame_parms,
- pusch_vars->rxdataF_comp,
- pusch_vars->ul_ch_mag0,
- pusch_vars->ul_ch_magb0,
- pusch_vars->ul_ch_magc0,
- pusch_vars->ul_ch_estimates_ext,
- rel15_ul->rb_size,
- frame_parms->nb_antennas_rx,
- rel15_ul->qam_mod_order,
- pusch_vars->log2_maxh,
- symbol,
- nb_re_pusch,
- nvar);
- }
-
- stop_meas(&gNB->ulsch_mrc_stats);
-
- if (rel15_ul->transform_precoding == transformPrecoder_enabled) {
- // For odd number of resource blocks need byte alignment to multiple of 8
- int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
-
- // perform IDFT operation on the compensated rxdata if transform precoding is enabled
- nr_idft(&pusch_vars->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch);
- LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d\n", symbol, nb_re_pusch);
- }
-
- //----------------------------------------------------------
- //--------------------- PTRS Processing --------------------
- //----------------------------------------------------------
- /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed *
- * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
- start_meas(&gNB->ulsch_ptrs_processing_stats);
- nr_pusch_ptrs_processing(gNB,
- frame_parms,
- rel15_ul,
- ulsch_id,
- slot,
- symbol,
- nb_re_pusch);
- stop_meas(&gNB->ulsch_ptrs_processing_stats);
-
- /* Subtract total PTRS RE's in the symbol from PUSCH RE's */
- pusch_vars->ul_valid_re_per_slot[symbol] -= pusch_vars->ptrs_re_per_slot;
- }
-
- /*---------------------------------------------------------------------------------------------------- */
- /*-------------------- LLRs computation -------------------------------------------------------------*/
- /*-----------------------------------------------------------------------------------------------------*/
- start_meas(&gNB->ulsch_llr_stats);
- if (ml_rx == false || rel15_ul->nrOfLayers == 1) {
- for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) {
- nr_ulsch_compute_llr(&pusch_vars->rxdataF_comp[aatx * frame_parms->nb_antennas_rx][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
- pusch_vars->ul_ch_mag0[aatx * frame_parms->nb_antennas_rx],
- pusch_vars->ul_ch_magb0[aatx * frame_parms->nb_antennas_rx],
- pusch_vars->ul_ch_magc0[aatx * frame_parms->nb_antennas_rx],
- &pusch_vars->llr_layers[aatx][rxdataF_ext_offset * rel15_ul->qam_mod_order],
- rel15_ul->rb_size,
- pusch_vars->ul_valid_re_per_slot[symbol],
- symbol,
- rel15_ul->qam_mod_order);
- }
+ nr_pusch_symbol_processing(rdata);
} else {
- nr_ulsch_compute_ML_llr(pusch_vars->rxdataF_comp,
- pusch_vars->ul_ch_mag0,
- pusch_vars->rho,
- pusch_vars->llr_layers,
- frame_parms->nb_antennas_rx,
- rel15_ul->rb_size,
- nb_re_pusch,
- symbol,
- rxdataF_ext_offset,
- rel15_ul->qam_mod_order);
-
- if (rel15_ul->qam_mod_order == 2) {
- nr_ulsch_shift_llr(pusch_vars->llr_layers, nb_re_pusch, rxdataF_ext_offset, rel15_ul->qam_mod_order, 4);
- }
-
-#ifdef ML_DEBUG
- c16_t *llr_layers0 = (c16_t *)&pusch_vars->llr_layers[0][rxdataF_ext_offset * rel15_ul->qam_mod_order];
- c16_t *llr_layers1 = (c16_t *)&pusch_vars->llr_layers[1][rxdataF_ext_offset * rel15_ul->qam_mod_order];
- printf("===============================\n");
- printf("AFTER nr_ulsch_compute_ML_llr()\n");
- printf("===============================\n");
- for (int k = 0; k < nb_re_pusch; k++) {
- printf("[%3i] llr_layers0 = (%6i, %6i), llr_layers1 = (%6i, %6i)\n",
- k, llr_layers0[k].r, llr_layers0[k].i, llr_layers1[k].r, llr_layers1[k].i);
- }
- printf("\n");
-#endif
+ pushTpool(&gNB->threadPool, req);
+ gNB->nbSymb++;
}
- stop_meas(&gNB->ulsch_llr_stats);
- rxdataF_ext_offset += pusch_vars->ul_valid_re_per_slot[symbol];
+
+ LOG_D(PHY,"%d.%d Added symbol %d (count %d) to process, in pipe\n",frame,slot,symbol,gNB->nbSymb);
}
} // symbol loop
- if (!(frame % 128)) {
- int num_llr = num_re_total*rel15_ul->qam_mod_order;
- GnbScopeUpdate(gNB, puschLLRe, num_llr);
- GnbScopeUpdate(gNB, puschIQe, num_re_total);
+
+ while (gNB->nbSymb > 0) {
+ notifiedFIFO_elt_t *req = pullTpool(&gNB->respPuschSymb, &gNB->threadPool);
+ gNB->nbSymb--;
+ delNotifiedFIFO_elt(req);
}
+
+ stop_meas(&gNB->rx_pusch_symbol_processing_stats);
+ return 0;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
index f4d526960e..1649f57878 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
@@ -30,6 +30,7 @@
* \warning
*/
+#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#include "PHY/sse_intrin.h"
#include "PHY/impl_defs_top.h"
@@ -46,16 +47,9 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
{
c16_t *rxF = (c16_t *)rxdataF_comp;
c16_t *llr32 = (c16_t *)ulsch_llr;
-
- if (!llr32) {
- LOG_E(PHY,"nr_ulsch_qpsk_llr: llr is null, symbol %d, llr32 = %p\n",symbol, llr32);
- }
for (int i = 0; i < nb_re; i++) {
- //*llr32 = *rxF;
- llr32->r = rxF->r >> 3;
- llr32->i = rxF->i >> 3;
- rxF++;
- llr32++;
+ llr32[i].r = rxF[i].r >> 3;
+ llr32[i].i = rxF[i].i >> 3;
}
}
@@ -66,72 +60,34 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
int32_t *ul_ch_mag,
int16_t *ulsch_llr,
- uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol)
{
+ simde__m256i *rxF_256 = (simde__m256i*)rxdataF_comp;
+ simde__m256i *ch_mag = (simde__m256i*)ul_ch_mag;
+ int64_t *llr_64 = (int64_t*)ulsch_llr;
- simde__m256i *rxF = (simde__m256i*)rxdataF_comp;
- simde__m256i *ch_mag;
- simde__m256i llr256[2];
- register simde__m256i xmm0;
- uint32_t *llr32;
- int i;
+ simde__m256i xmm0, xmm1, xmm2;
- int off = ((nb_rb&1) == 1)? 4:0;
-
- llr32 = (uint32_t*)ulsch_llr;
-
- ch_mag = (simde__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
- unsigned char len_mod8 = nb_re&7;
- nb_re >>= 3; // length in quad words (4 REs)
- nb_re += (len_mod8 == 0 ? 0 : 1);
-
- for (i=0; i |y_R|, registers of odd index in xmm0-> |y_I|
- xmm0 = simde_mm256_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
+ for (int i = 0; i < ((nb_re + 7) >> 3); i++) {
+ xmm0 = simde_mm256_abs_epi16(rxF_256[i]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
+ xmm0 = simde_mm256_subs_epi16(ch_mag[i], xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
- llr256[0] = simde_mm256_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st,2nd,5th and 6th REs
- llr256[1] = simde_mm256_unpackhi_epi32(rxF[i],xmm0); // llr128[1] contains the llrs of the 3rd, 4th, 7th and 8th REs
+ xmm1 = simde_mm256_unpacklo_epi32(rxF_256[i], xmm0);
+ xmm2 = simde_mm256_unpackhi_epi32(rxF_256[i], xmm0);
+
+ // xmm1 |1st 2ed 3rd 4th 9th 10th 13rd 14th|
+ // xmm2 |5th 6th 7th 8th 11st 12ed 15th 16th|
- // 1st RE
- llr32[0] = simde_mm256_extract_epi32(llr256[0],0); // llr32[0] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[1] = simde_mm256_extract_epi32(llr256[0],1); // llr32[1] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- // 2nd RE
- llr32[2] = simde_mm256_extract_epi32(llr256[0],2); // llr32[2] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[3] = simde_mm256_extract_epi32(llr256[0],3); // llr32[3] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- // 3rd RE
- llr32[4] = simde_mm256_extract_epi32(llr256[1],0); // llr32[4] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[5] = simde_mm256_extract_epi32(llr256[1],1); // llr32[5] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- // 4th RE
- llr32[6] = simde_mm256_extract_epi32(llr256[1],2); // llr32[6] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[7] = simde_mm256_extract_epi32(llr256[1],3); // llr32[7] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- // 5th RE
- llr32[8] = simde_mm256_extract_epi32(llr256[0],4); // llr32[8] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[9] = simde_mm256_extract_epi32(llr256[0],5); // llr32[9] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- // 6th RE
- llr32[10] = simde_mm256_extract_epi32(llr256[0],6); // llr32[10] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[11] = simde_mm256_extract_epi32(llr256[0],7); // llr32[11] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- // 7th RE
- llr32[12] = simde_mm256_extract_epi32(llr256[1],4); // llr32[12] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[13] = simde_mm256_extract_epi32(llr256[1],5); // llr32[13] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- // 8th RE
- llr32[14] = simde_mm256_extract_epi32(llr256[1],6); // llr32[14] low 16 bits-> y_R , high 16 bits-> y_I
- llr32[15] = simde_mm256_extract_epi32(llr256[1],7); // llr32[15] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
-
- llr32+=16;
-
+ *llr_64++ = simde_mm256_extract_epi64(xmm1, 0);
+ *llr_64++ = simde_mm256_extract_epi64(xmm1, 1);
+ *llr_64++ = simde_mm256_extract_epi64(xmm2, 0);
+ *llr_64++ = simde_mm256_extract_epi64(xmm2, 1);
+ *llr_64++ = simde_mm256_extract_epi64(xmm1, 2);
+ *llr_64++ = simde_mm256_extract_epi64(xmm1, 3);
+ *llr_64++ = simde_mm256_extract_epi64(xmm2, 2);
+ *llr_64++ = simde_mm256_extract_epi64(xmm2, 3);
}
-
- simde_mm_empty();
- simde_m_empty();
}
//----------------------------------------------------------------------------------------------
@@ -142,232 +98,110 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
int32_t *ul_ch_mag,
int32_t *ul_ch_magb,
int16_t *ulsch_llr,
- uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol)
{
- int off = ((nb_rb&1) == 1)? 4:0;
-
simde__m256i *rxF = (simde__m256i*)rxdataF_comp;
- simde__m256i *ch_mag,*ch_magb;
- register simde__m256i xmm0,xmm1,xmm2;
+ simde__m256i xmm0, xmm1, xmm2;
- int i;
+ simde__m256i *ch_maga = (simde__m256i*)ul_ch_mag;
+ simde__m256i *ch_magb = (simde__m256i*)ul_ch_magb;
- ch_mag = (simde__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
- ch_magb = (simde__m256i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))];
+ int32_t *llr_32 = (int32_t *)ulsch_llr;
- int len_mod8 = nb_re&7;
- nb_re = nb_re>>3; // length in quad words (4 REs)
- nb_re += ((len_mod8 == 0) ? 0 : 1);
-
- for (i=0; i> 3); i++) {
xmm0 = rxF[i];
- xmm1 = simde_mm256_abs_epi16(xmm0);
- xmm1 = simde_mm256_subs_epi16(ch_mag[i],xmm1);
+ xmm1 = simde_mm256_abs_epi16(xmm0); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
+ xmm1 = simde_mm256_subs_epi16(ch_maga[i], xmm1); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
xmm2 = simde_mm256_abs_epi16(xmm1);
- xmm2 = simde_mm256_subs_epi16(ch_magb[i],xmm2);
-
- // ---------------------------------------
- // 1st RE
- // ---------------------------------------
- ulsch_llr[0] = simde_mm256_extract_epi16(xmm0,0);
- ulsch_llr[1] = simde_mm256_extract_epi16(xmm0,1);
- ulsch_llr[2] = simde_mm256_extract_epi16(xmm1,0);
- ulsch_llr[3] = simde_mm256_extract_epi16(xmm1,1);
- ulsch_llr[4] = simde_mm256_extract_epi16(xmm2,0);
- ulsch_llr[5] = simde_mm256_extract_epi16(xmm2,1);
- // ---------------------------------------
+ xmm2 = simde_mm256_subs_epi16(ch_magb[i], xmm2);
+ // xmm0 |1st 4th 7th 10th 13th 16th 19th 22ed|
+ // xmm1 |2ed 5th 8th 11th 14th 17th 20th 23rd|
+ // xmm2 |3rd 6th 9th 12th 15th 18th 21st 24th|
- ulsch_llr+=6;
-
- // ---------------------------------------
- // 2nd RE
- // ---------------------------------------
- ulsch_llr[0] = simde_mm256_extract_epi16(xmm0,2);
- ulsch_llr[1] = simde_mm256_extract_epi16(xmm0,3);
- ulsch_llr[2] = simde_mm256_extract_epi16(xmm1,2);
- ulsch_llr[3] = simde_mm256_extract_epi16(xmm1,3);
- ulsch_llr[4] = simde_mm256_extract_epi16(xmm2,2);
- ulsch_llr[5] = simde_mm256_extract_epi16(xmm2,3);
- // ---------------------------------------
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,0);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,0);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,0);
- ulsch_llr+=6;
-
- // ---------------------------------------
- // 3rd RE
- // ---------------------------------------
- ulsch_llr[0] = simde_mm256_extract_epi16(xmm0,4);
- ulsch_llr[1] = simde_mm256_extract_epi16(xmm0,5);
- ulsch_llr[2] = simde_mm256_extract_epi16(xmm1,4);
- ulsch_llr[3] = simde_mm256_extract_epi16(xmm1,5);
- ulsch_llr[4] = simde_mm256_extract_epi16(xmm2,4);
- ulsch_llr[5] = simde_mm256_extract_epi16(xmm2,5);
- // ---------------------------------------
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,1);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,1);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,1);
- ulsch_llr+=6;
-
- // ---------------------------------------
- // 4th RE
- // ---------------------------------------
- ulsch_llr[0] = simde_mm256_extract_epi16(xmm0,6);
- ulsch_llr[1] = simde_mm256_extract_epi16(xmm0,7);
- ulsch_llr[2] = simde_mm256_extract_epi16(xmm1,6);
- ulsch_llr[3] = simde_mm256_extract_epi16(xmm1,7);
- ulsch_llr[4] = simde_mm256_extract_epi16(xmm2,6);
- ulsch_llr[5] = simde_mm256_extract_epi16(xmm2,7);
- // ---------------------------------------
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,2);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,2);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,2);
- ulsch_llr+=6;
- ulsch_llr[0] = simde_mm256_extract_epi16(xmm0,8);
- ulsch_llr[1] = simde_mm256_extract_epi16(xmm0,9);
- ulsch_llr[2] = simde_mm256_extract_epi16(xmm1,8);
- ulsch_llr[3] = simde_mm256_extract_epi16(xmm1,9);
- ulsch_llr[4] = simde_mm256_extract_epi16(xmm2,8);
- ulsch_llr[5] = simde_mm256_extract_epi16(xmm2,9);
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,3);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,3);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,3);
- ulsch_llr[6] = simde_mm256_extract_epi16(xmm0,10);
- ulsch_llr[7] = simde_mm256_extract_epi16(xmm0,11);
- ulsch_llr[8] = simde_mm256_extract_epi16(xmm1,10);
- ulsch_llr[9] = simde_mm256_extract_epi16(xmm1,11);
- ulsch_llr[10] = simde_mm256_extract_epi16(xmm2,10);
- ulsch_llr[11] = simde_mm256_extract_epi16(xmm2,11);
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,4);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,4);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,4);
- ulsch_llr[12] = simde_mm256_extract_epi16(xmm0,12);
- ulsch_llr[13] = simde_mm256_extract_epi16(xmm0,13);
- ulsch_llr[14] = simde_mm256_extract_epi16(xmm1,12);
- ulsch_llr[15] = simde_mm256_extract_epi16(xmm1,13);
- ulsch_llr[16] = simde_mm256_extract_epi16(xmm2,12);
- ulsch_llr[17] = simde_mm256_extract_epi16(xmm2,13);
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,5);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,5);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,5);
- ulsch_llr[18] = simde_mm256_extract_epi16(xmm0,14);
- ulsch_llr[19] = simde_mm256_extract_epi16(xmm0,15);
- ulsch_llr[20] = simde_mm256_extract_epi16(xmm1,14);
- ulsch_llr[21] = simde_mm256_extract_epi16(xmm1,15);
- ulsch_llr[22] = simde_mm256_extract_epi16(xmm2,14);
- ulsch_llr[23] = simde_mm256_extract_epi16(xmm2,15);
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,6);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,6);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,6);
- ulsch_llr+=24;
+ *llr_32++ = simde_mm256_extract_epi32(xmm0,7);
+ *llr_32++ = simde_mm256_extract_epi32(xmm1,7);
+ *llr_32++ = simde_mm256_extract_epi32(xmm2,7);
}
-
- simde_mm_empty();
- simde_m_empty();
}
void nr_ulsch_256qam_llr(int32_t *rxdataF_comp,
int32_t *ul_ch_mag,
int32_t *ul_ch_magb,
- int32_t *ul_ch_magc,
- int16_t *ulsch_llr,
- uint32_t nb_rb,
- uint32_t nb_re,
- uint8_t symbol)
+ int32_t *ul_ch_magc,
+ int16_t *ulsch_llr,
+ uint32_t nb_re,
+ uint8_t symbol)
{
- int off = ((nb_rb&1) == 1)? 4:0;
-
simde__m256i *rxF = (simde__m256i*)rxdataF_comp;
- simde__m256i *ch_mag,*ch_magb,*ch_magc;
- register simde__m256i xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6;
+ simde__m256i xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6;
simde__m256i *llr256=(simde__m256i*)ulsch_llr;
- ch_mag = (simde__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
- ch_magb = (simde__m256i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))];
- ch_magc = (simde__m256i*)&ul_ch_magc[(symbol*(off+(nb_rb*12)))];
- int len_mod8 = nb_re&7;
- int nb_re256 = nb_re>>3; // length in 256-bit words (8 REs)
+ simde__m256i* ch_maga = (simde__m256i*)ul_ch_mag;
+ simde__m256i* ch_magb = (simde__m256i*)ul_ch_magb;
+ simde__m256i* ch_magc = (simde__m256i*)ul_ch_magc;
- for (int i=0; i |y_R|, registers of odd index in xmm0-> |y_I|
- xmm0 = simde_mm256_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
- // xmmtmpD2 contains 16 LLRs
- xmm1 = simde_mm256_abs_epi16(xmm0);
- xmm1 = simde_mm256_subs_epi16(ch_magb[i],xmm1); // contains 16 LLRs
- xmm2 = simde_mm256_abs_epi16(xmm1);
- xmm2 = simde_mm256_subs_epi16(ch_magc[i],xmm2); // contains 16 LLRs
- // rxF[i] A0 A1 A2 A3 A4 A5 A6 A7 bits 7,6
- // xmm0 B0 B1 B2 B3 B4 B5 B6 B7 bits 5,4
- // xmm1 C0 C1 C2 C3 C4 C5 C6 C7 bits 3,2
- // xmm2 D0 D1 D2 D3 D4 D5 D6 D7 bits 1,0
- xmm3 = simde_mm256_unpacklo_epi32(rxF[i],xmm0); // A0 B0 A1 B1 A4 B4 A5 B5
- xmm4 = simde_mm256_unpackhi_epi32(rxF[i],xmm0); // A2 B2 A3 B3 A6 B6 A7 B7
- xmm5 = simde_mm256_unpacklo_epi32(xmm1,xmm2); // C0 D0 C1 D1 C4 D4 C5 D5
- xmm6 = simde_mm256_unpackhi_epi32(xmm1,xmm2); // C2 D2 C3 D3 C6 D6 C7 D7
-
- xmm0 = simde_mm256_unpacklo_epi64(xmm3,xmm5); // A0 B0 C0 D0 A4 B4 C4 D4
- xmm1 = simde_mm256_unpackhi_epi64(xmm3,xmm5); // A1 B1 C1 D1 A5 B5 C5 D5
- xmm2 = simde_mm256_unpacklo_epi64(xmm4,xmm6); // A2 B2 C2 D2 A6 B6 C6 D6
- xmm3 = simde_mm256_unpackhi_epi64(xmm4,xmm6); // A3 B3 C3 D3 A7 B7 C7 D7
- llr256[0] = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x20); // A0 B0 C0 D0 A1 B1 C1 D1
- llr256[1] = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x20); // A2 B2 C2 D2 A3 B3 C3 D3
- llr256[2] = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x31); // A4 B4 C4 D4 A5 B5 C5 D5
- llr256[3] = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x31); // A6 B6 C6 D6 A7 B7 C7 D7
- llr256+=4;
+ for (int i = 0; i < ((nb_re + 7) >> 3); i++) {
+ xmm0 = simde_mm256_abs_epi16(rxF[i]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
+ xmm0 = simde_mm256_subs_epi16(ch_maga[i], xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
+ // xmmtmpD2 contains 16 LLRs
+ xmm1 = simde_mm256_abs_epi16(xmm0);
+ xmm1 = simde_mm256_subs_epi16(ch_magb[i], xmm1); // contains 16 LLRs
+ xmm2 = simde_mm256_abs_epi16(xmm1);
+ xmm2 = simde_mm256_subs_epi16(ch_magc[i], xmm2); // contains 16 LLRs
+ // rxF[i] A0 A1 A2 A3 A4 A5 A6 A7 bits 7,6
+ // xmm0 B0 B1 B2 B3 B4 B5 B6 B7 bits 5,4
+ // xmm1 C0 C1 C2 C3 C4 C5 C6 C7 bits 3,2
+ // xmm2 D0 D1 D2 D3 D4 D5 D6 D7 bits 1,0
+ xmm3 = simde_mm256_unpacklo_epi32(rxF[i], xmm0); // A0 B0 A1 B1 A4 B4 A5 B5
+ xmm4 = simde_mm256_unpackhi_epi32(rxF[i], xmm0); // A2 B2 A3 B3 A6 B6 A7 B7
+ xmm5 = simde_mm256_unpacklo_epi32(xmm1, xmm2); // C0 D0 C1 D1 C4 D4 C5 D5
+ xmm6 = simde_mm256_unpackhi_epi32(xmm1, xmm2); // C2 D2 C3 D3 C6 D6 C7 D7
+ xmm0 = simde_mm256_unpacklo_epi64(xmm3, xmm5); // A0 B0 C0 D0 A4 B4 C4 D4
+ xmm1 = simde_mm256_unpackhi_epi64(xmm3, xmm5); // A1 B1 C1 D1 A5 B5 C5 D5
+ xmm2 = simde_mm256_unpacklo_epi64(xmm4, xmm6); // A2 B2 C2 D2 A6 B6 C6 D6
+ xmm3 = simde_mm256_unpackhi_epi64(xmm4, xmm6); // A3 B3 C3 D3 A7 B7 C7 D7
+ *llr256++ = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x20); // A0 B0 C0 D0 A1 B1 C1 D1
+ *llr256++ = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x20); // A2 B2 C2 D2 A3 B3 C3 D3
+ *llr256++ = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x31); // A4 B4 C4 D4 A5 B5 C5 D5
+ *llr256++ = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x31); // A6 B6 C6 D6 A7 B7 C7 D7
}
- simde__m128i *llr128 = (simde__m128i*)llr256;
- if (len_mod8 >= 4) {
- int nb_re128 = nb_re>>2;
- simde__m128i xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6;
- simde__m128i *rxF = (simde__m128i*)rxdataF_comp;
- simde__m128i *ch_mag = (simde__m128i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
- simde__m128i *ch_magb = (simde__m128i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))];
- simde__m128i *ch_magc = (simde__m128i*)&ul_ch_magc[(symbol*(off+(nb_rb*12)))];
-
- xmm0 = simde_mm_abs_epi16(rxF[nb_re128-1]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
- xmm0 = simde_mm_subs_epi16(ch_mag[nb_re128-1],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
- // xmmtmpD2 contains 8 LLRs
- xmm1 = simde_mm_abs_epi16(xmm0);
- xmm1 = simde_mm_subs_epi16(ch_magb[nb_re128-1],xmm1); // contains 8 LLRs
- xmm2 = simde_mm_abs_epi16(xmm1);
- xmm2 = simde_mm_subs_epi16(ch_magc[nb_re128-1],xmm2); // contains 8 LLRs
- // rxF[i] A0 A1 A2 A3
- // xmm0 B0 B1 B2 B3
- // xmm1 C0 C1 C2 C3
- // xmm2 D0 D1 D2 D3
- xmm3 = simde_mm_unpacklo_epi32(rxF[nb_re128-1],xmm0); // A0 B0 A1 B1
- xmm4 = simde_mm_unpackhi_epi32(rxF[nb_re128-1],xmm0); // A2 B2 A3 B3
- xmm5 = simde_mm_unpacklo_epi32(xmm1,xmm2); // C0 D0 C1 D1
- xmm6 = simde_mm_unpackhi_epi32(xmm1,xmm2); // C2 D2 C3 D3
-
- llr128[0] = simde_mm_unpacklo_epi64(xmm3,xmm5); // A0 B0 C0 D0
- llr128[1] = simde_mm_unpackhi_epi64(xmm3,xmm5); // A1 B1 C1 D1
- llr128[2] = simde_mm_unpacklo_epi64(xmm4,xmm6); // A2 B2 C2 D2
- llr128[3] = simde_mm_unpackhi_epi64(xmm4,xmm6); // A3 B3 C3 D3
- llr128+=4;
- }
- if (len_mod8 == 6) {
- int nb_re64 = nb_re>>1;
- simde__m64 *llr64 = (simde__m64 *)llr128;
- simde__m64 xmm0,xmm1,xmm2;
- simde__m64 *rxF = (simde__m64*)rxdataF_comp;
- simde__m64 *ch_mag = (simde__m64*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
- simde__m64 *ch_magb = (simde__m64*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))];
- simde__m64 *ch_magc = (simde__m64*)&ul_ch_magc[(symbol*(off+(nb_rb*12)))];
-
- xmm0 = simde_mm_abs_pi16(rxF[nb_re64-1]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
- xmm0 = simde_mm_subs_pi16(ch_mag[nb_re-1],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
- // xmmtmpD2 contains 4 LLRs
- xmm1 = simde_mm_abs_pi16(xmm0);
- xmm1 = simde_mm_subs_pi16(ch_magb[nb_re64-1],xmm1); // contains 4 LLRs
- xmm2 = simde_mm_abs_pi16(xmm1);
- xmm2 = simde_mm_subs_pi16(ch_magc[nb_re64-1],xmm2); // contains 4 LLRs
- // rxF[i] A0 A1
- // xmm0 B0 B1
- // xmm1 C0 C1
- // xmm2 D0 D1
- llr64[0] = simde_m_punpckldq(rxF[nb_re64-1],xmm0); // A0 B0
- llr64[2] = simde_m_punpckhdq(rxF[nb_re64-1],xmm0); // A1 B1
- llr64[1] = simde_m_punpckldq(xmm1,xmm2); // C0 D0
- llr64[3] = simde_m_punpckhdq(xmm1,xmm2); // C1 D1
- }
-
}
+
void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
int32_t *ul_ch_mag,
int32_t *ul_ch_magb,
int32_t *ul_ch_magc,
int16_t *ulsch_llr,
- uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol,
uint8_t mod_order)
@@ -383,7 +217,6 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
nr_ulsch_16qam_llr(rxdataF_comp,
ul_ch_mag,
ulsch_llr,
- nb_rb,
nb_re,
symbol);
break;
@@ -392,7 +225,6 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
ul_ch_mag,
ul_ch_magb,
ulsch_llr,
- nb_rb,
nb_re,
symbol);
break;
@@ -402,7 +234,6 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
ul_ch_magb,
ul_ch_magc,
ulsch_llr,
- nb_rb,
nb_re,
symbol);
break;
@@ -3786,46 +3617,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in,
simde_m_empty();
}
-void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp,
- int32_t **ul_ch_mag,
- int32_t ***rho,
- int16_t **llr_layers,
- uint8_t nb_antennas_rx,
- uint32_t rb_size,
- uint32_t nb_re,
- uint8_t symbol,
- uint32_t rxdataF_ext_offset,
- uint8_t mod_order)
-{
- int off = ((rb_size & 1) == 1) ? 4 : 0;
- c16_t *rxdataF_comp0 = (c16_t *)&rxdataF_comp[0][symbol * (off + (rb_size * NR_NB_SC_PER_RB))];
- c16_t *rxdataF_comp1 = (c16_t *)&rxdataF_comp[nb_antennas_rx][symbol * (off + (rb_size * NR_NB_SC_PER_RB))];
- c16_t *ul_ch_mag0 = (c16_t *)&ul_ch_mag[0][symbol * (off + (rb_size * NR_NB_SC_PER_RB))];
- c16_t *ul_ch_mag1 = (c16_t *)&ul_ch_mag[nb_antennas_rx][symbol * (off + (rb_size * NR_NB_SC_PER_RB))];
- c16_t *llr_layers0 = (c16_t *)&llr_layers[0][rxdataF_ext_offset * mod_order];
- c16_t *llr_layers1 = (c16_t *)&llr_layers[1][rxdataF_ext_offset * mod_order];
- c16_t *rho0 = (c16_t *)&rho[0][1][symbol * (off + (rb_size * NR_NB_SC_PER_RB))];
- c16_t *rho1 = (c16_t *)&rho[0][2][symbol * (off + (rb_size * NR_NB_SC_PER_RB))];
-
- switch (mod_order) {
- case 2:
- nr_ulsch_qpsk_qpsk(rxdataF_comp0, rxdataF_comp1, llr_layers0, rho0, nb_re);
- nr_ulsch_qpsk_qpsk(rxdataF_comp1, rxdataF_comp0, llr_layers1, rho1, nb_re);
- break;
- case 4:
- nr_ulsch_qam16_qam16(rxdataF_comp0, rxdataF_comp1, ul_ch_mag0, ul_ch_mag1, llr_layers0, rho0, nb_re);
- nr_ulsch_qam16_qam16(rxdataF_comp1, rxdataF_comp0, ul_ch_mag1, ul_ch_mag0, llr_layers1, rho1, nb_re);
- break;
- case 6:
- nr_ulsch_qam64_qam64(rxdataF_comp0, rxdataF_comp1, ul_ch_mag0, ul_ch_mag1, llr_layers0, rho0, nb_re);
- nr_ulsch_qam64_qam64(rxdataF_comp1, rxdataF_comp0, ul_ch_mag1, ul_ch_mag0, llr_layers1, rho1, nb_re);
- break;
- default:
- AssertFatal(1 == 0, "nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n", symbol, mod_order);
- }
-}
-
-void nr_ulsch_shift_llr(int16_t **llr_layers, uint32_t nb_re, uint32_t rxdataF_ext_offset, uint8_t mod_order, int shift)
+static void nr_ulsch_shift_llr(int16_t **llr_layers, uint32_t nb_re, uint32_t rxdataF_ext_offset, uint8_t mod_order, int shift)
{
simde__m128i *llr_layers0 = (simde__m128i *)&llr_layers[0][rxdataF_ext_offset * mod_order];
simde__m128i *llr_layers1 = (simde__m128i *)&llr_layers[1][rxdataF_ext_offset * mod_order];
@@ -3848,3 +3640,35 @@ void nr_ulsch_shift_llr(int16_t **llr_layers, uint32_t nb_re, uint32_t rxdataF_e
llr_layers1[i] = simde_mm_srai_epi16(llr_layers1[i], shift);
}
}
+
+void nr_ulsch_compute_ML_llr(NR_gNB_PUSCH *pusch_vars,
+ uint32_t symbol,
+ c16_t* rxdataF_comp0,
+ c16_t* rxdataF_comp1,
+ c16_t* ul_ch_mag0,
+ c16_t* ul_ch_mag1,
+ c16_t* llr_layers0,
+ c16_t* llr_layers1,
+ c16_t* rho0,
+ c16_t* rho1,
+ uint32_t nb_re,
+ uint8_t mod_order)
+{
+ switch (mod_order) {
+ case 2:
+ nr_ulsch_qpsk_qpsk(rxdataF_comp0, rxdataF_comp1, llr_layers0, rho0, nb_re);
+ nr_ulsch_qpsk_qpsk(rxdataF_comp1, rxdataF_comp0, llr_layers1, rho1, nb_re);
+ nr_ulsch_shift_llr(pusch_vars->llr_layers, nb_re, pusch_vars->llr_offset[symbol] >> 1, 2, 4);
+ break;
+ case 4:
+ nr_ulsch_qam16_qam16(rxdataF_comp0, rxdataF_comp1, ul_ch_mag0, ul_ch_mag1, llr_layers0, rho0, nb_re);
+ nr_ulsch_qam16_qam16(rxdataF_comp1, rxdataF_comp0, ul_ch_mag1, ul_ch_mag0, llr_layers1, rho1, nb_re);
+ break;
+ case 6:
+ nr_ulsch_qam64_qam64(rxdataF_comp0, rxdataF_comp1, ul_ch_mag0, ul_ch_mag1, llr_layers0, rho0, nb_re);
+ nr_ulsch_qam64_qam64(rxdataF_comp1, rxdataF_comp0, ul_ch_mag1, ul_ch_mag0, llr_layers1, rho1, nb_re);
+ break;
+ default:
+ AssertFatal(1 == 0, "nr_ulsch_compute_llr: invalid Qm value, Qm = %d\n", mod_order);
+ }
+}
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 305a90d819..de3555bf29 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -1693,12 +1693,16 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
// run polar decoder on llrs
decoderState = polar_decoder_int16((int16_t *)llrs, decodedPayload, 0, NR_POLAR_UCI_PUCCH_MESSAGE_TYPE, nb_bit, pucch_pdu->prb_size);
- LOG_D(PHY,"UCI decoderState %d, payload[0] %llu\n",decoderState,(unsigned long long)decodedPayload[0]);
+ // Decoder reversal
+ decodedPayload[0] = reverse_bits(decodedPayload[0], nb_bit);
+
if (decoderState>0) decoderState=1;
corr_dB = dB_fixed64(corr);
LOG_D(PHY,"metric %d dB\n",corr_dB);
}
+ LOG_D(PHY, "UCI decoderState %d, payload[0] %llu\n", decoderState, (unsigned long long)decodedPayload[0]);
+
// estimate CQI for MAC (from antenna port 0 only)
// TODO this computation is wrong -> to be ignored at MAC for now
int SNRtimes10 = dB_fixed_times10(signal_energy_nodc((int32_t *)&rxdataF[0][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[0]],
@@ -1761,7 +1765,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
}
bit_left = pucch_pdu->bit_len_csi_part1-((csi_part1_bytes-1)<<3);
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<bit_len_csi_part1 < 64 ? decodedPayload[0] >> pucch_pdu->bit_len_csi_part1 : 0;
+ decodedPayload[0] = pucch_pdu->bit_len_csi_part1 < 64 ? decodedPayload[0] >> bit_left : 0;
}
if (pucch_pdu->bit_len_csi_part2>0) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index f3ee7b0e7b..c993ec3709 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -44,6 +44,7 @@
#include "executables/nr-uesoftmodem.h"
#include "PHY/CODING/nrLDPC_extern.h"
#include "common/utils/nr/nr_common.h"
+#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
@@ -116,10 +117,8 @@ static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue,
if (*num_seg_ok == harq_process->C) {
if (harq_process->C > 1) {
/* check global CRC */
- int A = tbs;
- int crc_length = A > 3824 ? 3 : 2;
- int crc_type = A > 3824 ? CRC24_A : CRC16;
- if (!check_crc(b, A + crc_length * 8, crc_type)) {
+ // we have regrouped the transport block, so it is "1" segment
+ if (!check_crc(b, lenWithCrc(1, tbs), crcType(1, tbs))) {
harq_process->ack = 0;
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1;
LOG_E(PHY, " Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n", proc->frame_rx, proc->nr_slot_rx, harq_process->C);
@@ -166,10 +165,8 @@ static void nr_processDLSegment(void *arg)
NR_UE_DLSCH_t *dlsch = rdata->dlsch;
NR_DL_UE_HARQ_t *harq_process= rdata->harq_process;
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
- int length_dec;
int Kr;
int K_bits_F;
- uint8_t crc_type;
int r = rdata->segment_r;
int A = rdata->A;
int E = rdata->E;
@@ -240,19 +237,6 @@ static void nr_processDLSegment(void *arg)
LOG_D(PHY,"\n");
}
-
- if (harq_process->C == 1) {
- if (A > NR_MAX_PDSCH_TBS)
- crc_type = CRC24_A;
- else
- crc_type = CRC16;
-
- length_dec = harq_process->B;
- } else {
- crc_type = CRC24_B;
- length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
- }
-
{
start_meas(&rdata->ts_ldpc_decode);
//set first 2*Z_c bits to zeros
@@ -272,9 +256,9 @@ static void nr_processDLSegment(void *arg)
}
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
- p_decoderParms->block_length=length_dec;
- nrLDPC_initcall(p_decoderParms, (int8_t*)&pl[0], LDPCoutput);
- p_decoderParms->crc_type = crc_type;
+ p_decoderParms->block_length = lenWithCrc(harq_process->C, A);
+ p_decoderParms->crc_type = crcType(harq_process->C, A);
+ nrLDPC_initcall(p_decoderParms, (int8_t *)&pl[0], LDPCoutput);
rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], LDPCoutput, &procTime, &harq_process->abort_decode);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
@@ -311,8 +295,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
// HARQ stats
phy_vars_ue->dl_stats[harq_process->DLround]++;
- LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,dlsch->dlsch_config.rv);
- uint8_t kc;
+ LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch->dlsch_config.rv);
uint16_t nb_rb;// = 30;
uint8_t dmrs_Type = dlsch->dlsch_config.dmrsConfigType;
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
@@ -377,33 +360,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
LOG_D(PHY,"%d.%d DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d Qm %d Coderate %f\n",
frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, dlsch->dlsch_config.mcs, dlsch->Nl, nb_symb_sch, nb_rb, dlsch->dlsch_config.qamModOrder, Coderate);
-
- if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
- p_decParams->BG = 2;
- kc = 52;
- } else {
- p_decParams->BG = 1;
- kc = 68;
- }
+ p_decParams->BG = get_BG(A, dlsch->dlsch_config.targetCodeRate);
+ unsigned int kc = p_decParams->BG == 2 ? 52 : 68;
if (harq_process->first_rx == 1) {
// This is a new packet, so compute quantities regarding segmentation
- if (A > NR_MAX_PDSCH_TBS)
- harq_process->B = A+24;
- else
- harq_process->B = A+16;
-
nr_segmentation(NULL,
NULL,
- harq_process->B,
+ lenWithCrc(1, A), // We give a max size in case of 1 segment
&harq_process->C,
&harq_process->K,
&harq_process->Z, // [hna] Z is Zc
&harq_process->F,
p_decParams->BG);
-
+
if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl) {
- LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B);
+ LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, A);
return(-1);
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index ee79bdc47b..c7d10b69f4 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -493,12 +493,8 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
}
// printf("polar decoder output 0x%08x\n",pbch_a_prime);
// Decoder reversal
- uint32_t a_reversed=0;
+ pbch_a_prime = (uint32_t)reverse_bits(pbch_a_prime, NR_POLAR_PBCH_PAYLOAD_BITS);
- for (int i=0; i>i)&1)<<(31-i);
-
- pbch_a_prime = a_reversed;
//payload un-scrambling
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = ((pbch_a_prime>>24)&1) ^ (((pbch_a_prime>>6)&1)<<1);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 9f9b123781..b0ea45b7ec 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -53,8 +53,6 @@ typedef struct {
SCH_status_t status;
/// Last TPC command
uint8_t TPC;
- /// The payload + CRC size in bits, "B" from 36-212
- uint32_t B;
/// Length of ACK information (bits)
uint8_t O_ACK;
/// Index of current HARQ round for this ULSCH
@@ -117,8 +115,6 @@ typedef struct {
uint8_t Ndi;
/// DLSCH status flag indicating
SCH_status_t status;
- /// The payload + CRC size in bits
- uint32_t B;
/// Pointers to transport block segments
uint8_t **c;
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 42fe941848..1c4d7c0fec 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -92,8 +92,8 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
*/
int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers*1056;
-
- if (A > 3824) {
+ int B;
+ if (A > NR_MAX_PDSCH_TBS) {
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(harq_process->a,A)>>8;
harq_process->a[A>>3] = ((uint8_t*)&crc)[2];
@@ -102,13 +102,12 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
- harq_process->B = A+24;
+ B = A + 24;
AssertFatal((A/8)+4 <= max_payload_bytes,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,max_payload_bytes);
memcpy(harq_process->b,harq_process->a,(A/8)+4);
- }
- else {
+ } else {
// Add 16-bit crc (polynomial A) to payload
crc = crc16(harq_process->a,A)>>16;
harq_process->a[A>>3] = ((uint8_t*)&crc)[1];
@@ -116,7 +115,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
- harq_process->B = A+16;
+ B = A + 16;
AssertFatal((A/8)+3 <= max_payload_bytes,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,max_payload_bytes);
@@ -128,26 +127,25 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
///////////////////////// b---->| block segmentation |---->c /////////////////////////
///////////
- if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
+ if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
harq_process->BG = 2;
- }
- else{
+ } else {
harq_process->BG = 1;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_segmentation_stats);
- uint32_t Kb=nr_segmentation(harq_process->b,
- harq_process->c,
- harq_process->B,
- &harq_process->C,
- &harq_process->K,
- pz,
- &harq_process->F,
- harq_process->BG);
+ uint32_t Kb = nr_segmentation(harq_process->b,
+ harq_process->c,
+ B,
+ &harq_process->C,
+ &harq_process->K,
+ pz,
+ &harq_process->F,
+ harq_process->BG);
if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers) {
- LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B);
+ LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", harq_process->C, B);
return(-1);
}
stop_meas(&ue->ulsch_segmentation_stats);
@@ -169,7 +167,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
for (int r=0; rC; r++) {
//channel_input[r] = &harq_process->d[r][0];
#ifdef DEBUG_ULSCH_CODING
- printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F);
+ printf("Encoder: B %d F %d \n", B, harq_process->F);
printf("start ldpc encoder segment %d/%d\n",r,harq_process->C);
printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
index d59da8be97..f5c4276562 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
@@ -644,7 +644,9 @@ static void nr_uci_encoding(uint64_t payload,
b[7] = b[0];
AssertFatal(nrofPRB<=16,"Number of PRB >16\n");
} else if (A>=12) {
- AssertFatal(A<65,"Polar encoding not supported yet for UCI with more than 64 bits\n");
+ // Encoder reversal
+ payload = reverse_bits(payload, A);
+
polar_encoder_fast(&payload, b, 0,0,
NR_POLAR_UCI_PUCCH_MESSAGE_TYPE,
A,
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index c2e6dfba75..5252d7a4e3 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -75,8 +75,6 @@ typedef struct {
nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu;
/// pointer to pdu from MAC interface (this is "a" in 36.212)
uint8_t *pdu;
- /// The payload + CRC size in bits, "B" from 36-212
- uint32_t B;
/// Pointer to the payload
uint8_t *b;
/// Pointers to transport block segments
@@ -199,8 +197,6 @@ typedef struct {
uint32_t TBS;
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
uint8_t *b;
- /// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1)
- uint32_t B;
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
uint8_t **c;
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
@@ -227,6 +223,18 @@ typedef struct {
int llrLen;
//////////////////////////////////////////////////////////////
} NR_UL_gNB_HARQ_t;
+static inline int lenWithCrc(int nbSeg, int len)
+{
+ if (nbSeg > 1)
+ return (len + 24 + 24 * nbSeg) / nbSeg;
+ return len + (len > NR_MAX_PDSCH_TBS ? 24 : 16);
+}
+static inline int crcType(int nbSeg, int len)
+{
+ if (nbSeg > 1)
+ return CRC24_B;
+ return len > NR_MAX_PDSCH_TBS ? CRC24_A : CRC16;
+}
typedef struct {
//! estimated received spatial signal power (linear)
@@ -409,8 +417,8 @@ typedef struct {
/// \brief Total RE count after DMRS/PTRS RE's are extracted from respective symbol.
/// - first index: ? [0...14] smybol per slot
int16_t *ul_valid_re_per_slot;
- /// flag to verify if channel level computation is done
- uint8_t cl_done;
+ /// \brief offset for llr corresponding to each symbol
+ int llr_offset[14];
/// flag to indicate DTX on reception
int DTX;
} NR_gNB_PUSCH;
@@ -728,18 +736,14 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t dlsch_segmentation_stats;
time_stats_t rx_pusch_stats;
+ time_stats_t rx_pusch_init_stats;
+ time_stats_t rx_pusch_symbol_processing_stats;
time_stats_t ul_indication_stats;
time_stats_t schedule_response_stats;
time_stats_t ulsch_decoding_stats;
- time_stats_t ulsch_rate_unmatching_stats;
time_stats_t ulsch_ldpc_decoding_stats;
time_stats_t ulsch_deinterleaving_stats;
- time_stats_t ulsch_unscrambling_stats;
time_stats_t ulsch_channel_estimation_stats;
- time_stats_t ulsch_ptrs_processing_stats;
- time_stats_t ulsch_channel_compensation_stats;
- time_stats_t ulsch_rbs_extraction_stats;
- time_stats_t ulsch_mrc_stats;
time_stats_t ulsch_llr_stats;
time_stats_t rx_srs_stats;
time_stats_t generate_srs_stats;
@@ -754,6 +758,7 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t rx_dft_stats;
time_stats_t ulsch_freq_offset_estimation_stats;
*/
+ notifiedFIFO_t respPuschSymb;
notifiedFIFO_t respDecode;
notifiedFIFO_t resp_L1;
notifiedFIFO_t L1_tx_free;
@@ -761,6 +766,8 @@ typedef struct PHY_VARS_gNB_s {
notifiedFIFO_t L1_tx_out;
notifiedFIFO_t resp_RU_tx;
tpool_t threadPool;
+ int nbSymb;
+ int num_pusch_symbols_per_thread;
pthread_t L1_rx_thread;
int L1_rx_thread_core;
pthread_t L1_tx_thread;
@@ -771,6 +778,32 @@ typedef struct PHY_VARS_gNB_s {
rt_L1_profiling_t rt_L1_profiling;
} PHY_VARS_gNB;
+typedef struct puschSymbolProc_s {
+ PHY_VARS_gNB *gNB;
+ NR_DL_FRAME_PARMS *frame_parms;
+ nfapi_nr_pusch_pdu_t *rel15_ul;
+ int ulsch_id;
+ int slot;
+ int startSymbol;
+ int numSymbols;
+ int16_t *llr;
+ int16_t **llr_layers;
+ int16_t *s;
+ uint32_t nvar;
+} puschSymbolProc_t;
+
+struct puschSymbolReqId {
+ uint16_t ulsch_id;
+ uint16_t frame;
+ uint8_t slot;
+ uint16_t spare;
+} __attribute__((packed));
+
+union puschSymbolReqUnion {
+ struct puschSymbolReqId s;
+ uint64_t p;
+};
+
typedef struct LDPCDecode_s {
PHY_VARS_gNB *gNB;
NR_UL_gNB_HARQ_t *ulsch_harq;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index ad04ee9436..c5af8b8415 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -43,7 +43,7 @@
#define nr_slot_t lte_subframe_t
#define MAX_NUM_SUBCARRIER_SPACING 5
-#define NR_MAX_OFDM_SYMBOL_SIZE 4096
+#define NR_MAX_OFDM_SYMBOL_SIZE 8192
#define NR_SYMBOLS_PER_SLOT NR_NUMBER_OF_SYMBOLS_PER_SLOT
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 184e3ec63b..cf47c699d9 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -266,12 +266,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
// CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block
bool crc_valid = true;
if (ulsch_harq->C > 1) {
- // Check ULSCH transport block CRC
- int crc_type = CRC16;
- if (rdata->A > 3824) {
- crc_type = CRC24_A;
- }
- crc_valid = check_crc(ulsch_harq->b, ulsch_harq->B, crc_type);
+ crc_valid = check_crc(ulsch_harq->b, lenWithCrc(1, rdata->A), crcType(1, rdata->A));
}
if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
@@ -397,19 +392,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
-
- nr_ulsch_layer_demapping(gNB->pusch_vars[ULSCH_id].llr,
- pusch_pdu->nrOfLayers,
- pusch_pdu->qam_mod_order,
- G,
- gNB->pusch_vars[ULSCH_id].llr_layers);
-
- //----------------------------------------------------------
- //------------------- ULSCH unscrambling -------------------
- //----------------------------------------------------------
- start_meas(&gNB->ulsch_unscrambling_stats);
- nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id].llr, G, pusch_pdu->data_scrambling_id, pusch_pdu->rnti);
- stop_meas(&gNB->ulsch_unscrambling_stats);
+
//----------------------------------------------------------
//--------------------- ULSCH decoding ---------------------
//----------------------------------------------------------
@@ -417,7 +400,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int
start_meas(&gNB->ulsch_decoding_stats);
int nbDecode =
nr_ulsch_decoding(gNB, ULSCH_id, gNB->pusch_vars[ULSCH_id].llr, frame_parms, pusch_pdu, frame_rx, slot_rx, harq_pid, G);
- stop_meas(&gNB->ulsch_decoding_stats);
+
return nbDecode;
}
@@ -899,7 +882,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH, 1);
start_meas(&gNB->rx_pusch_stats);
- nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid);
+ nr_rx_pusch_tp(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid);
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id];
pusch_vars->ulsch_power_tot = 0;
pusch_vars->ulsch_noise_power_tot = 0;
@@ -953,7 +936,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0);
}
}
- if (totalDecode > 0 && gNB->ldpc_offload_flag == 0) {
while (totalDecode > 0) {
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
if (req == NULL)
@@ -962,7 +944,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
delNotifiedFIFO_elt(req);
totalDecode--;
}
- }
+ stop_meas(&gNB->ulsch_decoding_stats);
for (int i = 0; i < gNB->max_nb_srs; i++) {
NR_gNB_SRS_t *srs = &gNB->srs[i];
if (srs) {
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 5ee660d1e0..762487c759 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -561,10 +561,12 @@ int main(int argc, char *argv[])
RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0];
gNB->ofdm_offset_divisor = UINT_MAX;
- initNotifiedFIFO(&gNB->respDecode);
+ gNB->num_pusch_symbols_per_thread = 1;
initFloatingCoresTpool(threadCnt, &gNB->threadPool, false, "gNB-tpool");
initNotifiedFIFO(&gNB->respDecode);
+
+ initNotifiedFIFO(&gNB->respPuschSymb);
initNotifiedFIFO(&gNB->L1_tx_free);
initNotifiedFIFO(&gNB->L1_tx_filled);
initNotifiedFIFO(&gNB->L1_tx_out);
@@ -719,7 +721,6 @@ int main(int argc, char *argv[])
NR_gNB_ULSCH_t *ulsch_gNB = &gNB->ulsch[UE_id];
- // nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_process->ulsch_pdu;
NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO));
memset((void*)Sched_INFO,0,sizeof(*Sched_INFO));
nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req;
@@ -927,15 +928,10 @@ int main(int argc, char *argv[])
roundStats = 0;
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->rx_pusch_stats);
+ reset_meas(&gNB->rx_pusch_init_stats);
+ reset_meas(&gNB->rx_pusch_symbol_processing_stats);
reset_meas(&gNB->ulsch_decoding_stats);
- reset_meas(&gNB->ulsch_deinterleaving_stats);
- reset_meas(&gNB->ulsch_rate_unmatching_stats);
- reset_meas(&gNB->ulsch_ldpc_decoding_stats);
- reset_meas(&gNB->ulsch_unscrambling_stats);
reset_meas(&gNB->ulsch_channel_estimation_stats);
- reset_meas(&gNB->ulsch_llr_stats);
- reset_meas(&gNB->ulsch_channel_compensation_stats);
- reset_meas(&gNB->ulsch_rbs_extraction_stats);
reset_meas(&UE->ulsch_ldpc_encoding_stats);
reset_meas(&UE->ulsch_rate_matching_stats);
reset_meas(&UE->ulsch_interleaving_stats);
@@ -1588,25 +1584,22 @@ int main(int argc, char *argv[])
dump_pusch_stats(fd,gNB);
fclose(fd);
- if (print_perf==1) {
- printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
- printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
- printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
- printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
- printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
- printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
- printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
- printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
- printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
+ if (print_perf==1)
+ {
+ printf("gNB RX\n");
+ printDistribution(&gNB->phy_proc_rx,table_rx, "Total PHY proc rx");
+ printStatIndent(&gNB->rx_pusch_stats, "RX PUSCH time");
+ printStatIndent2(&gNB->ulsch_channel_estimation_stats, "ULSCH channel estimation time");
+ printStatIndent2(&gNB->rx_pusch_init_stats, "RX PUSCH Initialization time");
+ printStatIndent2(&gNB->rx_pusch_symbol_processing_stats, "RX PUSCH Symbol Processing time");
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
+
+ printf("\nUE TX\n");
printStatIndent(&UE->ulsch_encoding_stats,"ULSCH total encoding time");
printStatIndent2(&UE->ulsch_segmentation_stats,"ULSCH segmentation time");
printStatIndent2(&UE->ulsch_ldpc_encoding_stats,"ULSCH LDPC encoder time");
printStatIndent2(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time");
printStatIndent2(&UE->ulsch_interleaving_stats,"ULSCH interleaving time");
- //printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
- //printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
- //printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
printStatIndent(&gNB->rx_srs_stats,"RX SRS time");
printStatIndent2(&gNB->generate_srs_stats,"Generate SRS sequence time");
printStatIndent2(&gNB->get_srs_signal_stats,"Get SRS signal time");
diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h
index b47a763089..8f8a047ee5 100644
--- a/openair2/COMMON/f1ap_messages_types.h
+++ b/openair2/COMMON/f1ap_messages_types.h
@@ -301,6 +301,10 @@ typedef struct f1ap_rb_failed_to_be_setup_s {
long rb_id;
} f1ap_rb_failed_to_be_setup_t;
+typedef struct f1ap_drb_to_be_released_t {
+ long rb_id;
+} f1ap_drb_to_be_released_t;
+
typedef struct cu_to_du_rrc_information_s {
uint8_t * cG_ConfigInfo;
uint32_t cG_ConfigInfo_length;
@@ -354,6 +358,8 @@ typedef struct f1ap_ue_context_setup_s {
f1ap_srb_to_be_setup_t *srbs_to_be_setup;
uint8_t srbs_to_be_setup_length;
uint8_t srbs_failed_to_be_setup_length;
+ uint8_t drbs_to_be_released_length;
+ f1ap_drb_to_be_released_t *drbs_to_be_released;
f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup;
ReconfigurationCompl_t ReconfigComplOutcome;
uint8_t *rrc_container;
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index 9e9a85d9e5..1fb4981330 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -1531,14 +1531,14 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
}
/* optional */
- if(0){
+ if (f1ap_ue_context_modification_req->drbs_to_be_released_length > 0) {
/* c15. DRBs_ToBeReleased_List */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie15);
ie15->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List;
ie15->criticality = F1AP_Criticality_reject;
ie15->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List;
- for (int i=0; i<1; i++) {
+ for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_released_length; i++) {
//
asn1cSequenceAdd(ie15->value.choice.DRBs_ToBeReleased_List.list,
F1AP_DRBs_ToBeReleased_ItemIEs_t, drbs_toBeReleased_item_ies);
@@ -1549,7 +1549,10 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
F1AP_DRBs_ToBeReleased_Item_t *drbs_toBeReleased_item=
&drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item;
/* dRBID */
- drbs_toBeReleased_item->dRBID = 30L;
+ drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id;
+ newGtpuDeleteOneTunnel(getCxt(instance)->gtpInst,
+ f1ap_ue_context_modification_req->gNB_CU_ue_id,
+ f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id);
}
}
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
index f3ee222bea..b9d29303f0 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -881,6 +881,24 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
}
}
}
+
+ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDrb, container,
+ F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List, false);
+ if (ieDrb != NULL) {
+ f1ap_ue_context_modification_req->drbs_to_be_released_length = ieDrb->value.choice.DRBs_ToBeReleased_List.list.count;
+ f1ap_ue_context_modification_req->drbs_to_be_released =
+ calloc(f1ap_ue_context_modification_req->drbs_to_be_released_length, sizeof(f1ap_drb_to_be_released_t));
+ AssertFatal(f1ap_ue_context_modification_req->drbs_to_be_released,
+ "could not allocate memory for f1ap_ue_context_released_req->drbs_to_be_released\n");
+ for (i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_released_length; ++i) {
+ F1AP_DRBs_ToBeReleased_ItemIEs_t *tbrel = (F1AP_DRBs_ToBeReleased_ItemIEs_t *)ieDrb->value.choice.DRBs_ToBeReleased_List.list.array[i];
+ DevAssert(tbrel->id == F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item);
+ DevAssert(tbrel->value.present == F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item);
+ f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id = tbrel->value.choice.DRBs_ToBeReleased_Item.dRBID;
+ newGtpuDeleteOneTunnel(0, f1ap_ue_context_modification_req->gNB_DU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id);
+ }
+ }
+
/* RRC Reconfiguration Complete indicator */
F1AP_UEContextModificationRequestIEs_t *ieReconf;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieReconf, container,
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
index 7ea6df92fc..aa1042491b 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
@@ -26,6 +26,7 @@
#define INDEX_MAX_TBS_TABLE (93)
#include "common/utils/nr/nr_common.h"
+#include "openair1/PHY/defs_nr_common.h"
#include
//Table 5.1.2.2-2
@@ -64,7 +65,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint32_t nr_tbs=0;
uint32_t Np_info, C, n;
- if (Ninfo <=3824) {
+ if (Ninfo <= NR_MAX_PDSCH_TBS) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<>10;
- if (Ninfo <=3824) {
+ if (Ninfo <= NR_MAX_PDSCH_TBS) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<
#include
@@ -4080,7 +4081,7 @@ void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
uint8_t get_BG(uint32_t A, uint16_t R) {
float code_rate = (float) R / 10240.0f;
- if ((A <=292) || ((A<=3824) && (code_rate <= 0.6667)) || code_rate <= 0.25)
+ if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (code_rate <= 0.6667)) || code_rate <= 0.25)
return 2;
else
return 1;
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
index 54d91e9971..9328d75b37 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -71,6 +71,7 @@ void init_RA(module_id_t mod_id,
ra->first_Msg3 = 1;
ra->starting_preamble_nb = 0;
ra->RA_backoff_cnt = 0;
+ ra->RA_window_cnt = -1;
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
@@ -653,7 +654,9 @@ uint8_t nr_ue_get_rach(module_id_t mod_id,
if (ra->ra_state > RA_UE_IDLE && ra->ra_state < RA_SUCCEEDED) {
if (ra->RA_active == 0) {
- /* RA not active - checking if RRC is ready to initiate the RA procedure */
+ NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon;
+ NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
+ init_RA(mod_id, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated);
LOG_D(NR_MAC, "In %s: RA not active. Checking for data to transmit from upper layers...\n", __FUNCTION__);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 6a8a4c213d..e2548fc7b1 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -2471,7 +2471,6 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr
if (is_nr_prach_slot) {
AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n");
- init_RA(module_idP, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated);
nr_get_RA_window(mac);
uint16_t format = prach_occasion_info_p->format;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index a3ab4eb74c..995e5b5d83 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -53,7 +53,7 @@
#define WORD 32
//#define SIZE_OF_POINTER sizeof (void *)
-const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) {
+int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) {
/* we assume that this function is mutex-protected from outside */
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index b1b60a9816..b9bb149310 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -2750,6 +2750,14 @@ static void nr_mac_apply_cellgroup(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *)UE->CellGroup);
+
+ /* remove the rlc_BearerToReleaseList, we don't need it anymore */
+ if (UE->CellGroup->rlc_BearerToReleaseList != NULL) {
+ struct NR_CellGroupConfig__rlc_BearerToReleaseList *l = UE->CellGroup->rlc_BearerToReleaseList;
+ asn_sequence_del(&l->list, l->list.count, /* free */1);
+ free(UE->CellGroup->rlc_BearerToReleaseList);
+ UE->CellGroup->rlc_BearerToReleaseList = NULL;
+ }
}
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 692e1b681c..174a50bead 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -39,7 +39,7 @@
//#define SRS_IND_DEBUG
-const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot)
+int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot)
{
/* we assume that this function is mutex-protected from outside */
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index a39945d8fb..b5c8ac4a97 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -393,8 +393,8 @@ void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
const NR_ServingCellConfigCommon_t *scc);
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl);
-const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
-const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot);
+int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
+int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot);
int get_cce_index(const gNB_MAC_INST *nrmac,
const int CC_id,
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
index 0e383e4eaf..e18c9ea5b7 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
@@ -138,6 +138,42 @@ static int handle_ue_context_drbs_setup(int rnti,
return drbs_len;
}
+static int handle_ue_context_drbs_release(int rnti,
+ int drbs_len,
+ const f1ap_drb_to_be_released_t *req_drbs,
+ NR_CellGroupConfig_t *cellGroupConfig)
+{
+ DevAssert(req_drbs != NULL && cellGroupConfig != NULL);
+
+ cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList));
+ AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n");
+
+ /* Note: the actual GTP tunnels are already removed in the F1AP message
+ * decoding */
+ for (int i = 0; i < drbs_len; i++) {
+ const f1ap_drb_to_be_released_t *drb = &req_drbs[i];
+
+ long lcid = drb->rb_id + 3; /* LCID is DRB + 3 */
+ int idx = 0;
+ while (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) {
+ const NR_RLC_BearerConfig_t *bc = cellGroupConfig->rlc_BearerToAddModList->list.array[idx];
+ if (bc->logicalChannelIdentity == lcid)
+ break;
+ ++idx;
+ }
+ if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) {
+ nr_rlc_release_entity(rnti, lcid);
+ asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1);
+ long *plcid = malloc(sizeof(*plcid));
+ AssertFatal(plcid != NULL, "out of memory\n");
+ *plcid = lcid;
+ int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToReleaseList->list, plcid);
+ DevAssert(ret == 0);
+ }
+ }
+ return drbs_len;
+}
+
static NR_UE_NR_Capability_t *get_ue_nr_cap(int rnti, uint8_t *buf, uint32_t len)
{
if (buf == NULL || len == 0)
@@ -287,6 +323,11 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
NR_SCHED_LOCK(&mac->sched_lock);
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->gNB_DU_ue_id);
+ if (!UE) {
+ LOG_E(NR_MAC, "could not find UE with RNTI %04x\n", req->gNB_DU_ue_id);
+ NR_SCHED_UNLOCK(&mac->sched_lock);
+ return;
+ }
NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup);
@@ -306,6 +347,11 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
new_CellGroup);
}
+ if (req->drbs_to_be_released_length > 0) {
+ resp.drbs_to_be_released_length =
+ handle_ue_context_drbs_release(req->gNB_DU_ue_id, req->drbs_to_be_released_length, req->drbs_to_be_released, new_CellGroup);
+ }
+
if (req->rrc_container != NULL)
nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length);
@@ -323,7 +369,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc);
}
- if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0 || ue_cap != NULL) {
+ if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0 || req->drbs_to_be_released_length > 0) {
resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t));
AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n");
resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1, 1024);
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 14c75deb26..5aa4f10a8c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -166,21 +166,15 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
UE->rnti,
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
- for (int lc_id = 0; lc_id < 63; lc_id++) {
- if (stats->dl.lc_bytes[lc_id] > 0)
- output += snprintf(output,
- end - output,
- "UE %04x: LCID %d: %"PRIu64" bytes TX\n",
- UE->rnti,
- lc_id,
- stats->dl.lc_bytes[lc_id]);
- if (stats->ul.lc_bytes[lc_id] > 0)
- output += snprintf(output,
- end - output,
- "UE %04x: LCID %d: %"PRIu64" bytes RX\n",
- UE->rnti,
- lc_id,
- stats->ul.lc_bytes[lc_id]);
+ for (int i = 0; i < sched_ctrl->dl_lc_num; i++) {
+ int lc_id = sched_ctrl->dl_lc_ids[i];
+ output += snprintf(output,
+ end - output,
+ "UE %04x: LCID %d: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
+ UE->rnti,
+ lc_id,
+ stats->dl.lc_bytes[lc_id],
+ stats->ul.lc_bytes[lc_id]);
}
}
NR_SCHED_UNLOCK(&gNB->UE_info.mutex);
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index f19ae36819..d5766a7814 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -1081,7 +1081,7 @@ void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering)
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
-void nr_release_srb(ue_id_t ue_id, int srb_id)
+void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
@@ -1094,7 +1094,7 @@ void nr_release_srb(ue_id_t ue_id, int srb_id)
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
-void nr_release_drb(ue_id_t ue_id, int drb_id)
+void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
@@ -1274,7 +1274,7 @@ nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager() {
}
/* returns false in case of error, true if everything ok */
-const bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_statistics_t *out)
+bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_statistics_t *out)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h
index e6e7ca9273..36568b58ba 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h
@@ -68,8 +68,8 @@ void nr_pdcp_reestablishment(ue_id_t ue_id);
void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering);
void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering);
-void nr_release_srb(ue_id_t ue_id, int srb_id);
-void nr_release_drb(ue_id_t ue_id, int drb_id);
+void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id);
+void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id);
void add_srb(int is_gnb,
ue_id_t rntiMaybeUEid,
@@ -123,6 +123,6 @@ void nr_pdcp_tick(int frame, int subframe);
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager();
-const bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_statistics_t *out);
+bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_statistics_t *out);
#endif /* NR_PDCP_OAI_API_H */
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
index c2d41cedb4..91985393cb 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
@@ -1638,7 +1638,10 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
entity->common.bstatus.tx_size -= pdu_size;
/* assign SN to SDU */
- sdu->sdu->sn = entity->tx_next;
+ if (sdu->sdu->sn == -1) {
+ sdu->sdu->sn = entity->tx_next;
+ entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus;
+ }
/* segment if necessary */
if (pdu_size > size) {
@@ -1656,10 +1659,6 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
+ next_sdu->size;
}
- /* update tx_next if the SDU segment is the last */
- if (sdu->is_last)
- entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus;
-
/* put SDU/SDU segment in the wait list */
/* speedup: check end of wait list, probably the new sdu comes after */
if (entity->wait_end == NULL
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 04c1186f6e..2aec005e6d 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -100,7 +100,7 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i
}
}
-void nr_release_rlc_entity(int rnti, logical_chan_id_t channel_id)
+void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id)
{
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
@@ -1177,7 +1177,7 @@ void nr_rlc_activate_avg_time_to_tx(
}
/* returns false in case of error, true if everything ok */
-const bool nr_rlc_get_statistics(
+bool nr_rlc_get_statistics(
int rnti,
int srb_flag,
int rb_id,
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
index c40e5c923a..be12b236e8 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h
@@ -51,7 +51,7 @@ bool nr_rlc_update_rnti(int from_rnti, int to_rnti);
/* test function for CI to trigger reestablishments */
void nr_rlc_test_trigger_reestablishment(int rnti);
-void nr_release_rlc_entity(int rnti, logical_chan_id_t channel_id);
+void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id);
void nr_rlc_reconfigure_entity(int rnti, int lc_id, struct NR_RLC_Config *rlc_Config, struct NR_LogicalChannelConfig *lc_Config);
@@ -75,4 +75,4 @@ void nr_rlc_activate_srb0(int rnti, struct gNB_MAC_INST_s *mac, void *rawUE,
sdu_size_t sdu_len,
void *rawUE));
-const bool nr_rlc_get_statistics(int rnti, int srb_flag, int rb_id, nr_rlc_statistics_t *out);
+bool nr_rlc_get_statistics(int rnti, int srb_flag, int rb_id, nr_rlc_statistics_t *out);
diff --git a/openair2/LAYER2/nr_rlc/tests/test.c b/openair2/LAYER2/nr_rlc/tests/test.c
index 716a6aef11..2086dba3c6 100644
--- a/openair2/LAYER2/nr_rlc/tests/test.c
+++ b/openair2/LAYER2/nr_rlc/tests/test.c
@@ -426,8 +426,8 @@ int test_main(void)
}
}
- gnb->delete(gnb);
- ue->delete(ue);
+ gnb->delete_entity(gnb);
+ ue->delete_entity(ue);
free(sdu);
free(pdu);
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 4f042d4f05..2e3e00f12d 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1125,7 +1125,7 @@ int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t r
return((enc_rval.encoded+7)/8);
}
-NR_MeasConfig_t *get_defaultMeasConfig(int arfcn, int band, int scs)
+NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
{
NR_MeasConfig_t *mc = calloc(1, sizeof(*mc));
mc->measObjectToAddModList = calloc(1, sizeof(*mc->measObjectToAddModList));
@@ -1137,7 +1137,7 @@ NR_MeasConfig_t *get_defaultMeasConfig(int arfcn, int band, int scs)
mo1->measObjectId = 1;
mo1->measObject.present = NR_MeasObjectToAddMod__measObject_PR_measObjectNR;
NR_MeasObjectNR_t *monr1 = calloc(1, sizeof(*monr1));
- asn1cCallocOne(monr1->ssbFrequency, arfcn);
+ asn1cCallocOne(monr1->ssbFrequency, ssb_arfcn);
asn1cCallocOne(monr1->ssbSubcarrierSpacing, scs);
monr1->referenceSignalConfig.ssb_ConfigMobility = calloc(1, sizeof(*monr1->referenceSignalConfig.ssb_ConfigMobility));
monr1->referenceSignalConfig.ssb_ConfigMobility->deriveSSB_IndexFromCell = true;
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index 5dcff1501a..5bd932ffd4 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -150,7 +150,7 @@ int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP,
int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier);
-NR_MeasConfig_t *get_defaultMeasConfig(int absFreqSSB, int band, int scs);
+NR_MeasConfig_t *get_defaultMeasConfig(uint32_t absFreqSSB, int band, int scs);
void free_defaultMeasConfig(NR_MeasConfig_t *mc);
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c
index 88c5ad125e..6ead51e3da 100644
--- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c
+++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c
@@ -94,6 +94,13 @@ static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req
AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n");
memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup));
}
+ if (req->drbs_to_be_released_length > 0) {
+ int n = req->drbs_to_be_released_length;
+ f1ap_msg->drbs_to_be_released_length = n;
+ f1ap_msg->drbs_to_be_released = calloc(n, sizeof(*f1ap_msg->drbs_to_be_released));
+ AssertFatal(f1ap_msg->drbs_to_be_released != NULL, "out of memory\n");
+ memcpy(f1ap_msg->drbs_to_be_released, req->drbs_to_be_released, n * sizeof(*f1ap_msg->drbs_to_be_released));
+ }
if (req->rrc_container_length > 0) {
f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container));
AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 215fc9851d..c37979598a 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -238,6 +238,7 @@ typedef enum {
typedef struct gNB_RRC_UE_s {
drb_t established_drbs[MAX_DRBS_PER_UE];
uint8_t DRB_active[MAX_DRBS_PER_UE];
+ NR_DRB_ToReleaseList_t *DRB_ReleaseList;
NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity
NR_MeasConfig_t *measConfig;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 9160d7213e..e5dcc79dfd 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -46,6 +46,7 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
+#include "openair2/E1AP/e1ap_asnc.h"
#include "NR_BCCH-BCH-Message.h"
#include "NR_UL-DCCH-Message.h"
@@ -558,8 +559,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info;
int scs = get_ssb_scs(cell_info);
int band = get_dl_band(cell_info);
- int arfcn = get_dl_arfcn(cell_info);
- NR_MeasConfig_t *measconfig = get_defaultMeasConfig(arfcn, band, scs);
+ uint32_t ssb_arfcn = get_ssb_arfcn(cell_info, du->mib, du->sib1);
+ NR_MeasConfig_t *measconfig = get_defaultMeasConfig(ssb_arfcn, band, scs);
uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_RRCReconfiguration(ue_p,
@@ -672,7 +673,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
xid,
SRBs,
DRBs,
- NULL,
+ ue_p->DRB_ReleaseList,
NULL,
NULL,
dedicatedNAS_MessageList,
@@ -680,6 +681,9 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n");
freeSRBlist(SRBs);
freeDRBlist(DRBs);
+ ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToReleaseList, ue_p->DRB_ReleaseList);
+ ue_p->DRB_ReleaseList = NULL;
+
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
@@ -2855,6 +2859,147 @@ rrc_gNB_generate_RRCRelease(
/* UE will be freed after UE context release complete */
}
+void rrc_gNB_trigger_new_bearer(int rnti)
+{
+ /* get RRC and UE */
+ gNB_RRC_INST *rrc = RC.nrrrc[0];
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, rnti);
+ if (ue_context_p == NULL) {
+ LOG_E(RRC, "unknown UE RNTI %04x\n", rnti);
+ return;
+ }
+ gNB_RRC_UE_t *ue = &ue_context_p->ue_context;
+
+ /* get the existing PDU sessoin */
+ if (ue->nb_of_pdusessions < 1) {
+ LOG_E(RRC, "no PDU session set up yet, cannot create additional bearer\n");
+ return;
+ }
+
+ if (ue->established_drbs[0].status != DRB_INACTIVE
+ && ue->established_drbs[1].status != DRB_INACTIVE) {
+ LOG_E(RRC, "already have two established bearers, aborting\n");
+ return;
+ }
+
+ e1ap_bearer_setup_req_t bearer_req = {0};
+ bearer_req.gNB_cu_cp_ue_id = ue->rrc_ue_id;
+ bearer_req.cipheringAlgorithm = ue->ciphering_algorithm;
+ memcpy(bearer_req.encryptionKey, ue->kgnb, sizeof(ue->kgnb));
+ bearer_req.integrityProtectionAlgorithm = ue->integrity_algorithm;
+ memcpy(bearer_req.integrityProtectionKey, ue->kgnb, sizeof(ue->kgnb));
+ bearer_req.ueDlAggMaxBitRate = 10000; /* probably does not matter */
+
+ pdu_session_to_setup_t *pdu = &bearer_req.pduSession[0];
+ //bearer_req.numPDUSessions++;
+ bearer_req.numPDUSessions = 1;
+ //pdu->sessionId = session->pdusession_id;
+ //pdu->sst = msg->allowed_nssai[i].sST;
+ //pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed;
+
+ //pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
+ //pdu->teId = session->gtp_teid;
+ pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
+ DRB_nGRAN_to_setup_t *drb = &pdu->DRBnGRanList[0];
+ int drb_id = 2;
+ drb->id = drb_id;
+
+ drb->defaultDRB = E1AP_DefaultDRB_false;
+ drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap);
+ drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap);
+
+ drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18;
+ drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18;
+
+ drb->discardTimer = E1AP_DiscardTimer_infinity;
+ drb->reorderingTimer = E1AP_T_Reordering_ms0;
+
+ drb->rLC_Mode = E1AP_RLC_Mode_rlc_am;
+
+ drb->numCellGroups = 1; // assume one cell group associated with a DRB
+
+ for (int k=0; k < drb->numCellGroups; k++) {
+ cell_group_t *cellGroup = drb->cellGroupList + k;
+ cellGroup->id = 0; // MCG
+ }
+
+ int xid = rrc_gNB_get_next_transaction_identifier(0);
+ /* generate a new bearer, it will be put into internal RRC state and picked
+ * up later */
+ generateDRB(ue,
+ drb_id,
+ &ue->pduSession[0],
+ rrc->configuration.enable_sdap,
+ rrc->security.do_drb_integrity,
+ rrc->security.do_drb_ciphering);
+
+ /* associate the new bearer to it */
+ ue->xids[xid] = RRC_PDUSESSION_MODIFY;
+ ue->pduSession[0].xid = xid; // hack: fake xid for ongoing PDU session
+ LOG_W(RRC, "trigger new bearer %ld for UE %04x xid %d\n", drb->id, ue->rnti, xid);
+ rrc->cucp_cuup.bearer_context_setup(&bearer_req, 0);
+}
+
+void rrc_gNB_trigger_release_bearer(int rnti)
+{
+ /* get RRC and UE */
+ gNB_RRC_INST *rrc = RC.nrrrc[0];
+ rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, rnti);
+ if (ue_context_p == NULL) {
+ LOG_E(RRC, "unknown UE RNTI %04x\n", rnti);
+ return;
+ }
+ gNB_RRC_UE_t *ue = &ue_context_p->ue_context;
+
+ if (ue->established_drbs[1].status == DRB_INACTIVE) {
+ LOG_E(RRC, "no second bearer, aborting\n");
+ return;
+ }
+
+ // don't use E1: bearer release is not implemented, call directly
+ // into PDCP/SDAP and then send corresponding message via F1
+
+ int drb_id = 2;
+ ue->established_drbs[1].status = DRB_INACTIVE;
+ ue->DRB_ReleaseList = calloc(1, sizeof(*ue->DRB_ReleaseList));
+ AssertFatal(ue->DRB_ReleaseList != NULL, "out of memory\n");
+ NR_DRB_Identity_t *asn1_drb = malloc(sizeof(*asn1_drb));
+ AssertFatal(asn1_drb != NULL, "out of memory\n");
+ int idx = 0;
+ NR_DRB_ToAddModList_t *drb_list = createDRBlist(ue, false);
+ while (idx < drb_list->list.count) {
+ const NR_DRB_ToAddMod_t *drbc = drb_list->list.array[idx];
+ if (drbc->drb_Identity == drb_id)
+ break;
+ ++idx;
+ }
+ if (idx < drb_list->list.count) {
+ nr_pdcp_release_drb(rnti, drb_id);
+ asn_sequence_del(&drb_list->list, idx, 1);
+ }
+ *asn1_drb = drb_id;
+ asn1cSeqAdd(&ue->DRB_ReleaseList->list, asn1_drb);
+
+ f1ap_drb_to_be_released_t drbs_to_be_released[1] = {{.rb_id = drb_id}};
+ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id);
+ f1ap_ue_context_modif_req_t ue_context_modif_req = {
+ .gNB_CU_ue_id = ue->rrc_ue_id,
+ .gNB_DU_ue_id = ue_data.secondary_ue,
+ .plmn.mcc = rrc->configuration.mcc[0],
+ .plmn.mnc = rrc->configuration.mnc[0],
+ .plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
+ .nr_cellid = rrc->nr_cellid,
+ .servCellId = 0, /* TODO: correct value? */
+ .srbs_to_be_setup_length = 0,
+ .srbs_to_be_setup = NULL,
+ .drbs_to_be_setup_length = 0,
+ .drbs_to_be_setup = NULL,
+ .drbs_to_be_released_length = 1,
+ .drbs_to_be_released = drbs_to_be_released,
+ };
+ rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req);
+}
+
int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){
const unsigned int Ttab[4] = {32,64,128,256};
uint8_t Tc;
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index 17bfc108ea..a6a0d9dd07 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -759,7 +759,7 @@ void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig,
for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i];
AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n");
- nr_release_rlc_entity(rnti, *lcid);
+ nr_rlc_release_entity(rnti, *lcid);
}
}
@@ -1460,7 +1460,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB
NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
if (radioBearerConfig->srb3_ToRelease)
- nr_release_srb(ctxt_pP->rntiMaybeUEid, 3);
+ nr_pdcp_release_srb(ctxt_pP->rntiMaybeUEid, 3);
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
@@ -1514,7 +1514,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB
for (int cnt = 0; cnt < radioBearerConfig->drb_ToReleaseList->list.count; cnt++) {
NR_DRB_Identity_t *DRB_id = radioBearerConfig->drb_ToReleaseList->list.array[cnt];
if (DRB_id)
- nr_release_drb(ctxt_pP->rntiMaybeUEid, *DRB_id);
+ nr_pdcp_release_drb(ctxt_pP->rntiMaybeUEid, *DRB_id);
}
}
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index b1920b6522..20e9c8c127 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -803,6 +803,32 @@ int gtpv1u_create_x2u_tunnel(
AssertFatal( false, "to be developped\n");
}
+int newGtpuDeleteOneTunnel(instance_t instance, ue_id_t ue_id, int rb_id)
+{
+ pthread_mutex_lock(&globGtp.gtp_lock);
+ getInstRetInt(compatInst(instance));
+ map::iterator ue_it = inst->ue2te_mapping.find(ue_id);
+ if (ue_it == inst->ue2te_mapping.end()) {
+ LOG_E(GTPU, "%s() no such UE %ld\n", __func__, ue_id);
+ pthread_mutex_unlock(&globGtp.gtp_lock);
+ return !GTPNOK;
+ }
+ map::iterator rb_it = ue_it->second.bearers.find(rb_id);
+ if (rb_it == ue_it->second.bearers.end()) {
+ LOG_E(GTPU, "%s() UE %ld has no bearer %d, available\n", __func__, ue_id, rb_id);
+ pthread_mutex_unlock(&globGtp.gtp_lock);
+ return !GTPNOK;
+ }
+ int teid = rb_it->second.teid_incoming;
+ globGtp.te2ue_mapping.erase(teid);
+ ue_it->second.bearers.erase(rb_id);
+ pthread_mutex_unlock(&globGtp.gtp_lock);
+ LOG_I(GTPU, "Deleted tunnel TEID %d (RB %d) for ue id %ld, remaining bearers:\n", teid, rb_id, ue_id);
+ for (auto b: ue_it->second.bearers)
+ LOG_I(GTPU, "bearer %ld\n", b.first);
+ return !GTPNOK;
+}
+
int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id) {
LOG_D(GTPU, "[%ld] Start delete tunnels for ue id %lu\n",
instance, ue_id);
diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h
index d57769c509..7ac025f14a 100644
--- a/openair3/ocp-gtpu/gtp_itf.h
+++ b/openair3/ocp-gtpu/gtp_itf.h
@@ -98,6 +98,7 @@ extern "C" {
in_addr_t newOutgoingAddr,
teid_t newOutgoingTeid);
+ int newGtpuDeleteOneTunnel(instance_t instance, ue_id_t ue_id, int rb_id);
int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id);
int newGtpuDeleteTunnels(instance_t instance, ue_id_t ue_id, int nbTunnels, pdusessionid_t *pdusession_id);
instance_t gtpv1Init(openAddr_t context);