Merge branch 'integration_2026_w08' into 'develop'

Integration: `2026.w08`

* !3934 Fix Ubuntu build: reinstate -Werror
* !3803 remove cblas and atlas dependancy
* !3918 Add a simple GTP unit test
* !3924 T: macpdu2wireshark: gentle exit (and some other minor work in the T tracer)
* !3925 Fix race condition on double RA during RRC reestablishment
* !3930 bugfix: add PCell to serving_cells in fallback path and refactor update logic
* !3936 [FHI72] Remove support for xran E release
* !3893 NR Paging on CU

See merge request oai/openairinterface5g!3939
This commit is contained in:
Robert Schmidt
2026-02-20 06:46:39 +00:00
131 changed files with 4059 additions and 5553 deletions
+6 -22
View File
@@ -434,7 +434,9 @@ add_library(ngap
${NGAP_DIR}/ngap_gNB_handlers.c
${NGAP_DIR}/ngap_gNB_itti_messaging.c
${NGAP_DIR}/ngap_gNB_management_procedures.c
${NGAP_DIR}/ngap_gNB_paging.c
${NGAP_DIR}/ngap_gNB_nas_procedures.c
${NGAP_DIR}/ngap_gNB_pdu_session_management.c
${NGAP_DIR}/ngap_gNB_nnsf.c
${NGAP_DIR}/ngap_gNB_overload.c
${NGAP_DIR}/ngap_gNB_trace.c
@@ -442,6 +444,9 @@ add_library(ngap
)
target_link_libraries(ngap PUBLIC asn1_ngap)
target_link_libraries(ngap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
if(ENABLE_TESTS)
target_compile_definitions(ngap PRIVATE ENABLE_TESTS)
endif()
#M2AP
##############
@@ -648,7 +653,6 @@ include_directories("${OPENAIR3_DIR}/S1AP")
include_directories("${OPENAIR2_DIR}/X2AP")
include_directories("${OPENAIR2_DIR}/M2AP")
include_directories("${OPENAIR2_DIR}/F1AP")
include_directories("${OPENAIR3_DIR}/ocp-gtpu")
include_directories("${OPENAIR3_DIR}/M3AP")
include_directories("${OPENAIR3_DIR}/MME_APP")
include_directories("${OPENAIR_DIR}/radio/COMMON")
@@ -926,7 +930,6 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/uci_tools_ue.c
@@ -1072,16 +1075,8 @@ add_dependencies(PHY_COMMON dfts)
add_library(PHY ${PHY_SRC})
target_link_libraries(PHY PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
pkg_check_modules(blas REQUIRED blas)
pkg_check_modules(lapacke REQUIRED lapacke)
add_library(PHY_UE ${PHY_SRC_UE})
target_link_libraries(PHY_UE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
# RHEL needs also cblas, but Ubuntu does not have it. So `cblas_LIBRARIES` and
# `cblas_INCLUDE_DIRS` will be empty for Ubuntu, a no-op
pkg_check_modules(cblas cblas)
target_link_libraries(PHY_UE PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES})
target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${cblas_INCLUDE_DIRS} ${lapacke_INCLUDE_DIRS})
add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
target_link_libraries(PHY_NR_COMMON PUBLIC UTIL)
@@ -1158,7 +1153,7 @@ set(L2_SRC
${RRC_DIR}/rrc_eNB_S1AP.c
${RRC_DIR}/rrc_eNB_M2AP.c
${RRC_DIR}/rrc_eNB_UE_context.c
${NR_RRC_DIR}/rrc_gNB_UE_context.c
${RRC_DIR}/rrc_eNB_GTPV1U.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface.c
${RRC_DIR}/L2_interface_common.c
@@ -1405,15 +1400,6 @@ include_directories("${OPENAIR1_DIR}/SCHED_NR_UE")
# CN libs
##########################
add_library (GTPV1U
${RRC_DIR}/rrc_eNB_GTPV1U.c
${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp
${OPENAIR3_DIR}/ocp-gtpu/gtpu_extensions.c
)
target_link_libraries(GTPV1U PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(GTPV1U PRIVATE SIMU ds)
include_directories(${OPENAIR3_DIR}/ocp-gtp)
set (MME_APP_SRC
${OPENAIR3_DIR}/MME_APP/mme_app.c
${OPENAIR3_DIR}/MME_APP/mme_config.c
@@ -1773,7 +1759,6 @@ target_link_libraries(lte-softmodem PRIVATE
target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-softmodem PRIVATE ${T_LIB})
target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(lte-softmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES})
if(E2_AGENT)
target_link_libraries(lte-softmodem PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
@@ -1824,7 +1809,6 @@ target_link_libraries(lte-uesoftmodem PRIVATE
target_link_libraries(lte-uesoftmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-uesoftmodem PRIVATE ${T_LIB})
target_link_libraries(lte-uesoftmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(lte-uesoftmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES})
# force the generation of ASN.1 so that we don't need to wait during the build
target_link_libraries(lte-uesoftmodem PRIVATE
-7
View File
@@ -496,9 +496,6 @@ check_install_oai_software() {
ninja-build \
pkg-config \
git \
libblas-dev \
liblapack-dev \
liblapacke-dev \
libreadline-dev \
libconfig-dev \
libsctp-dev \
@@ -536,10 +533,6 @@ check_install_oai_software() {
openssl-devel \
patch \
readline-devel \
lapack \
lapack-devel \
blas \
blas-devel \
vim-common \
zlib-devel \
yaml-cpp-devel
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -21,7 +21,7 @@ incgen/T_IDs.h: $(GENIDS) T_messages.txt
./$(GENIDS) T_messages.txt incgen/T_IDs.h
check_vcd: incgen/T_IDs.h incgen/T_messages.txt.h
gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
gcc -Wall -I. -I.. -I../../.. -I../itti -I../../../openair2/COMMON -Itracer -Iincgen -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
./_check_vcd T_messages.txt ../LOG/vcd_signal_dumper.h || (rm -rf ./_check_vcd ./incgen && false)
rm -f ./_check_vcd
+4 -3
View File
@@ -18,6 +18,7 @@ void usage(void)
" (you can use several -f options)\n"
" -after <raw time> <nsec> 'event' time has to be greater than this\n"
" -count <n> dump 'n' matching events (less if EOF reached)\n"
" (default: no limit)\n"
);
exit(1);
}
@@ -53,7 +54,7 @@ int main(int n, char **v)
int filter_count = 0;
int buffer_arg;
int found;
int count = 1;
int count = -1;
int check_time = 0;
time_t sec = 0; /* initialization not necessary but gcc is not happy */
long nsec = 0; /* initialization not necessary but gcc is not happy */
@@ -132,12 +133,12 @@ int main(int n, char **v)
if (fwrite(e.e[buffer_arg].b, e.e[buffer_arg].bsize, 1, out) != 1)
{ perror(output_file); exit(1); }
found++;
if (found == count)
if (count != -1 && found == count)
break;
}
if (found == 0) printf("ERROR: event not found\n");
if (found != count)
if (count != -1 && found != count)
printf("WARNING: dumped %d events (wanted %d)\n", found, count);
fclose(out);
+10 -10
View File
@@ -135,7 +135,7 @@ int main(int n, char **v)
int input_is_float = 0;
int no_fft = 0;
int delay = 0;
int skip = 0;
uint64_t skip = 0;
int symbols_per_subframe;
long sampling_rate = 61440000;
int mu = 1;
@@ -152,7 +152,7 @@ int main(int n, char **v)
if (!strcmp(v[i], "-srate")) { if (i>n-2) usage(); sampling_rate = atol(v[++i]); continue; }
if (!strcmp(v[i], "-prb")) { if (i>n-2) usage(); prb = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-mu")) { if (i>n-2) usage(); mu = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-skip")) { if (i>n-2) usage(); skip = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-skip")) { if (i>n-2) usage(); skip = atoll(v[++i]); continue; }
usage();
}
@@ -222,14 +222,14 @@ int main(int n, char **v)
int back_color = 0;
int hpixel = 0;
if (skip) {
if (input_is_float) {
float intime[skip * 2];
if (fread(intime, skip * 8, 1, stdin) != 1) abort();
} else {
short intime[skip * 2];
if (fread(intime, skip * 4, 1, stdin) != 1) abort();
}
/* skip data */
int sample_size = input_is_float ? 8 : 4;
uint64_t to_skip = skip;
while (to_skip) {
char intime[4096 * sample_size];
int count = to_skip > 4096 ? 4096 : to_skip;
if (fread(intime, count * sample_size, 1, stdin) != 1) abort();
to_skip -= count;
}
while (1) {
+27 -2
View File
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -387,6 +389,7 @@ void sr(void *_d, event e)
#define MAC_NR_HARQID 0x06
#define MAC_NR_FRAME_SLOT_TAG 0x07
#define NR_FDD_RADIO 1
#define NR_TDD_RADIO 2
#define NR_DIRECTION_UPLINK 0
@@ -948,6 +951,18 @@ void usage(void)
exit(1);
}
volatile int run = 1;
static int sock = -1;
void force_stop(int x)
{
printf("\ngently quit...\n");
close(sock);
sock = -1;
run = 0;
}
int main(int n, char **v)
{
char *database_filename = NULL;
@@ -968,6 +983,9 @@ int main(int n, char **v)
int live = 0;
memset(&d, 0, sizeof(ev_data));
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
for (i = 0; i < 65536; i++) {
d.lte_rnti_to_ueid[i] = -1;
d.nr_rnti_to_ueid[i] = -1;
@@ -1014,8 +1032,10 @@ int main(int n, char **v)
perror(input_filename);
return 1;
}
} else
} else {
in = connect_to(live_ip, live_port);
sock = in;
}
database = parse_database(database_filename);
load_config_file(database_filename);
@@ -1121,10 +1141,15 @@ int main(int n, char **v)
new_thread(receiver, &d);
}
/* exit on ctrl+c and ctrl+z */
if (signal(SIGQUIT, force_stop) == SIG_ERR) abort();
if (signal(SIGINT, force_stop) == SIG_ERR) abort();
if (signal(SIGTSTP, force_stop) == SIG_ERR) abort();
OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL};
/* read messages */
while (1) {
while (run) {
event e;
e = get_event(in, &ebuf, database);
+81
View File
@@ -0,0 +1,81 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef EQ_CHECK_H_
#define EQ_CHECK_H_
#include <stdio.h>
#include <string.h>
/*
* Layers may override PRINT_ERROR() before including this header to preserve
* custom logging style (for example by mapping it to a local PRINT_ERROR()).
*/
#ifndef PRINT_ERROR
#ifdef ENABLE_TESTS
#define PRINT_ERROR(fmt, ...) fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define PRINT_ERROR(...) \
do { \
} while (0)
#endif
#endif
#ifndef EQ_CHECK_FAIL
#define EQ_CHECK_FAIL() return false
#endif
#define EQ_CHECK_GENERIC(condition, fmt, ...) \
do { \
if (!(condition)) { \
PRINT_ERROR("Equality condition '%s' failed: " fmt " != " fmt "\n", #condition, ##__VA_ARGS__); \
EQ_CHECK_FAIL(); \
} \
} while (0)
#define _EQ_CHECK_LONG(A, B) EQ_CHECK_GENERIC((A) == (B), "%ld", (A), (B))
#define _EQ_CHECK_INT(A, B) EQ_CHECK_GENERIC((A) == (B), "%d", (A), (B))
#define _EQ_CHECK_UINT32(A, B) EQ_CHECK_GENERIC((A) == (B), "%u", (A), (B))
#define _EQ_CHECK_UINT64(A, B) EQ_CHECK_GENERIC((A) == (B), "%" PRIu64, (uint64_t)(A), (uint64_t)(B))
#define _EQ_CHECK_STR(A, B) EQ_CHECK_GENERIC(strcmp((A), (B)) == 0, "'%s'", (A), (B))
#define _EQ_CHECK_OPTIONAL_IE(A, B, FIELD, EQ_MACRO) \
do { \
EQ_CHECK_GENERIC((((A)->FIELD) != NULL) == (((B)->FIELD) != NULL), "%d", ((A)->FIELD) != NULL, ((B)->FIELD) != NULL); \
if ((A)->FIELD && (B)->FIELD) \
EQ_MACRO(*(A)->FIELD, *(B)->FIELD); \
} while (0)
#define _EQ_CHECK_OPTIONAL_PTR(A, B, FIELD) \
do { \
if ((((A)->FIELD) != NULL) != (((B)->FIELD) != NULL)) { \
PRINT_ERROR("%s:%d: optional IE '%s' not allocated: %p, %p\n", \
__FILE__, \
__LINE__, \
#FIELD, \
(void *)(A)->FIELD, \
(void *)(B)->FIELD); \
EQ_CHECK_FAIL(); \
} \
} while (0)
#endif /* EQ_CHECK_H_ */
+56 -1
View File
@@ -1463,6 +1463,18 @@ uint64_t nr_construct_5g_s_tmsi(uint16_t amf_set_id, uint8_t amf_pointer, uint32
return ((uint64_t)amf_set_id << 38) | ((uint64_t)amf_pointer << 32) | m_tmsi;
}
/** @brief Extract 5G-S-TMSI-Part1 from full 5G-S-TMSI
* @param fiveg_s_tmsi Full 5G-S-TMSI (48 bits)
* @return 5G-S-TMSI-Part1 (rightmost 39 bits)
* @note 5G-S-TMSI-Part1 is the rightmost 39 bits of the full 5G-S-TMSI:
* - Bits 32-37: AMF Pointer (6 bits)
* - Bits 0-31: 5G-TMSI (32 bits)
* @ref 3GPP TS 23.003 */
uint64_t nr_extract_5g_s_tmsi_part1(const uint64_t fiveg_s_tmsi)
{
return fiveg_s_tmsi & ((1ULL << 39) - 1);
}
/** @brief Construct 5G-S-TMSI-Part1 from 5G-S-TMSI components
* @param amf_set_id AMF Set ID (10 bits)
* @param amf_pointer AMF Pointer (6 bits)
@@ -1476,5 +1488,48 @@ uint64_t nr_construct_5g_s_tmsi_part1(uint16_t amf_set_id, uint8_t amf_pointer,
{
// Construct full 5G-S-TMSI and extract Part1: rightmost 39 bits
uint64_t full_s_tmsi = nr_construct_5g_s_tmsi(amf_set_id, amf_pointer, m_tmsi);
return full_s_tmsi & ((1ULL << 39) - 1);
return nr_extract_5g_s_tmsi_part1(full_s_tmsi);
}
/** @brief Extract 5G-S-TMSI-Part2 from full 5G-S-TMSI
* @param fiveg_s_tmsi Full 5G-S-TMSI (48 bits)
* @return 5G-S-TMSI-Part2 (leftmost 9 bits)
* @note 5G-S-TMSI-Part2 is the leftmost 9 bits of the full 5G-S-TMSI:
* - Bits 39-47: AMF Set ID (9 bits)
* @ref 3GPP TS 23.003 */
uint16_t nr_extract_5g_s_tmsi_part2(const uint64_t fiveg_s_tmsi)
{
return (fiveg_s_tmsi >> 39) & ((1ULL << 9) - 1);
}
/** @brief Build full 5G-S-TMSI from Part1 and Part2
* @param part1 5G-S-TMSI-Part1 (rightmost 39 bits)
* @param part2 5G-S-TMSI-Part2 (leftmost 9 bits)
* @return Full 5G-S-TMSI (48 bits)
* @note Combines Part2 (leftmost 9 bits) and Part1 (rightmost 39 bits)
* @ref 3GPP TS 23.003 */
uint64_t nr_build_full_5g_s_tmsi(const uint64_t part1, const uint16_t part2)
{
return ((uint64_t)part2 << 39) | part1;
}
/** @brief Deconstruct full 5G-S-TMSI into its components
* @param fiveg_s_tmsi Full 5G-S-TMSI (48 bits)
* @param[out] amf_set_id Pointer to store AMF Set ID (10 bits)
* @param[out] amf_pointer Pointer to store AMF Pointer (6 bits)
* @param[out] m_tmsi Pointer to store 5G-TMSI (32 bits)
* @note The 5G-S-TMSI is deconstructed from a 48-bit value:
* - Bits 38-47: AMF Set ID (10 bits)
* - Bits 32-37: AMF Pointer (6 bits)
* - Bits 0-31: 5G-TMSI (32 bits)
* @ref 3GPP TS 23.003 */
void nr_deconstruct_5g_s_tmsi(const uint64_t fiveg_s_tmsi, uint16_t *amf_set_id, uint8_t *amf_pointer, uint32_t *m_tmsi)
{
DevAssert(amf_set_id != NULL);
DevAssert(amf_pointer != NULL);
DevAssert(m_tmsi != NULL);
*amf_set_id = fiveg_s_tmsi >> 38;
*amf_pointer = (fiveg_s_tmsi >> 32) & 0x3F;
*m_tmsi = fiveg_s_tmsi;
}
+12
View File
@@ -360,6 +360,18 @@ uint64_t nr_construct_5g_s_tmsi(uint16_t amf_set_id, uint8_t amf_pointer, uint32
/** @brief Construct 5G-S-TMSI-Part1 from 5G-S-TMSI components */
uint64_t nr_construct_5g_s_tmsi_part1(uint16_t amf_set_id, uint8_t amf_pointer, uint32_t m_tmsi);
/** @brief Extract 5G-S-TMSI-Part1 from full 5G-S-TMSI */
uint64_t nr_extract_5g_s_tmsi_part1(const uint64_t fiveg_s_tmsi);
/** @brief Extract 5G-S-TMSI-Part2 from full 5G-S-TMSI */
uint16_t nr_extract_5g_s_tmsi_part2(const uint64_t fiveg_s_tmsi);
/** @brief Build full 5G-S-TMSI from Part1 and Part2 */
uint64_t nr_build_full_5g_s_tmsi(const uint64_t part1, const uint16_t part2);
/** @brief Deconstruct full 5G-S-TMSI into its components */
void nr_deconstruct_5g_s_tmsi(const uint64_t fiveg_s_tmsi, uint16_t *amf_set_id, uint8_t *amf_pointer, uint32_t *m_tmsi);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
#define BOUNDED_EVAL(a, b, c) (min(c, max(a, b)))
+9
View File
@@ -109,6 +109,15 @@ int hex_char_to_hex_value (char c);
// Converts an hexadecimal ASCII coded string into its value.**
int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size);
/* Map task id to printable name. */
typedef struct {
int id;
char text[256];
} text_info_t;
#define TO_TEXT(LabEl, nUmID) {nUmID, #LabEl},
#define TO_ENUM(LabEl, nUmID) LabEl = nUmID,
char *itoa(int i);
#define STRINGIFY(S) #S
+2 -12
View File
@@ -69,11 +69,10 @@ Tested libxran releases:
| Vendor |
|-----------------------------------------|
| `oran_e_maintenance_release_v1.0` |
| `oran_f_release_v1.0` |
**Note**: The libxran driver of OAI identifies the above E release version as "5.1.0" (E is fifth letter, then 1.0), and the above F release as "6.1.0".
**Note**: The libxran driver of OAI identifies the above F release version as "6.1.0" (F is the sixth letter, then 1.0).
### Configure your server
@@ -375,14 +374,6 @@ cd ~/openairinterface5g/
Download ORAN FHI DU library, checkout the correct version, and apply the correct patch (available in `oai_folder/cmake_targets/tools/oran_fhi_integration_patches`).
#### E release
```bash
git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git ~/phy
cd ~/phy
git checkout oran_e_maintenance_release_v1.0
git apply ~/openairinterface5g/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch
```
#### F release
```bash
git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git ~/phy
@@ -404,7 +395,6 @@ This feature is intended to enable experiments and future improvements on Arm sy
```bash
cd ~/phy/fhi_lib/lib
make clean
RTE_SDK=~/dpdk-stable-20.11.9/ XRAN_DIR=~/phy/fhi_lib make XRAN_LIB_SO=1 # E release
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=~/dpdk-stable-20.11.9/ XRAN_DIR=~/phy/fhi_lib make XRAN_LIB_SO=1 # F release
...
[AR] build/libxran.so
@@ -967,7 +957,7 @@ Sample configuration files for OAI gNB, specific to the manufacturer of the radi
4. Benetel 550 RU:
[`gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf)
[`gnb.sa.band78.273prb.fhi72.4x2-benetel550.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x2-benetel550.conf)
[`gnb.sa.band78.273prb.fhi72.2x2-benetel550-16b.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.2x2-benetel550-16b.conf) - only with E release; with F, UL U-plane fragmentation is not correct
[`gnb.sa.band78.273prb.fhi72.2x2-benetel550-16b.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.2x2-benetel550-16b.conf) - tested successfully with E release; with F, UL U-plane fragmentation is not correct
5. Metanoia RU:
[`gnb.sa.band78.273prb.fhi72.4x4-metanoia.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-metanoia.conf)
-3
View File
@@ -42,10 +42,7 @@ sudo apt install -y gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu
sudo apt-get install -y \
libblas-dev:arm64 \
libc6-dev-i386 \
liblapack-dev:arm64 \
liblapacke-dev:arm64 \
libreadline-dev:arm64 \
libgnutls28-dev:arm64 \
libconfig-dev:arm64 \
@@ -57,9 +57,6 @@ RUN apt-get update && \
tzdata \
xxd \
# ARM64 packages
libblas-dev:arm64 \
liblapack-dev:arm64 \
liblapacke-dev:arm64 \
libreadline-dev:arm64 \
libgnutls28-dev:arm64 \
libconfig-dev:arm64 \
+1 -3
View File
@@ -51,7 +51,6 @@ RUN apt-get update && \
libboost-system1.83.0 \
libboost-program-options1.83.0 \
tzdata \
libblas3 \
libconfig9 \
openssl \
net-tools \
@@ -74,8 +73,7 @@ RUN apt-get update && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libasan8 \
libubsan1 \
liblapacke; fi' && \
libubsan1 ; fi' && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
-1
View File
@@ -70,7 +70,6 @@ RUN apt-get update && \
procps \
libsctp1 \
tzdata \
libblas3 \
libconfig9 \
openssl \
net-tools \
@@ -69,7 +69,6 @@ RUN apt-get update && \
procps \
libsctp1 \
tzdata \
libblas3 \
libconfig9 \
openssl \
net-tools \
-1
View File
@@ -48,7 +48,6 @@ RUN apt-get update && \
procps \
libsctp1 \
tzdata \
libblas3 \
libc6 \
libconfig9 \
gdb \
-4
View File
@@ -101,10 +101,6 @@ COPY --from=gnb-build /usr/local/lib64/flexric /usr/local/lib64/flexric
COPY --from=gnb-base \
/lib64/libconfig.so.11 \
/lib64/libforms.so.2 \
/lib64/libblas.so.3 \
/lib64/libcblas.so.3 \
/lib64/liblapack.so.3 \
/lib64/liblapacke.so.3 \
/lib64/libicudata.so.67 \
/lib64/libicui18n.so.67 \
/lib64/libicuuc.so.67 \
-4
View File
@@ -90,10 +90,6 @@ COPY --from=gnb-build /usr/local/lib64/flexric /usr/local/lib64/flexric
COPY --from=gnb-base \
/lib64/libconfig.so.11 \
/lib64/libforms.so.2 \
/lib64/libblas.so.3 \
/lib64/libcblas.so.3 \
/lib64/liblapack.so.3 \
/lib64/liblapacke.so.3 \
/lib64/libicudata.so.67 \
/lib64/libicui18n.so.67 \
/lib64/libicuuc.so.67 \
+1 -3
View File
@@ -44,7 +44,6 @@ RUN apt-get update && \
pkg-config \
libsctp1 \
tzdata \
libblas3 \
libconfig9 \
openssl \
net-tools \
@@ -63,8 +62,7 @@ RUN apt-get update && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libasan8 \
libubsan1 \
liblapacke; fi' && \
libubsan1 ; fi' && \
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/oai-gnb/bin
+1 -3
View File
@@ -51,7 +51,6 @@ RUN apt-get update && \
libboost-system1.83.0 \
libboost-program-options1.83.0 \
tzdata \
libblas3 \
libconfig9 \
openssl \
net-tools \
@@ -69,8 +68,7 @@ RUN apt-get update && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libasan8 \
libubsan1 \
liblapacke; fi' && \
libubsan1; fi' && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
-1
View File
@@ -49,7 +49,6 @@ RUN apt-get update && \
libboost-thread1.83.0 \
libboost-system1.83.0 \
libboost-program-options1.83.0 \
libblas3 \
libconfig9 \
net-tools \
gdb \
-4
View File
@@ -73,10 +73,6 @@ COPY --from=lte-ue-build \
COPY --from=lte-ue-base \
/lib64/libconfig.so.11 \
/lib64/libblas.so.3 \
/lib64/libcblas.so.3 \
/lib64/liblapack.so.3 \
/lib64/liblapacke.so.3 \
/lib64/libboost_chrono.so.1.75.0 \
/lib64/libboost_date_time.so.1.75.0 \
/lib64/libboost_filesystem.so.1.75.0 \
-4
View File
@@ -74,10 +74,6 @@ COPY --from=lte-ue-build \
COPY --from=lte-ue-base \
/lib64/libconfig.so.11 \
/lib64/libblas.so.3 \
/lib64/libcblas.so.3 \
/lib64/liblapack.so.3 \
/lib64/liblapacke.so.3 \
/lib64/libboost_chrono.so.1.75.0 \
/lib64/libboost_date_time.so.1.75.0 \
/lib64/libboost_filesystem.so.1.75.0 \
+1 -4
View File
@@ -51,8 +51,6 @@ RUN apt-get update && \
libboost-system1.83.0 \
libboost-program-options1.83.0 \
tzdata \
liblapacke \
libblas3 \
libconfig9 \
openssl \
net-tools \
@@ -75,8 +73,7 @@ RUN apt-get update && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libasan8 \
libubsan1 \
liblapacke; fi' && \
libubsan1 ; fi' && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
+1 -2
View File
@@ -47,8 +47,7 @@ RUN apt-get update && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libasan8 \
libubsan1 \
liblapacke; fi' && \
libubsan1; fi' && \
rm -rf /var/lib/apt/lists/*
## Copy E2 SM models
-1
View File
@@ -36,7 +36,6 @@ RUN apt-get update && \
pkg-config \
libsctp1 \
tzdata \
libblas3 \
libconfig9 \
openssl \
net-tools \
-2
View File
@@ -52,8 +52,6 @@ RUN apt-get update && \
libboost-system1.83.0 \
libboost-program-options1.83.0 \
tzdata \
liblapacke \
libblas3 \
libconfig9 \
openssl \
net-tools \
-4
View File
@@ -69,10 +69,6 @@ COPY --from=phy-sim-build /opt/oai-physim/bin/ /opt/oai-physim/bin/
COPY --from=phy-sim-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/lib64/liblapacke.so.3 \
/lib64/libblas.so.3 \
/lib64/libcblas.so.3 \
/lib64/liblapack.so.3 \
/usr/lib64/libasan.so.6 \
/usr/lib64/libubsan.so.1 \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
+3 -3
View File
@@ -44,12 +44,12 @@ $(OBJ) : %.o : %.c
$(CC) -c $(CFLAGS) -Wall -I$(TOP_DIR) -I$(TOP_DIR)/PHY/CODING -I$(OPENAIR0_DIR)/express-mimo/simulator/baseband/C/channel_decoder -o $@ $<
ltetest: $(OBJ) ltetest.c
$(CC) ltetest.c -O2 -I$(TOP_DIR) -I$(TOP_DIR)/PHY/CODING -I$(OPENAIR0_DIR)/express-mimo/simulator/baseband/C/channel_decoder -o ltetest $(CFLAGS) $(OBJ) -lm -DOPENAIR_LTE -lblas -lrt
$(CC) ltetest.c -O2 -I$(TOP_DIR) -I$(TOP_DIR)/PHY/CODING -I$(OPENAIR0_DIR)/express-mimo/simulator/baseband/C/channel_decoder -o ltetest $(CFLAGS) $(OBJ) -lm -DOPENAIR_LTE -lrt
pdcch_test: $(OBJ) pdcch_test.c
$(CC) pdcch_test.c -I$(TOP_DIR) -o pdcch_test $(CFLAGS) $(PHY_OBJS) -lm -lblas
$(CC) pdcch_test.c -I$(TOP_DIR) -o pdcch_test $(CFLAGS) $(PHY_OBJS) -lm
viterbi_test: $(OBJ) viterbi_test.c
$(CC) viterbi_test.c -I$(TOP_DIR) -o viterbi_test $(CFLAGS) $(PHY_OBJS) -lm -lblas
$(CC) viterbi_test.c -I$(TOP_DIR) -o viterbi_test $(CFLAGS) $(PHY_OBJS) -lm
clean:
rm $(OBJ)
@@ -549,10 +549,7 @@ void construct_HhH_elements(int *ch0conj_ch0, //00_00
}
}
void squared_matrix_element(int32_t *Hh_h_00,
int32_t *Hh_h_00_sq,
unsigned short nb_rb)
static void squared_matrix_element(int32_t *Hh_h_00, int32_t *Hh_h_00_sq, unsigned short nb_rb)
{
simde__m128i *Hh_h_00_128,*Hh_h_00_sq_128;
File diff suppressed because it is too large Load Diff
@@ -1,370 +0,0 @@
/* These functions compute linear preprocessing for
the UE using LAPACKE and CBLAS modules of
LAPACK libraries.
MMSE and MMSE whitening filters are available.
Functions are using RowMajor storage of the
matrices, like in conventional C. Traditional
Fortran functions of LAPACK employ ColumnMajor
data storage. */
#include<stdio.h>
#include<math.h>
#include<complex.h>
#include <stdlib.h>
#include <linux/version.h>
#include <cblas.h>
#include <string.h>
#include <linux/version.h>
#include <lapacke_utils.h>
#include <lapacke.h>
//#define DEBUG_PREPROC
#include "common/utils/utils.h"
void transpose (int N, float complex *A, float complex *Result)
{
// COnputes C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = N; // number of rows in op(A) and in C
int col_opB = N; //number of columns of op(B) and in C
int col_opA = N; //number of columns in op(A) and rows in op(B)
int col_B; //number of columns in B
float complex alpha = 1.0+I*0;
int lda = rows_opA;
float complex beta = 0.0+I*0;
int ldc = rows_opA;
int i;
float complex* B;
int ldb = col_opB;
if (transb == CblasNoTrans) {
B = calloc_or_fail(ldb * col_opB, sizeof(float complex));
col_B= col_opB;
}
else {
B = calloc_or_fail(ldb * col_opA, sizeof(float complex));
col_B = col_opA;
}
float complex* C = malloc_or_fail(ldc * col_opB * sizeof(float complex));
for (i=0; i<lda*col_B; i+=N+1)
B[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, B, ldb, &beta, C, ldc);
memcpy(Result, C, N*N*sizeof(float complex));
free(B);
free(C);
}
void conjugate_transpose (int N, float complex *A, float complex *Result)
{
// Computes C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasConjTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = N; // number of rows in op(A) and in C
int col_opB = N; //number of columns of op(B) and in C
int col_opA = N; //number of columns in op(A) and rows in op(B)
int col_B; //number of columns in B
float complex alpha = 1.0+I*0;
int lda = rows_opA;
float complex beta = 0.0+I*0;
int ldc = rows_opA;
int i;
float complex* B;
int ldb = col_opB;
if (transb == CblasNoTrans) {
B = calloc_or_fail(ldb * col_opB, sizeof(float complex));
col_B= col_opB;
}
else {
B = calloc_or_fail(ldb * col_opA, sizeof(float complex));
col_B = col_opA;
}
float complex* C = malloc_or_fail(ldc * col_opB * sizeof(float complex));
for (i=0; i<lda*col_B; i+=N+1)
B[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, B, ldb, &beta, C, ldc);
memcpy(Result, C, N*N*sizeof(float complex));
free(B);
free(C);
}
void H_hermH_plus_sigma2I (int N, int M, float complex *A, float sigma2, float complex *Result)
{
//C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasConjTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = N; // number of rows in op(A) and in C
int col_opB = N; //number of columns of op(B) and in C
int col_opA = N; //number of columns in op(A) and rows in op(B)
int col_C = N; //number of columns in B
float complex alpha = 1.0+I*0;
int lda = col_opA;
float complex beta = 1.0 + I*0;
int ldc = col_opA;
int i;
float complex* C = calloc_or_fail(ldc * col_opB, sizeof(float complex));
for (i=0; i<lda*col_C; i+=N+1)
C[i]=sigma2*(1.0+I*0);
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, A, lda, &beta, C, ldc);
memcpy(Result, C, N*M*sizeof(float complex));
free(C);
}
void HH_herm_plus_sigma2I (int M, int N, float complex *A, float sigma2, float complex *Result)
{
//C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasNoTrans;
CBLAS_TRANSPOSE transb = CblasConjTrans;
int k = N; //number of columns in op(A) and rows in op(B),k
float complex alpha = 1.0+I*0;
int lda = N;
int ldb = N;
int ldc = M;
int i;
float complex* C = calloc_or_fail(M * M, sizeof(float complex));
for (i=0; i<M*M; i+=M+1)
C[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, M, M, k, &alpha, A, lda, A, ldb, &sigma2, C, ldc);
memcpy(Result, C, M*M*sizeof(float complex));
free(C);
}
void eigen_vectors_values (int N, float complex *A, float complex *Vectors, float *Values_Matrix)
{
// This function computes ORTHONORMAL eigenvectors and eigenvalues of matrix A,
// where Values_Matrix is a diagonal matrix of eigenvalues.
// A=Vectors*Values_Matrix*Vectors'
char jobz = 'V';
char uplo = 'U';
int order_A = N;
int lda = N;
int i;
float* Values = malloc_or_fail(sizeof(float) * 1 * N);
LAPACKE_cheev(LAPACK_ROW_MAJOR, jobz, uplo, order_A, A, lda, Values);
memcpy(Vectors, A, N*N*sizeof(float complex));
for (i=0; i<lda; i+=1)
Values_Matrix[i*(lda+1)]=Values[i];
free(Values);
}
void lin_eq_solver (int N, float complex* A, float complex* B, float complex* Result)
{
int n = N;
int lda = N;
int ldb = N;
int nrhs = N;
char transa = 'N';
int* IPIV = malloc_or_fail(N * N * sizeof(int));
// Compute LU-factorization
LAPACKE_cgetrf(LAPACK_ROW_MAJOR, n, nrhs, A, lda, IPIV);
// Solve AX=B
LAPACKE_cgetrs(LAPACK_ROW_MAJOR, transa, n, nrhs, A, lda, IPIV, B, ldb);
// cgetrs( "N", N, 4, A, lda, IPIV, B, ldb, INFO )
memcpy(Result, B, N*N*sizeof(float complex));
free(IPIV);
}
void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){
CBLAS_TRANSPOSE transa = CblasNoTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = rows_M0; // number of rows in op(A) and in C
int col_opB = col_M1; //number of columns of op(B) and in C
int col_opA = col_M0; //number of columns in op(A) and rows in op(B)
float complex alpha =1.0;
int lda = col_M0;
float complex beta = 0.0;
int ldc = col_M1;
int ldb = col_M1;
#ifdef DEBUG_PREPROC
int i=0;
printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1);
for(i=0; i<rows_M0*col_M0; ++i)
printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i]));
for(i=0; i<rows_M1*col_M1; ++i)
printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i]));
#endif
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc);
#ifdef DEBUG_PREPROC
for(i=0; i<rows_opA*col_opB; ++i)
printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i]));
#endif
}
void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){
CBLAS_TRANSPOSE transa = CblasNoTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = rows_M0; // number of rows in op(A) and in C
int col_opB = col_M1; //number of columns of op(B) and in C
int col_opA = col_M0; //number of columns in op(A) and rows in op(B)
float complex alpha =1.0;
int lda = col_M0;
float complex beta = 0.0;
int ldc = rows_M1;
int ldb = rows_M1;
#ifdef DEBUG_PREPROC
int i = 0;
printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1);
for(i=0; i<rows_M0*col_M0; ++i)
printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i]));
for(i=0; i<rows_M1*col_M1; ++i)
printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i]));
#endif
cblas_cgemm(CblasColMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc);
#ifdef DEBUG_PREPROC
for(i=0; i<rows_opA*col_opB; ++i)
printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i]));
#endif
}
/*FILTERS */
void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE)
{
int N = order_H;
float complex* H_hermH_sigmaI = malloc_or_fail(N * N * sizeof(float complex));
float complex* H_herm = malloc_or_fail(N * N * sizeof(float complex));
H_hermH_plus_sigma2I(N, N, H, sigma2, H_hermH_sigmaI);
#ifdef DEBUG_PREPROC
int i =0;
for(i=0;i<N*N;i++)
printf(" H_hermH_sigmaI[%d] = (%f + i%f)\n", i , creal(H_hermH_sigmaI[i]), cimag(H_hermH_sigmaI[i]));
#endif
conjugate_transpose (N, H, H_herm); //equals H_herm
#ifdef DEBUG_PREPROC
for(i=0;i<N*N;i++)
printf(" H_herm[%d] = (%f + i%f)\n", i , creal(H_herm[i]), cimag(H_herm[i]));
#endif
lin_eq_solver(N, H_hermH_sigmaI, H_herm, W_MMSE);
#ifdef DEBUG_PREPROC
for(i=0;i<N*N;i++)
printf(" W_MMSE[%d] = (%f + i%f)\n", i , creal(W_MMSE[i]), cimag(W_MMSE[i]));
#endif
free(H_hermH_sigmaI);
free(H_herm);
}
#if 0
void compute_white_filter(float complex* H_re,
int order_H,
float sigma2,
float complex* W_Wh_0_re,
float complex* W_Wh_1_re){
int aatx, aarx, re;
int i,j;
int M =n_rx;
int N = n_tx;
int sigma2=noise_power;
float complex *H0_re = malloc_or_fail(n_rx*(n_tx>>2)*sizeof(float complex));
float complex *H1_re = malloc_or_fail(n_rx*(n_tx>>2)*sizeof(float complex));
float complex *R_corr_col_n_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *R_corr_col_n_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_0_herm_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_1_herm_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *D_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *D_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *W_Wh_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *W_Wh_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
for (aatx=0; aatx<n_tx/2; aatx++){
for (aarx=0; aarx<n_rx; aarx++) {
H0_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx][re]; // H0 gets [0 1 2 3; 4,5,6,7].' coefficients of H
H1_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx + 8][re]; // H1 gets [8 9 10 11; 12, 13, 14, 15].' coefficients of H
if (re == 0)
printf("ant %d, H_re = (%f + i%f) \n", aatx*n_rx + aarx, creal(H[aatx*n_rx + aarx][re]), cimag(H[aatx*n_rx + aarx][re]));
}
}
//HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H1_re, sigma2, R_corr_col_n_0_re);
HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H0_re, sigma2, R_corr_col_n_1_re);
eigen_vectors_values(n_rx, R_corr_col_n_0_re, U_0_re, D_0_re);
eigen_vectors_values(n_rx, R_corr_col_n_1_re, U_1_re, D_1_re);
transpose (n_rx, U_0_re, U_0_herm_re);
transpose (n_rx, U_1_re, U_1_herm_re);
sigma = (float)(sqrt((double)(sigma2)));
/*The inverse of a diagonal matrix is obtained by replacing each element in the diagonal with its reciprocal.
A square root of a diagonal matrix is given by the diagonal matrix, whose diagonal entries are just the square
roots of the original matrix.*/
D_0_re_inv_sqrt[0] = sqrt_float(1/D_0_re_inv[0]);
D_0_re_inv_sqrt[5] = sqrt_float(1/D_0_re_inv[5]);
D_0_re_inv_sqrt[10] = sqrt_float(1/D_0_re_inv[10]);
D_0_re_inv_sqrt[15] = sqrt_float(1/D_0_re_inv[15]);
D_1_re_inv[0] = sqrt_float(1/D_1_re_inv[0]);
D_1_re_inv[5] = sqrt_float(1/D_1_re_inv[5]);
D_1_re_inv[10] = sqrt_float(1/D_1_re_inv[10]);
D_1_re_inv[15] = sqrt_float(1/D_1_re_inv[15]);
now only to multiply
free(H0);
free(H1);
free(R_corr_col_n_0);
free(R_corr_col_n_1);
}
#endif
float sqrt_float(float x, float sqrt_x)
{
sqrt_x = (float)(sqrt((double)(x)));
return sqrt_x;
}
@@ -1,121 +0,0 @@
#include<stdio.h>
#include<math.h>
#include<complex.h>
#include <stdlib.h>
#include "PHY/defs_UE.h"
/* FUNCTIONS FOR LINEAR PREPROCESSING: MMSE, WHITENNING, etc*/
void transpose(int N, float complex *A, float complex *Result);
void conjugate_transpose(int N, float complex *A, float complex *Result);
void H_hermH_plus_sigma2I(int N, int M, float complex *A, float sigma2, float complex *Result);
void HH_herm_plus_sigma2I(int M, int N, float complex *A, float sigma2, float complex *Result);
void eigen_vectors_values(int N, float complex *A, float complex *Vectors, float *Values_Matrix);
void lin_eq_solver(int N, float complex *A, float complex* B);
//float complex* lin_eq_solver (int N, float complex* A, float complex* B);
/* mutl_matrix_matrix_row_based performs multiplications when matrix is row-oriented H[0], H[1]; H[2], H[3]*/
void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result );
/* mutl_matrix_matrix_col_based performs multiplications matrix is column-oriented H[0], H[2]; H[1], H[3]*/
void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result );
void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE);
void compute_white_filter(float complex* H, int order_H, float sigma2, float complex* U_1, float complex* D_1);
void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars,
LTE_DL_FRAME_PARMS *frame_parms,
PHY_MEASUREMENTS *measurements,
unsigned char first_symbol_flag,
MIMO_mode_t mimo_mode,
unsigned short mmse_flag,
int noise_power,
unsigned char symbol,
unsigned short nb_rb);
void precode_channel_est(int32_t **dl_ch_estimates_ext,
LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *pdsch_vars,
unsigned char symbol,
unsigned short nb_rb,
MIMO_mode_t mimo_mode);
void rxdataF_to_float(int32_t **rxdataF_ext,
float complex **rxdataF_f,
int n_rx,
int length,
int start_point);
void chan_est_to_float(int32_t **dl_ch_estimates_ext,
float complex **dl_ch_estimates_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void float_to_chan_est(int32_t **dl_ch_estimates_ext,
float complex **dl_ch_estimates_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void float_to_rxdataF(int32_t **rxdataF_ext,
float complex **rxdataF_f,
int n_tx,
int n_rx,
int length,
int start_point);
void mult_mmse_rxdataF(float complex** Wmmse,
float complex** rxdataF_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void mult_mmse_chan_est(float complex** Wmmse,
float complex** dl_ch_estimates_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void mmse_processing_core(int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
int sigma2,
int n_tx,
int n_rx,
int length,
int start_point);
void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx,
float complex **H,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
float sigma2,
int n_tx,
int n_rx,
int length,
int start_point);
void whitening_processing_core_flp(float complex** rxdataF_ext_flcpx,
float complex **H,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
float sigma2,
int n_tx,
int n_rx,
int length,
int start_point);
float sqrt_float(float x, float sqrt_x);
-43
View File
@@ -50,49 +50,6 @@
#define MBSFN_FDD_SF7 0x08
#define MBSFN_FDD_SF8 0x04
void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe) {
char fname[32],vname[32];
#define NSYMB_PMCH 12
sprintf(fname,"mch_rxF_ext0.m");
sprintf(vname,"pmch_rxF_ext0");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0],12*(ue->frame_parms.N_RB_DL)*12,1,1);
sprintf(fname,"mch_ch_ext00.m");
sprintf(vname,"pmch_ch_ext00");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
/*
LOG_M("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*NSYMB_PMCH,1,1);
LOG_M("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*NSYMB_PMCH,1,1);
LOG_M("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*NSYMB_PMCH,1,1);
LOG_M("dlsch%d_rho.m","dl_rho",pdsch_vars[eNB_id]->rho[0],12*N_RB_DL*NSYMB_PMCH,1,1);
*/
sprintf(fname,"mch_rxF_comp0.m");
sprintf(vname,"pmch_rxF_comp0");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
sprintf(fname,"mch_rxF_llr.m");
sprintf(vname,"pmch_llr");
LOG_M(fname,vname, ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->llr[0],coded_bits_per_codeword,1,0);
sprintf(fname,"mch_mag1.m");
sprintf(vname,"pmch_mag1");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
sprintf(fname,"mch_mag2.m");
sprintf(vname,"pmch_mag2");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
LOG_M("mch00_ch0.m","pmch00_ch0",
&(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
ue->frame_parms.ofdm_symbol_size*12,1,1);
LOG_M("rxsig_mch.m","rxs_mch",
&ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],
ue->frame_parms.samples_per_tti,1,1);
/*
if (PHY_vars_eNB_g)
LOG_M("txsig_mch.m","txs_mch",
&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][0][subframe*ue->frame_parms.samples_per_tti],
ue->frame_parms.samples_per_tti,1,1);*/
}
void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id) {
LTE_UE_DLSCH_t *dlsch = ue->dlsch_MCH[eNB_id];
LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
@@ -78,17 +78,6 @@ int rx_pmch_khz_1dot25(PHY_VARS_UE *ue,
unsigned char symbol*/
,int mcs);
/** \brief Dump OCTAVE/MATLAB files for PMCH debugging
@param phy_vars_ue Pointer to UE variables
@param eNB_id index of eNB in ue variables
@param coded_bits_per_codeword G from 36.211
@param subframe Index of subframe
@returns 0 on success
*/
void dump_mch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe);
/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
@param stream0_in Input from channel compensated (MR combined) stream 0
@param stream1_in Input from channel compensated (MR combined) stream 1
@@ -580,216 +569,6 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint32_t llr_offset,
uint8_t beamforming_mode);
/** \fn dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
uint8_t l,
uint16_t nb_rb)
\brief This function does the first stage of llr computation for SISO, by just extracting the pilots, PBCH and primary/secondary synchronization sequences.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param rxdataF_comp_i Compensated channel output for interference
@param l symbol in sub-frame
@param nb_rb Number of RBs in this allocation
*/
void dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
uint8_t l,
uint16_t nb_rb);
/** \fn dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb)
\brief This function does Alamouti combining on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param symbol Symbol in sub-frame
@param nb_rb Number of RBs in this allocation
*/
void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb);
/** \fn dlsch_antcyc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb)
\brief This function does antenna selection (based on antenna cycling pattern) on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals. Note that this is not LTE, it is just included for comparison purposes.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param symbol Symbol in sub-frame
@param nb_rb Number of RBs in this allocation
*/
void dlsch_antcyc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb);
/** \fn dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
int32_t **rho,
int32_t **rho_i,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb,
uint8_t dual_stream_UE)
\brief This function does maximal-ratio combining for dual-antenna receivers.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param rxdataF_comp_i Compensated channel output for interference
@param rho Cross correlation between spatial channels
@param rho_i Cross correlation between signal and inteference channels
@param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param symbol Symbol in sub-frame
@param nb_rb Number of RBs in this allocation
@param dual_stream_UE Flag to indicate dual-stream detection
*/
void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
int32_t **rho,
int32_t **rho_i,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
int32_t **dl_ch_mag_i,
int32_t **dl_ch_magb_i,
uint8_t symbol,
uint16_t nb_rb,
uint8_t dual_stream_UE);
void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *lte_ue_pdsch_vars,
int harq_pid,
int round,
unsigned char symbol,
unsigned short nb_rb,
unsigned char dual_stream_UE);
/** \fn dlsch_extract_rbs_single(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
LTE_DL_FRAME_PARMS *frame_parms)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for single antenna eNB transmission.
@param rxdataF Raw FFT output of received signal
@param dl_ch_estimates Channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_ch_estimates_ext Channel estimates for RBs in this allocation
@param pmi subband Precoding matrix indicator
@param pmi_ext Extracted PMI for chosen RBs
@param rb_alloc RB allocation vector
@param symbol Symbol to extract
@param subframe Subframe number
@param vrb_type Flag to indicate distributed VRB type
@param high_speed_flag
@param frame_parms Pointer to frame descriptor
*/
uint16_t dlsch_extract_rbs_single(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
LTE_DL_FRAME_PARMS *frame_parms)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for dual antenna eNB transmission.
@param rxdataF Raw FFT output of received signal
@param dl_ch_estimates Channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_ch_estimates_ext Channel estimates for RBs in this allocation
@param pmi subband Precoding matrix indicator
@param pmi_ext Extracted PMI for chosen RBs
@param rb_alloc RB allocation vector
@param symbol Symbol to extract
@param subframe Subframe index
@param high_speed_flag
@param frame_parms Pointer to frame descriptor
*/
uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms,
MIMO_mode_t mimo_mode);
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_bf_ch_estimates_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for single antenna eNB transmission.
@param rxdataF Raw FFT output of received signal
@param dl_bf_ch_estimates Beamforming channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_bf_ch_estimates_ext Beamforming channel estimates for RBs in this allocation
@param rb_alloc RB allocation vector
@param symbol Symbol to extract
@param subframe Subframe number
@param high_speed_flag
@param frame_parms Pointer to frame descriptor
*/
uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_bf_ch_estimates_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
/** \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 dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
@@ -819,35 +598,6 @@ void dlsch_channel_compensation(int32_t **rxdataF_ext,
uint8_t output_shift,
PHY_MEASUREMENTS *phy_measurements);
void dlsch_channel_compensation_core(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
int **dl_ch_magb,
int **rxdataF_comp,
int **rho,
unsigned char n_tx,
unsigned char n_rx,
unsigned char mod_order,
unsigned char output_shift,
int length,
int start_point);
void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
unsigned short nb_rb,
int **dl_ch_estimates_ext,
int **dl_ch_estimates_ext_i,
int **dl_ch_rho_ext,
unsigned char output_shift);
void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
unsigned short nb_rb,
int **dl_ch_estimates_ext,
int **dl_ch_estimates_ext_i,
int **dl_ch_rho_ext,
unsigned char output_shift0,
unsigned char output_shift1);
//This function is used to compute multiplications in Hhermitian * H matrix
void conjch0_mult_ch1(int *ch0,
int *ch1,
@@ -869,10 +619,6 @@ void construct_HhH_elements(int *ch0conj_ch0,
int32_t *after_mf_11,
unsigned short nb_rb);
void squared_matrix_element(int32_t *Hh_h_00,
int32_t *Hh_h_00_sq,
unsigned short nb_rb);
void dlsch_channel_level_TM34_meas(int *ch00,
int *ch01,
int *ch10,
@@ -901,38 +647,6 @@ uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
int *dl_ch_estimates_11,
unsigned short nb_rb);
void dlsch_channel_compensation_TM56(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
int **dl_ch_magb,
int **rxdataF_comp,
unsigned char *pmi_ext,
LTE_DL_FRAME_PARMS *frame_parms,
PHY_MEASUREMENTS *phy_measurements,
int eNB_id,
unsigned char symbol,
unsigned char mod_order,
unsigned short nb_rb,
unsigned char output_shift,
unsigned char dl_power_off);
void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *lte_ue_pdsch_vars,
PHY_MEASUREMENTS *phy_measurements,
int eNB_id,
unsigned char symbol,
unsigned char mod_order0,
unsigned char mod_order1,
int harq_pid,
int round,
MIMO_mode_t mimo_mode,
unsigned short nb_rb,
unsigned short mmse_flag,
unsigned char output_shift0,
unsigned char output_shift1);
/** \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 dl_ch_estimates_ext Channel estimates in allocated RBs
@param frame_parms Pointer to frame descriptor
@@ -1669,12 +1383,6 @@ uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2nd
uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode);
uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB,
LTE_DL_FRAME_PARMS *lte_frame_parms,
LTE_UE_DLSCH_t *dlsch,
uint8_t subframe,
uint8_t num_pdcch_symbols);
// DL power control functions
double get_pa_dB(uint8_t pa);
@@ -50,30 +50,6 @@
//#define DEBUG_DLSCH_DEMOD
//#define DEBUG_PDSCH_RX
// [MCS][i_mod (0,1,2) = (2,4,6)]
//unsigned char offset_mumimo_llr_drange_fix=0;
//inferference-free case
/*unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;*/
//unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1,
// 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous
/*
unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{6,6,6},{6,6,6},{6,6,6},{5,5,5},{4,4,4},{1,2,4}, // QPSK
{5,5,4},{5,5,5},{5,5,5},{3,3,3},{2,2,2},{2,2,2},{2,2,2}, // 16-QAM
{2,2,1},{3,3,3},{3,3,3},{3,3,1},{2,2,2},{2,2,2},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; //64-QAM
*/
/*
//first optimization try
unsigned char offset_mumimo_llr_drange[29][3]={{7, 8, 7},{6, 6, 7},{6, 6, 7},{6, 6, 6},{5, 6, 6},{5, 5, 6},{5, 5, 6},{4, 5, 4},{4, 3, 4},{3, 2, 2},{6, 5, 5},{5, 4, 4},{5, 5, 4},{3, 3, 2},{2, 2, 1},{2, 1, 1},{2, 2, 2},{3, 3, 3},{3, 3, 2},{3, 3, 2},{3, 2, 1},{2, 2, 2},{2, 2, 2},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
*/
//second optimization try
/*
unsigned char offset_mumimo_llr_drange[29][3]={{5, 8, 7},{4, 6, 8},{3, 6, 7},{7, 7, 6},{4, 7, 8},{4, 7, 4},{6, 6, 6},{3, 6, 6},{3, 6, 6},{1, 3, 4},{1, 1, 0},{3, 3, 2},{3, 4, 1},{4, 0, 1},{4, 2, 2},{3, 1, 2},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; w
*/
//unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
#define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
#define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
+7 -12
View File
@@ -2925,19 +2925,16 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
else
ue->dlsch_mtch_errors[sync_area][0]++;
LOG_E(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
LOG_E(PHY,
"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
ue->Mod_id,
frame_rx,subframe_rx,
frame_rx,
subframe_rx,
ue->dlsch_mcch_errors[sync_area][0],
ue->dlsch_mtch_errors[sync_area][0],
ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
ue->dlsch_MCH[0]->harq_processes[0]->TBS >> 3,
ue->dlsch_MCH[0]->max_turbo_iterations,
ue->dlsch_MCH[0]->harq_processes[0]->G);
// dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
//if(subframe_rx == 3){
//dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
//exit_fun("nothing to add");
//}
if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) {
for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
@@ -2962,11 +2959,9 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
CC_id,
frame_rx,
ue->dlsch_MCH[0]->harq_processes[0]->b,
ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
eNB_id,// not relevant in eMBMS context
ue->dlsch_MCH[0]->harq_processes[0]->TBS >> 3,
eNB_id, // not relevant in eMBMS context
sync_area);
//dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
//exit_fun("nothing to add");
if (mcch_active == 1)
ue->dlsch_mcch_received[sync_area][0]++;
@@ -1849,27 +1849,6 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
}
}
/*
FIXME: Function cblas_zgemv has an undefined output (for the same input) after a second call in RHEL8 (acorr = nan)
alpha.r = 1.0;
alpha.i = 0.0;
beta.r = 0.0;
beta.i = 0.0;
cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx,
(void *) &alpha, (void *) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx,
(void *) anew, 1, (void *) &beta, (void *) acorr, 1);
*/
/*
for (aarx=0;aarx<desc->nb_rx;aarx++) {
for (aatx=0;aatx<desc->nb_tx;aatx++) {
desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x;
desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y;
printf("tap %d, acorr1(%d,%d) = %f+1j*%f\n",i,aatx,aarx,acorr[aarx+(aatx*desc->nb_rx)].x, acorr[aarx+(aatx*desc->nb_rx)].y);
}
}
*/
if (desc->first_run==1) {
memcpy(desc->a[i], acorr, desc->nb_tx * desc->nb_rx * sizeof(*acorr));
} else {
+1 -1
View File
@@ -64,4 +64,4 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_CONFIRM, MESSAGE_PRIORITY_MED, f1ap_ue_
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REFUSE, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_refuse_t, f1ap_ue_context_modification_refuse)
/* CU -> DU*/
MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind)
MESSAGE_DEF(F1AP_PAGING, MESSAGE_PRIORITY_MED, f1ap_paging_t, f1ap_paging)
+61 -7
View File
@@ -24,6 +24,7 @@
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <stdbool.h>
#include "common/5g_platform_types.h"
#include "common/platform_constants.h"
#include "common/utils/ds/byte_array.h"
@@ -67,7 +68,7 @@
#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_cmd
#define F1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_complete
#define F1AP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.f1ap_paging_ind
#define F1AP_PAGING(mSGpTR) (mSGpTR)->ittiMsg.f1ap_paging
/* Length of the transport layer address string
* 160 bits / 8 bits by char.
@@ -631,14 +632,67 @@ typedef struct f1ap_ue_context_rel_cplt_t {
uint32_t gNB_DU_ue_id;
} f1ap_ue_context_rel_cplt_t;
typedef struct f1ap_paging_ind_s {
uint16_t ueidentityindexvalue;
uint64_t fiveg_s_tmsi;
uint8_t fiveg_s_tmsi_length;
typedef struct f1ap_paging_cell_item_s {
plmn_id_t plmn;
uint64_t nr_cellid;
uint8_t paging_drx;
} f1ap_paging_ind_t;
} f1ap_paging_cell_item_t;
typedef enum f1ap_paging_identity_type_e {
F1AP_PAGING_IDENTITY_RAN_UE, // RAN UE Paging Identity (I-RNTI)
F1AP_PAGING_IDENTITY_CN_UE // CN UE Paging Identity (5G-S-TMSI)
} f1ap_paging_identity_type_t;
typedef union f1ap_paging_identity_u {
// RAN UE Paging Identity (I-RNTI)
uint64_t ran_ue_paging_identity;
// CN UE Paging Identity (5G-S-TMSI)
uint64_t cn_ue_paging_identity;
} f1ap_paging_identity_t;
/** @brief Paging DRX (9.3.1.40 TS 38.473)
* This IE indicates the Paging DRX as defined in
* TS 38.304. Unit in radio frames.*/
typedef enum f1ap_paging_drx_e {
F1AP_PAGING_DRX_32 = 0,
F1AP_PAGING_DRX_64 = 1,
F1AP_PAGING_DRX_128 = 2,
F1AP_PAGING_DRX_256 = 3
} f1ap_paging_drx_t;
/** @brief Paging Priority (9.3.1.41 TS 38.473)
* Lower value codepoint indicates higher priority.
* codepoint indicates higher priority.*/
typedef enum f1ap_paging_priority_e {
F1AP_PAGING_PRIO_LEVEL1 = 0,
F1AP_PAGING_PRIO_LEVEL2 = 1,
F1AP_PAGING_PRIO_LEVEL3 = 2,
F1AP_PAGING_PRIO_LEVEL4 = 3,
F1AP_PAGING_PRIO_LEVEL5 = 4,
F1AP_PAGING_PRIO_LEVEL6 = 5,
F1AP_PAGING_PRIO_LEVEL7 = 6,
F1AP_PAGING_PRIO_LEVEL8 = 7
} f1ap_paging_priority_t;
typedef bool f1ap_paging_origin_t;
#define F1AP_PAGING_ORIGIN_NON_3GPP true
/* 9.2.6.1 Paging (3GPP TS 38.473) */
typedef struct {
// UE Identity Index value (mandatory)
uint16_t ue_identity_index_value;
// Paging Identity (mandatory)
f1ap_paging_identity_type_t identity_type;
f1ap_paging_identity_t identity;
// Paging DRX: 0 (32), 1 (64), 2 (128), 3 (256) (optional)
f1ap_paging_drx_t *drx;
// Paging priority (optional)
f1ap_paging_priority_t *priority;
// Paging origin (optional)
f1ap_paging_origin_t *origin;
// Paging Cell List (mandatory); max 512 cells
uint16_t n_cells;
f1ap_paging_cell_item_t *cells;
} f1ap_paging_t;
typedef struct f1ap_lost_connection_t {
int dummy;
-5
View File
@@ -47,8 +47,6 @@ MESSAGE_DEF(NGAP_PAGING_LOG , MESSAGE_PRIORITY_MED, IttiMsgText
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_release_request_log)
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_release_response_log)
MESSAGE_DEF(NGAP_ERROR_INDICATION_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_error_indication_log)
MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_path_switch_req_log)
MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_ACK_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_path_switch_req_ack_log)
/* gNB application layer -> NGAP messages */
MESSAGE_DEF(NGAP_REGISTER_GNB_REQ , MESSAGE_PRIORITY_MED, ngap_register_gnb_req_t , ngap_register_gnb_req)
@@ -65,8 +63,6 @@ MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, ngap_initial_
MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_FAIL, MESSAGE_PRIORITY_MED, ngap_initial_context_setup_fail_t, ngap_initial_context_setup_fail)
MESSAGE_DEF(NGAP_NAS_NON_DELIVERY_IND , MESSAGE_PRIORITY_MED, ngap_nas_non_delivery_ind_t , ngap_nas_non_delivery_ind)
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, ngap_ue_release_complete_t , ngap_ue_release_complete)
MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_resp_t , ngap_ue_ctxt_modification_resp)
MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_fail_t , ngap_ue_ctxt_modification_fail)
MESSAGE_DEF(NGAP_PDUSESSION_SETUP_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_resp_t , ngap_pdusession_setup_resp)
MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_modify_resp_t , ngap_pdusession_modify_resp)
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, ngap_pdusession_release_resp_t , ngap_pdusession_release_resp)
@@ -81,7 +77,6 @@ MESSAGE_DEF(NGAP_DL_RAN_STATUS_TRANSFER, MESSAGE_PRIORITY_MED, ngap_ran_status_t
/* NGAP -> RRC messages */
MESSAGE_DEF(NGAP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, ngap_downlink_nas_t , ngap_downlink_nas )
MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, ngap_initial_context_setup_req_t , ngap_initial_context_setup_req )
MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_req_t , ngap_ue_ctxt_modification_req)
MESSAGE_DEF(NGAP_PAGING_IND , MESSAGE_PRIORITY_MED, ngap_paging_ind_t , ngap_paging_ind )
MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQ , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_req_t , ngap_pdusession_setup_req )
MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_REQ , MESSAGE_PRIORITY_MED, ngap_pdusession_modify_req_t , ngap_pdusession_modify_req )
+174 -149
View File
@@ -32,9 +32,9 @@
#include "common/5g_platform_types.h"
#include "common/platform_constants.h"
#include "common/platform_types.h"
#include "common/5g_platform_types.h"
#include "s1ap_messages_types.h"
#include "ds/byte_array.h"
#include "utils.h"
// Defines to access message fields.
#define NGAP_REGISTER_GNB_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_register_gnb_req
@@ -58,7 +58,6 @@
#define NGAP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_nas
#define NGAP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_req
#define NGAP_UE_CTXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_req
#define NGAP_UE_CONTEXT_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_command
#define NGAP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_complete
#define NGAP_PDUSESSION_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_req
@@ -89,39 +88,46 @@
#define NGAP_MAX_NB_AMF_IP_ADDRESS 10
#define NGAP_MAX_NO_TAI_PAGING 16 // 9.2.4.1 3GPP TS 38.413
/* Security key length used within gNB
* Even if only 16 bytes will be effectively used,
* the key length is 32 bytes (256 bits)
*/
#define SECURITY_KEY_LENGTH 32
typedef enum ngap_paging_drx_e {
NGAP_PAGING_DRX_32 = 0x0,
NGAP_PAGING_DRX_64 = 0x1,
NGAP_PAGING_DRX_128 = 0x2,
NGAP_PAGING_DRX_256 = 0x3
} ngap_paging_drx_t;
#define NGAP_MAX_NO_TAI_PAGING 16 // 9.2.4.1 3GPP TS 38.413
/* Lower value codepoint
* indicates higher priority.
*/
typedef enum ngap_paging_priority_s {
NGAP_PAGING_PRIO_LEVEL1 = 0,
NGAP_PAGING_PRIO_LEVEL2 = 1,
NGAP_PAGING_PRIO_LEVEL3 = 2,
NGAP_PAGING_PRIO_LEVEL4 = 3,
NGAP_PAGING_PRIO_LEVEL5 = 4,
NGAP_PAGING_PRIO_LEVEL6 = 5,
NGAP_PAGING_PRIO_LEVEL7 = 6,
NGAP_PAGING_PRIO_LEVEL8 = 7
} ngap_paging_priority_t;
/* Paging DRX values (3GPP TS 38.413) */
#define FOREACH_PAGING_DRX(DRX_DEF) \
DRX_DEF(NGAP_PAGING_DRX_32, 0x0) \
DRX_DEF(NGAP_PAGING_DRX_64, 0x1) \
DRX_DEF(NGAP_PAGING_DRX_128, 0x2) \
DRX_DEF(NGAP_PAGING_DRX_256, 0x3)
typedef enum ngap_cn_domain_s {
NGAP_CN_DOMAIN_PS = 1,
NGAP_CN_DOMAIN_CS = 2
} ngap_cn_domain_t;
/* Lower value codepoint indicates higher priority (3GPP TS 38.413) */
#define FOREACH_PAGING_PRIORITY(PRIO_DEF) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL1, 0) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL2, 1) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL3, 2) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL4, 3) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL5, 4) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL6, 5) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL7, 6) \
PRIO_DEF(NGAP_PAGING_PRIO_LEVEL8, 7)
/* Paging Origin (9.3.3.22 of 3GPP TS 38.413) */
#define FOREACH_PAGING_ORIGIN(ORIGIN_DEF) ORIGIN_DEF(NGAP_PAGING_ORIGIN_NON_3GPP, 0)
static const text_info_t paging_drx_text[] = {FOREACH_PAGING_DRX(TO_TEXT)};
static const text_info_t paging_prio_text[] = {FOREACH_PAGING_PRIORITY(TO_TEXT)};
static const text_info_t paging_origin_text[] = {FOREACH_PAGING_ORIGIN(TO_TEXT)};
typedef enum { FOREACH_PAGING_DRX(TO_ENUM) } ngap_paging_drx_t;
typedef enum { FOREACH_PAGING_PRIORITY(TO_ENUM) } ngap_paging_priority_t;
typedef enum { FOREACH_PAGING_ORIGIN(TO_ENUM) } ngap_paging_origin_t;
typedef struct ngap_net_ip_address_s {
unsigned ipv4:1;
@@ -144,25 +150,26 @@ typedef struct ngap_security_capabilities_s {
uint16_t eUTRAintegrity_algorithms;
} ngap_security_capabilities_t;
/* Provides the establishment cause for the RRC connection request as provided
* by the upper layers. W.r.t. the cause value names: highPriorityAccess
* concerns AC11..AC15, ‘mt Estands for ‘Mobile Terminating Eand ‘mo Efor
* 'Mobile Originating'. Defined in TS 36.331.
*/
typedef enum ngap_rrc_establishment_cause_e {
NGAP_RRC_CAUSE_EMERGENCY = 0x0,
NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS = 0x1,
NGAP_RRC_CAUSE_MT_ACCESS = 0x2,
NGAP_RRC_CAUSE_MO_SIGNALLING = 0x3,
NGAP_RRC_CAUSE_MO_DATA = 0x4,
NGAP_RRC_CAUSE_MO_VOICECALL = 0x5,
NGAP_RRC_CAUSE_MO_VIDEOCALL = 0x6,
NGAP_RRC_CAUSE_MO_SMS = 0x7,
NGAP_RRC_CAUSE_MPS_PRIORITY_ACCESS = 0x8,
NGAP_RRC_CAUSE_MCS_PRIORITY_ACCESS = 0x9,
NGAP_RRC_CAUSE_NOTAVAILABLE = 0x10,
NGAP_RRC_CAUSE_LAST
} ngap_rrc_establishment_cause_t;
/** @brief RRC Establishment Cause (9.3.1.111 of 3GPP TS 38.413)
* Indicates the reason for RRC Connection Establishment/Resume as received from the UE.
* The notAvailable value is used when re-establishing/resuming an RRC connection and the
* cause value from the UE does not map to any other value. */
#define FOREACH_RRC_ESTABLISHMENT_CAUSE(CAUSE_DEF) \
CAUSE_DEF(NGAP_RRC_CAUSE_EMERGENCY, 0) \
CAUSE_DEF(NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS, 1) \
CAUSE_DEF(NGAP_RRC_CAUSE_MT_ACCESS, 2) \
CAUSE_DEF(NGAP_RRC_CAUSE_MO_SIGNALLING, 3) \
CAUSE_DEF(NGAP_RRC_CAUSE_MO_DATA, 4) \
CAUSE_DEF(NGAP_RRC_CAUSE_MO_VOICECALL, 5) \
CAUSE_DEF(NGAP_RRC_CAUSE_MO_VIDEOCALL, 6) \
CAUSE_DEF(NGAP_RRC_CAUSE_MO_SMS, 7) \
CAUSE_DEF(NGAP_RRC_CAUSE_MPS_PRIORITY_ACCESS, 8) \
CAUSE_DEF(NGAP_RRC_CAUSE_MCS_PRIORITY_ACCESS, 9) \
CAUSE_DEF(NGAP_RRC_CAUSE_NOTAVAILABLE, 10) \
CAUSE_DEF(NGAP_RRC_CAUSE_MO_EXCEPTION_DATA, 11) \
CAUSE_DEF(NGAP_RRC_CAUSE_LAST, 12)
typedef enum { FOREACH_RRC_ESTABLISHMENT_CAUSE(TO_ENUM) } ngap_rrc_establishment_cause_t;
typedef struct fiveg_s_tmsi_s {
uint16_t amf_set_id;
@@ -170,10 +177,6 @@ typedef struct fiveg_s_tmsi_s {
uint32_t m_tmsi;
} fiveg_s_tmsi_t;
typedef struct ngap_ue_paging_identity_s {
fiveg_s_tmsi_t s_tmsi;
} ngap_ue_paging_identity_t;
typedef enum ngap_ue_identities_presenceMask_e {
NGAP_UE_IDENTITIES_FiveG_s_tmsi = 1 << 1,
NGAP_UE_IDENTITIES_guami = 1 << 2,
@@ -243,15 +246,16 @@ typedef struct pdusession_modify_s {
qos_flow_addmod_response_item_t qos[MAX_QOS_FLOWS];
} pdusession_modify_t;
/* Cause (9.3.1.2 of 3GPP TS 38.413) */
typedef enum ngap_cause_group_e {
NGAP_CAUSE_NOTHING, /* No components present */
NGAP_CAUSE_RADIO_NETWORK,
NGAP_CAUSE_TRANSPORT,
NGAP_CAUSE_NAS,
NGAP_CAUSE_PROTOCOL,
NGAP_CAUSE_MISC,
} ngap_cause_group_t;
/* Cause Group (9.3.1.2 of 3GPP TS 38.413) */
#define FOREACH_CAUSE_GROUP(CAUSE_DEF) \
CAUSE_DEF(NGAP_CAUSE_NOTHING, 0) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK, 1) \
CAUSE_DEF(NGAP_CAUSE_TRANSPORT, 2) \
CAUSE_DEF(NGAP_CAUSE_NAS, 3) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL, 4) \
CAUSE_DEF(NGAP_CAUSE_MISC, 5)
typedef enum { FOREACH_CAUSE_GROUP(TO_ENUM) } ngap_cause_group_t;
/* Cause (9.3.1.2 of 3GPP TS 38.413) */
typedef struct ngap_cause_s {
@@ -259,73 +263,74 @@ typedef struct ngap_cause_s {
uint8_t value;
} ngap_cause_t;
typedef enum ngap_Cause_radio_network_e {
NGAP_CAUSE_RADIO_NETWORK_UNSPECIFIED,
NGAP_CAUSE_RADIO_NETWORK_TXNRELOCOVERALL_EXPIRY,
NGAP_CAUSE_RADIO_NETWORK_SUCCESSFUL_HANDOVER,
NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_NGRAN_GENERATED_REASON,
NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_5GC_GENERATED_REASON,
NGAP_CAUSE_RADIO_NETWORK_HANDOVER_CANCELLED,
NGAP_CAUSE_RADIO_NETWORK_PARTIAL_HANDOVER,
NGAP_CAUSE_RADIO_NETWORK_HO_FAILURE_IN_TARGET_5GC_NGRAN_NODE_OR_TARGET_SYSTEM,
NGAP_CAUSE_RADIO_NETWORK_HO_TARGET_NOT_ALLOWED,
NGAP_CAUSE_RADIO_NETWORK_TNGRELOCOVERALL_EXPIRY,
NGAP_CAUSE_RADIO_NETWORK_TNGRELOCPREP_EXPIRY,
NGAP_CAUSE_RADIO_NETWORK_CELL_NOT_AVAILABLE,
NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_TARGETID,
NGAP_CAUSE_RADIO_NETWORK_NO_RADIO_RESOURCES_AVAILABLE_IN_TARGET_CELL,
NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_LOCAL_UE_NGAP_ID,
NGAP_CAUSE_RADIO_NETWORK_INCONSISTENT_REMOTE_UE_NGAP_ID,
NGAP_CAUSE_RADIO_NETWORK_HANDOVER_DESIRABLE_FOR_RADIO_REASON,
NGAP_CAUSE_RADIO_NETWORK_TIME_CRITICAL_HANDOVER,
NGAP_CAUSE_RADIO_NETWORK_RESOURCE_OPTIMISATION_HANDOVER,
NGAP_CAUSE_RADIO_NETWORK_REDUCE_LOAD_IN_SERVING_CELL,
NGAP_CAUSE_RADIO_NETWORK_USER_INACTIVITY,
NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST,
NGAP_CAUSE_RADIO_NETWORK_RADIO_RESOURCES_NOT_AVAILABLE,
NGAP_CAUSE_RADIO_NETWORK_INVALID_QOS_COMBINATION,
NGAP_CAUSE_RADIO_NETWORK_FAILURE_IN_RADIO_INTERFACE_PROCEDURE,
NGAP_CAUSE_RADIO_NETWORK_INTERACTION_WITH_OTHER_PROCEDURE,
NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID,
NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_QOS_FLOW_ID,
NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_PDU_SESSION_ID_INSTANCES,
NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_QOS_FLOW_ID_INSTANCES,
NGAP_CAUSE_RADIO_NETWORK_ENCRYPTION_AND_OR_INTEGRITY_PROTECTION_ALGORITHMS_NOT_SUPPORTED,
NGAP_CAUSE_RADIO_NETWORK_NG_INTRA_SYSTEM_HANDOVER_TRIGGERED,
NGAP_CAUSE_RADIO_NETWORK_NG_INTER_SYSTEM_HANDOVER_TRIGGERED,
NGAP_CAUSE_RADIO_NETWORK_XN_HANDOVER_TRIGGERED,
NGAP_CAUSE_RADIO_NETWORK_NOT_SUPPORTED_5QI_VALUE,
NGAP_CAUSE_RADIO_NETWORK_UE_CONTEXT_TRANSFER,
NGAP_CAUSE_RADIO_NETWORK_IMS_VOICE_EPS_FALLBACK_OR_RAT_FALLBACK_TRIGGERED,
NGAP_CAUSE_RADIO_NETWORK_UP_INTEGRITY_PROTECTION_NOT_POSSIBLE,
NGAP_CAUSE_RADIO_NETWORK_UP_CONFIDENTIALITY_PROTECTION_NOT_POSSIBLE,
NGAP_CAUSE_RADIO_NETWORK_SLICE_NOT_SUPPORTED,
NGAP_CAUSE_RADIO_NETWORK_UE_IN_RRC_INACTIVE_STATE_NOT_REACHABLE,
NGAP_CAUSE_RADIO_NETWORK_REDIRECTION,
NGAP_CAUSE_RADIO_NETWORK_RESOURCES_NOT_AVAILABLE_FOR_THE_SLICE,
NGAP_CAUSE_RADIO_NETWORK_UE_MAX_INTEGRITY_PROTECTED_DATA_RATE_REASON,
NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_CN_DETECTED_MOBILITY,
NGAP_CAUSE_RADIO_NETWORK_N26_INTERFACE_NOT_AVAILABLE,
NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_PRE_EMPTION,
NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_LOCATION_REPORTING_REFERENCE_ID_INSTANCES,
NGAP_CAUSE_RADIO_NETWORK_RSN_NOT_AVAILABLE_FOR_THE_UP,
NGAP_CAUSE_RADIO_NETWORK_NPN_ACCESS_DENIED,
NGAP_CAUSE_RADIO_NETWORK_CAG_ONLY_ACCESS_DENIED,
NGAP_CAUSE_RADIO_NETWORK_INSUFFICIENT_UE_CAPABILITIES
} ngap_cause_radio_network_t;
/* Radio Network Cause (9.3.1.2 of 3GPP TS 38.413) */
#define FOREACH_CAUSE_RADIO_NETWORK(CAUSE_DEF) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UNSPECIFIED, 0) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_TXNRELOCOVERALL_EXPIRY, 1) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_SUCCESSFUL_HANDOVER, 2) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_NGRAN_GENERATED_REASON, 3) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_5GC_GENERATED_REASON, 4) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_HANDOVER_CANCELLED, 5) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_PARTIAL_HANDOVER, 6) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_HO_FAILURE_IN_TARGET_5GC_NGRAN_NODE_OR_TARGET_SYSTEM, 7) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_HO_TARGET_NOT_ALLOWED, 8) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_TNGRELOCOVERALL_EXPIRY, 9) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_TNGRELOCPREP_EXPIRY, 10) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_CELL_NOT_AVAILABLE, 11) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_TARGETID, 12) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_NO_RADIO_RESOURCES_AVAILABLE_IN_TARGET_CELL, 13) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_LOCAL_UE_NGAP_ID, 14) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_INCONSISTENT_REMOTE_UE_NGAP_ID, 15) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_HANDOVER_DESIRABLE_FOR_RADIO_REASON, 16) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_TIME_CRITICAL_HANDOVER, 17) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RESOURCE_OPTIMISATION_HANDOVER, 18) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_REDUCE_LOAD_IN_SERVING_CELL, 19) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_USER_INACTIVITY, 20) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST, 21) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RADIO_RESOURCES_NOT_AVAILABLE, 22) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_INVALID_QOS_COMBINATION, 23) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_FAILURE_IN_RADIO_INTERFACE_PROCEDURE, 24) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_INTERACTION_WITH_OTHER_PROCEDURE, 25) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_PDU_SESSION_ID, 26) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UNKNOWN_QOS_FLOW_ID, 27) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_PDU_SESSION_ID_INSTANCES, 28) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_QOS_FLOW_ID_INSTANCES, 29) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_ENCRYPTION_AND_OR_INTEGRITY_PROTECTION_ALGORITHMS_NOT_SUPPORTED, 30) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_NG_INTRA_SYSTEM_HANDOVER_TRIGGERED, 31) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_NG_INTER_SYSTEM_HANDOVER_TRIGGERED, 32) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_XN_HANDOVER_TRIGGERED, 33) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_NOT_SUPPORTED_5QI_VALUE, 34) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UE_CONTEXT_TRANSFER, 35) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_IMS_VOICE_EPS_FALLBACK_OR_RAT_FALLBACK_TRIGGERED, 36) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UP_INTEGRITY_PROTECTION_NOT_POSSIBLE, 37) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UP_CONFIDENTIALITY_PROTECTION_NOT_POSSIBLE, 38) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_SLICE_NOT_SUPPORTED, 39) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UE_IN_RRC_INACTIVE_STATE_NOT_REACHABLE, 40) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_REDIRECTION, 41) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RESOURCES_NOT_AVAILABLE_FOR_THE_SLICE, 42) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_UE_MAX_INTEGRITY_PROTECTED_DATA_RATE_REASON, 43) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_CN_DETECTED_MOBILITY, 44) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_N26_INTERFACE_NOT_AVAILABLE, 45) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_PRE_EMPTION, 46) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_LOCATION_REPORTING_REFERENCE_ID_INSTANCES, 47) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_RSN_NOT_AVAILABLE_FOR_THE_UP, 48) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_NPN_ACCESS_DENIED, 49) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_CAG_ONLY_ACCESS_DENIED, 50) \
CAUSE_DEF(NGAP_CAUSE_RADIO_NETWORK_INSUFFICIENT_UE_CAPABILITIES, 51)
/**
* NGAP protocol cause values as per 9.3.1.2 `Cause` section in 3GPP TS 38.413.
*/
typedef enum ngap_cause_protocol_e {
NGAP_CAUSE_PROTOCOL_TRANSFER_SYNTAX_ERROR,
NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT,
NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE,
NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE,
NGAP_CAUSE_PROTOCOL_SEMANTIC_ERROR,
NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_FCM,
NGAP_CAUSE_PROTOCOL_UNSPECIFIED
} ngap_cause_protocol_t;
typedef enum { FOREACH_CAUSE_RADIO_NETWORK(TO_ENUM) } ngap_cause_radio_network_t;
/** NGAP protocol cause values (9.3.1.2 of 3GPP TS 38.413) */
#define FOREACH_CAUSE_PROTOCOL(CAUSE_DEF) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL_TRANSFER_SYNTAX_ERROR, 0) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT, 1) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE, 2) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE, 3) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL_SEMANTIC_ERROR, 4) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_FCM, 5) \
CAUSE_DEF(NGAP_CAUSE_PROTOCOL_UNSPECIFIED, 6)
typedef enum { FOREACH_CAUSE_PROTOCOL(TO_ENUM) } ngap_cause_protocol_t;
typedef struct pdusession_failed_s {
/* Unique pdusession_id for the UE. */
@@ -352,7 +357,11 @@ typedef struct {
} ngap_plmn_t;
//-------------------------------------------------------------------------------------------//
// gNB application layer -> NGAP messages
/** @brief NG SETUP REQUEST message (9.2.6.1 of 3GPP TS 38.413)
* This message is sent by the NG-RAN node to transfer application layer information
* for an NG-C interface instance.
* Direction: NG-RAN node -> AMF */
typedef struct ngap_register_gnb_req_s {
/* Unique gNB_id to identify the gNB within EPC.
* For macro gNB ids this field should be 20 bits long.
@@ -790,29 +799,6 @@ typedef struct ngap_initial_context_setup_req_s {
byte_array_t nas_pdu;
} ngap_initial_context_setup_req_t;
typedef struct ngap_paging_ind_s {
/* UE paging identity */
ngap_ue_paging_identity_t ue_paging_identity;
/* Indicates origin of paging */
ngap_cn_domain_t cn_domain;
/* PLMN_identity in TAI of Paging*/
plmn_id_t plmn_identity[NGAP_MAX_NO_TAI_PAGING];
/* TAC in TAIList of Paging*/
int16_t tac[NGAP_MAX_NO_TAI_PAGING];
/* size of TAIList*/
int16_t tai_size;
/* Optional fields */
ngap_paging_drx_t paging_drx;
ngap_paging_priority_t paging_priority;
} ngap_paging_ind_t;
typedef struct ngap_pdusession_setup_req_s {
/* UE id for initial connection to NGAP */
uint32_t gNB_ue_ngap_id;
@@ -939,6 +925,45 @@ typedef struct ngap_pdusession_release_resp_s {
pdusession_release_t pdusession_release[NGAP_MAX_PDU_SESSION];
} ngap_pdusession_release_resp_t;
/** NG PAGING PROCEDURES (9.2.4. of 3GPP TS 38.413) */
typedef struct {
plmn_id_t plmn;
uint16_t tac;
} nr_tai_t;
typedef struct ngap_ue_paging_identity_s {
fiveg_s_tmsi_t s_tmsi;
} ngap_ue_paging_identity_t;
/** 9.3.1.72 Paging Attempt Information (3GPP TS 38.413) */
typedef struct {
/* Paging Attempt Count */
uint8_t paging_attempt_count;
/* Intended Number of Paging Attempts */
uint8_t intended_paging_attempts;
} ngap_paging_attempt_info_t;
/** 9.2.4.1 3GPP TS 38.413 */
typedef struct {
/* UE paging identity */
ngap_ue_paging_identity_t ue_paging_identity;
/* TAI List for Paging */
nr_tai_t tai_list[NGAP_MAX_NO_TAI_PAGING];
int16_t n_tai;
/* Optional fields */
ngap_paging_drx_t *paging_drx;
ngap_paging_priority_t *paging_priority;
/* UE Radio Capability for Paging (optional) */
byte_array_t *ue_radio_capability;
/* Paging Origin (optional) */
ngap_paging_origin_t *origin;
/* Assistance Data for Paging (optional) */
ngap_paging_attempt_info_t *paging_attempt_info;
} ngap_paging_ind_t;
/** 9.2.3.14 Uplink RAN Status Transfer (3GPP TS 38.413)
* COUNT value used for both UL and DL PDCP SN + HFN (12-bit or 18-bit SN) */
+1 -5
View File
@@ -4,13 +4,9 @@ add_subdirectory(lib)
add_library(e1ap e1ap.c e1ap_common.c)
target_link_libraries(e1ap
PUBLIC asn1_e1ap e1ap_lib
PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap UTIL e1_if)
PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap UTIL e1_if GTPV1U)
target_include_directories(e1ap PUBLIC ${CMAKE_CURRENT_DIR})
if(ENABLE_TESTS)
add_subdirectory(tests)
endif()
if(ENABLE_TESTS)
target_compile_definitions(e1ap PRIVATE E1AP_LOG_ERRORS)
endif()
+4
View File
@@ -9,3 +9,7 @@ target_include_directories(e1ap_lib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
if(ENABLE_TESTS)
target_compile_definitions(e1ap_lib PRIVATE ENABLE_TESTS)
endif()
+208 -207
View File
@@ -96,12 +96,12 @@ static bool e1_decode_security_info(security_information_t *out, const E1AP_Secu
// User Plane Security Keys (M) (9.3.1.32)
// Encryption Key (M)
_E1_EQ_CHECK_INT((int)in->uPSecuritykey.encryptionKey.size, E1AP_SECURITY_KEY_SIZE);
_EQ_CHECK_INT((int)in->uPSecuritykey.encryptionKey.size, E1AP_SECURITY_KEY_SIZE);
memcpy(out->encryptionKey, in->uPSecuritykey.encryptionKey.buf, in->uPSecuritykey.encryptionKey.size);
// Integrity Protection Key (O)
if (in->uPSecuritykey.integrityProtectionKey) {
E1AP_IntegrityProtectionKey_t *ipKey = in->uPSecuritykey.integrityProtectionKey;
_E1_EQ_CHECK_INT((int)ipKey->size, E1AP_SECURITY_KEY_SIZE);
_EQ_CHECK_INT((int)ipKey->size, E1AP_SECURITY_KEY_SIZE);
memcpy(out->integrityProtectionKey, ipKey->buf, E1AP_SECURITY_KEY_SIZE);
} else {
memset(out->integrityProtectionKey, 0, E1AP_SECURITY_KEY_SIZE);
@@ -132,7 +132,7 @@ static bool e1_decode_up_tnl_info(UP_TL_information_t *out, const E1AP_UP_TNL_In
// GTP Tunnel
struct E1AP_GTPTunnel *gTPTunnel = in->choice.gTPTunnel;
AssertFatal(gTPTunnel != NULL, "item->nG_UL_UP_TNL_Information.choice.gTPTunnel is a mandatory IE");
_E1_EQ_CHECK_INT(in->present, E1AP_UP_TNL_Information_PR_gTPTunnel);
_EQ_CHECK_INT(in->present, E1AP_UP_TNL_Information_PR_gTPTunnel);
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gTPTunnel->transportLayerAddress, out->tlAddress);
// GTP-TEID
OCTET_STRING_TO_INT32(&gTPTunnel->gTP_TEID, out->teId);
@@ -178,12 +178,12 @@ static bool e1_decode_pdcp_config(bearer_context_pdcp_config_t *out, const E1AP_
*/
static bool eq_pdcp_config(const bearer_context_pdcp_config_t *a, const bearer_context_pdcp_config_t *b)
{
_E1_EQ_CHECK_LONG(a->pDCP_SN_Size_UL, b->pDCP_SN_Size_UL);
_E1_EQ_CHECK_LONG(a->pDCP_SN_Size_DL, b->pDCP_SN_Size_DL);
_E1_EQ_CHECK_LONG(a->rLC_Mode, b->rLC_Mode);
_E1_EQ_CHECK_LONG(a->reorderingTimer, b->reorderingTimer);
_E1_EQ_CHECK_LONG(a->discardTimer, b->discardTimer);
_E1_EQ_CHECK_INT(a->pDCP_Reestablishment, b->pDCP_Reestablishment);
_EQ_CHECK_LONG(a->pDCP_SN_Size_UL, b->pDCP_SN_Size_UL);
_EQ_CHECK_LONG(a->pDCP_SN_Size_DL, b->pDCP_SN_Size_DL);
_EQ_CHECK_LONG(a->rLC_Mode, b->rLC_Mode);
_EQ_CHECK_LONG(a->reorderingTimer, b->reorderingTimer);
_EQ_CHECK_LONG(a->discardTimer, b->discardTimer);
_EQ_CHECK_INT(a->pDCP_Reestablishment, b->pDCP_Reestablishment);
return true;
}
@@ -211,9 +211,9 @@ static bool e1_decode_sdap_config(bearer_context_sdap_config_t *out, const E1AP_
*/
static bool eq_sdap_config(const bearer_context_sdap_config_t *a, const bearer_context_sdap_config_t *b)
{
_E1_EQ_CHECK_LONG(a->defaultDRB, b->defaultDRB);
_E1_EQ_CHECK_INT(a->sDAP_Header_UL, b->sDAP_Header_UL);
_E1_EQ_CHECK_INT(a->sDAP_Header_DL, b->sDAP_Header_DL);
_EQ_CHECK_LONG(a->defaultDRB, b->defaultDRB);
_EQ_CHECK_INT(a->sDAP_Header_UL, b->sDAP_Header_UL);
_EQ_CHECK_INT(a->sDAP_Header_DL, b->sDAP_Header_DL);
return true;
}
@@ -285,22 +285,22 @@ bool e1_decode_qos_flow_to_setup(qos_flow_to_setup_t *out, const E1AP_QoS_Flow_Q
*/
static bool eq_qos_flow(const qos_flow_to_setup_t *a, const qos_flow_to_setup_t *b)
{
_E1_EQ_CHECK_LONG(a->qfi, b->qfi);
_EQ_CHECK_LONG(a->qfi, b->qfi);
const ngran_allocation_retention_priority_t *arp_a = &a->qos_params.alloc_reten_priority;
const ngran_allocation_retention_priority_t *arp_b = &b->qos_params.alloc_reten_priority;
_E1_EQ_CHECK_INT(arp_a->preemption_capability, arp_b->preemption_capability);
_E1_EQ_CHECK_INT(arp_a->preemption_vulnerability, arp_b->preemption_vulnerability);
_E1_EQ_CHECK_INT(arp_a->priority_level, arp_b->priority_level);
_EQ_CHECK_INT(arp_a->preemption_capability, arp_b->preemption_capability);
_EQ_CHECK_INT(arp_a->preemption_vulnerability, arp_b->preemption_vulnerability);
_EQ_CHECK_INT(arp_a->priority_level, arp_b->priority_level);
const qos_characteristics_t *qos_a = &a->qos_params.qos_characteristics;
const qos_characteristics_t *qos_b = &b->qos_params.qos_characteristics;
_E1_EQ_CHECK_INT(qos_a->qos_type, qos_b->qos_type);
_E1_EQ_CHECK_INT(qos_a->dynamic.fiveqi, qos_b->dynamic.fiveqi);
_E1_EQ_CHECK_INT(qos_a->dynamic.packet_delay_budget, qos_b->dynamic.packet_delay_budget);
_E1_EQ_CHECK_INT(qos_a->dynamic.packet_error_rate.per_exponent, qos_b->dynamic.packet_error_rate.per_exponent);
_E1_EQ_CHECK_INT(qos_a->dynamic.packet_error_rate.per_scalar, qos_b->dynamic.packet_error_rate.per_scalar);
_E1_EQ_CHECK_INT(qos_a->dynamic.qos_priority_level, qos_b->dynamic.qos_priority_level);
_E1_EQ_CHECK_INT(qos_a->non_dynamic.fiveqi, qos_b->non_dynamic.fiveqi);
_E1_EQ_CHECK_INT(qos_a->non_dynamic.qos_priority_level, qos_b->non_dynamic.qos_priority_level);
_EQ_CHECK_INT(qos_a->qos_type, qos_b->qos_type);
_EQ_CHECK_INT(qos_a->dynamic.fiveqi, qos_b->dynamic.fiveqi);
_EQ_CHECK_INT(qos_a->dynamic.packet_delay_budget, qos_b->dynamic.packet_delay_budget);
_EQ_CHECK_INT(qos_a->dynamic.packet_error_rate.per_exponent, qos_b->dynamic.packet_error_rate.per_exponent);
_EQ_CHECK_INT(qos_a->dynamic.packet_error_rate.per_scalar, qos_b->dynamic.packet_error_rate.per_scalar);
_EQ_CHECK_INT(qos_a->dynamic.qos_priority_level, qos_b->dynamic.qos_priority_level);
_EQ_CHECK_INT(qos_a->non_dynamic.fiveqi, qos_b->non_dynamic.fiveqi);
_EQ_CHECK_INT(qos_a->non_dynamic.qos_priority_level, qos_b->non_dynamic.qos_priority_level);
return true;
}
@@ -386,10 +386,10 @@ static e1_pdcp_status_info_t decode_pdcp_status_info(const E1AP_PDCP_SN_Status_I
static bool eq_pdcp_info(const e1_pdcp_status_info_t *a, const e1_pdcp_status_info_t *b)
{
_E1_EQ_CHECK_INT(a->dl_count.hfn, b->dl_count.hfn);
_E1_EQ_CHECK_INT(a->dl_count.sn, b->dl_count.sn);
_E1_EQ_CHECK_INT(a->ul_count.hfn, b->ul_count.hfn);
_E1_EQ_CHECK_INT(a->ul_count.sn, b->ul_count.sn);
_EQ_CHECK_INT(a->dl_count.hfn, b->dl_count.hfn);
_EQ_CHECK_INT(a->dl_count.sn, b->dl_count.sn);
_EQ_CHECK_INT(a->ul_count.hfn, b->ul_count.hfn);
_EQ_CHECK_INT(a->ul_count.sn, b->ul_count.sn);
return true;
}
@@ -398,12 +398,12 @@ static bool eq_pdcp_info(const e1_pdcp_status_info_t *a, const e1_pdcp_status_in
*/
static bool eq_drb_to_setup(const DRB_nGRAN_to_setup_t *a, const DRB_nGRAN_to_setup_t *b)
{
_E1_EQ_CHECK_LONG(a->id, b->id);
_E1_EQ_CHECK_INT(a->numCellGroups, b->numCellGroups);
_EQ_CHECK_LONG(a->id, b->id);
_EQ_CHECK_INT(a->numCellGroups, b->numCellGroups);
for (int i = 0; i < a->numCellGroups; i++) {
_E1_EQ_CHECK_INT(a->cellGroupList[i], b->cellGroupList[i]);
_EQ_CHECK_INT(a->cellGroupList[i], b->cellGroupList[i]);
}
_E1_EQ_CHECK_INT(a->numQosFlow2Setup, b->numQosFlow2Setup);
_EQ_CHECK_INT(a->numQosFlow2Setup, b->numQosFlow2Setup);
for (int i = 0; i < a->numQosFlow2Setup; i++) {
if (!eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]))
return false;
@@ -474,13 +474,13 @@ static bool e1_decode_pdu_session_to_setup_item(pdu_session_to_setup_t *out, E1A
PRINT_ERROR("Missing mandatory IE item->nG_UL_UP_TNL_Information.choice.gTPTunnel\n");
return false;
}
_E1_EQ_CHECK_INT(item->nG_UL_UP_TNL_Information.present, E1AP_UP_TNL_Information_PR_gTPTunnel);
_EQ_CHECK_INT(item->nG_UL_UP_TNL_Information.present, E1AP_UP_TNL_Information_PR_gTPTunnel);
CHECK_E1AP_DEC(e1_decode_up_tnl_info(&out->UP_TL_information, &item->nG_UL_UP_TNL_Information));
/* DRB To Setup List ( > 1 item ) */
E1AP_DRB_To_Setup_List_NG_RAN_t *drb2SetupList = &item->dRB_To_Setup_List_NG_RAN;
_E1_EQ_CHECK_GENERIC(drb2SetupList->list.count > 0, "%d", drb2SetupList->list.count, 0);
EQ_CHECK_GENERIC(drb2SetupList->list.count > 0, "%d", drb2SetupList->list.count, 0);
out->numDRB2Setup = drb2SetupList->list.count;
_E1_EQ_CHECK_INT(out->numDRB2Setup, 1); // can only handle one DRB per PDU session
_EQ_CHECK_INT(out->numDRB2Setup, 1); // can only handle one DRB per PDU session
for (int j = 0; j < drb2SetupList->list.count; j++) {
DRB_nGRAN_to_setup_t *drb = out->DRBnGRanList + j;
E1AP_DRB_To_Setup_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j];
@@ -492,7 +492,7 @@ static bool e1_decode_pdu_session_to_setup_item(pdu_session_to_setup_t *out, E1A
CHECK_E1AP_DEC(e1_decode_pdcp_config(&drb->pdcp_config, &drb2Setup->pDCP_Configuration));
// Cell Group Information (M)
E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information;
_E1_EQ_CHECK_GENERIC(cellGroupList->list.count > 0, "%d", cellGroupList->list.count, 0);
EQ_CHECK_GENERIC(cellGroupList->list.count > 0, "%d", cellGroupList->list.count, 0);
drb->numCellGroups = cellGroupList->list.count;
for (int k = 0; k < cellGroupList->list.count; k++) {
E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k];
@@ -542,8 +542,8 @@ void free_pdu_session_to_setup_item(const pdu_session_to_setup_t *msg)
/** @brief Equality check for UP Transport Layer Information (3GPP TS 38.463 9.3.2.1)*/
static bool eq_up_tl_info(const UP_TL_information_t *a, const UP_TL_information_t *b)
{
_E1_EQ_CHECK_INT(a->tlAddress, b->tlAddress);
_E1_EQ_CHECK_INT(a->teId, b->teId);
_EQ_CHECK_INT(a->tlAddress, b->tlAddress);
_EQ_CHECK_INT(a->teId, b->teId);
return true;
}
@@ -552,17 +552,17 @@ static bool eq_up_tl_info(const UP_TL_information_t *a, const UP_TL_information_
*/
static bool eq_pdu_session_item(const pdu_session_to_setup_t *a, const pdu_session_to_setup_t *b)
{
_E1_EQ_CHECK_LONG(a->sessionId, b->sessionId);
_E1_EQ_CHECK_LONG(a->sessionType, b->sessionType);
_EQ_CHECK_LONG(a->sessionId, b->sessionId);
_EQ_CHECK_LONG(a->sessionType, b->sessionType);
eq_up_tl_info(&a->UP_TL_information, &b->UP_TL_information);
_E1_EQ_CHECK_INT(a->numDRB2Setup, b->numDRB2Setup);
_EQ_CHECK_INT(a->numDRB2Setup, b->numDRB2Setup);
for (int i = 0; i < a->numDRB2Setup; i++)
if (!eq_drb_to_setup(&a->DRBnGRanList[i], &b->DRBnGRanList[i]))
return false;
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, inactivityTimer);
_EQ_CHECK_OPTIONAL_PTR(a, b, inactivityTimer);
if (a->inactivityTimer && b->inactivityTimer)
_E1_EQ_CHECK_INT(*a->inactivityTimer, *b->inactivityTimer);
_E1_EQ_CHECK_OPTIONAL_IE(a, b, dlAggregateMaxBitRate, _E1_EQ_CHECK_LONG);
_EQ_CHECK_INT(*a->inactivityTimer, *b->inactivityTimer);
_EQ_CHECK_OPTIONAL_IE(a, b, dlAggregateMaxBitRate, _EQ_CHECK_LONG);
return true;
}
@@ -660,9 +660,9 @@ bool decode_E1_bearer_context_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_bea
DevAssert(pdu != NULL);
// Check message type
_E1_EQ_CHECK_INT(pdu->present,E1AP_E1AP_PDU_PR_initiatingMessage);
_E1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
_E1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest);
const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
E1AP_BearerContextSetupRequestIEs_t *ie;
@@ -681,22 +681,22 @@ bool decode_E1_bearer_context_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_bea
AssertFatal(ie != NULL, "in->protocolIEs.list.array[i] shall not be null");
switch (ie->id) {
case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
out->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
break;
case E1AP_ProtocolIE_ID_id_SecurityInformation:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation);
CHECK_E1AP_DEC(e1_decode_security_info(&out->secInfo, &ie->value.choice.SecurityInformation));
break;
case E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_BitRate);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_BitRate);
asn_INTEGER2long(&ie->value.choice.BitRate, &out->ueDlAggMaxBitRate);
break;
case E1AP_ProtocolIE_ID_id_Serving_PLMN:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity);
PLMNID_TO_MCC_MNC(&ie->value.choice.PLMN_Identity,
out->servingPLMNid.mcc,
out->servingPLMNid.mnc,
@@ -704,7 +704,7 @@ bool decode_E1_bearer_context_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_bea
break;
case E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest);
E1AP_System_BearerContextSetupRequest_t *System_BearerContextSetupRequest =
&ie->value.choice.System_BearerContextSetupRequest;
switch (System_BearerContextSetupRequest->present) {
@@ -717,8 +717,8 @@ bool decode_E1_bearer_context_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_bea
break;
case E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest:
// Handle nG-RAN Bearer Context Setup Request
_E1_EQ_CHECK_INT(System_BearerContextSetupRequest->present,
E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest);
_EQ_CHECK_INT(System_BearerContextSetupRequest->present,
E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest);
AssertFatal(System_BearerContextSetupRequest->choice.nG_RAN_BearerContextSetupRequest != NULL,
"System_BearerContextSetupRequest->choice.nG_RAN_BearerContextSetupRequest shall not be null");
break;
@@ -731,10 +731,9 @@ bool decode_E1_bearer_context_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_bea
(E1AP_ProtocolIE_Container_4932P19_t *)System_BearerContextSetupRequest->choice.nG_RAN_BearerContextSetupRequest;
E1AP_NG_RAN_BearerContextSetupRequest_t *msgNGRAN = msgNGRAN_list->list.array[0];
// NG-RAN
_E1_EQ_CHECK_INT(msgNGRAN_list->list.count, 1); // only one RAN is expected
_E1_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List);
_E1_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List);
_EQ_CHECK_INT(msgNGRAN_list->list.count, 1); // only one RAN is expected
_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List);
_EQ_CHECK_INT(msgNGRAN->value.present, E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List);
// PDU Session Resource To Setup List (9.3.3.2 of 3GPP TS 38.463)
E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2SetupList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
out->numPDUSessions = pdu2SetupList->list.count;
@@ -791,18 +790,18 @@ e1ap_bearer_setup_req_t cp_bearer_context_setup_request(const e1ap_bearer_setup_
bool eq_bearer_context_setup_request(const e1ap_bearer_setup_req_t *a, const e1ap_bearer_setup_req_t *b)
{
// Primitive data types
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_LONG(a->secInfo.cipheringAlgorithm, b->secInfo.cipheringAlgorithm);
_E1_EQ_CHECK_LONG(a->secInfo.integrityProtectionAlgorithm, b->secInfo.integrityProtectionAlgorithm);
_E1_EQ_CHECK_LONG(a->ueDlAggMaxBitRate, b->ueDlAggMaxBitRate);
_E1_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_LONG(a->secInfo.cipheringAlgorithm, b->secInfo.cipheringAlgorithm);
_EQ_CHECK_LONG(a->secInfo.integrityProtectionAlgorithm, b->secInfo.integrityProtectionAlgorithm);
_EQ_CHECK_LONG(a->ueDlAggMaxBitRate, b->ueDlAggMaxBitRate);
_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
// PLMN
_E1_EQ_CHECK_INT(a->servingPLMNid.mcc, b->servingPLMNid.mcc);
_E1_EQ_CHECK_INT(a->servingPLMNid.mnc, b->servingPLMNid.mnc);
_E1_EQ_CHECK_INT(a->servingPLMNid.mnc_digit_length, b->servingPLMNid.mnc_digit_length);
_EQ_CHECK_INT(a->servingPLMNid.mcc, b->servingPLMNid.mcc);
_EQ_CHECK_INT(a->servingPLMNid.mnc, b->servingPLMNid.mnc);
_EQ_CHECK_INT(a->servingPLMNid.mnc_digit_length, b->servingPLMNid.mnc_digit_length);
// Security Keys
_E1_EQ_CHECK_STR(a->secInfo.encryptionKey, b->secInfo.encryptionKey);
_E1_EQ_CHECK_STR(a->secInfo.integrityProtectionKey, b->secInfo.integrityProtectionKey);
_EQ_CHECK_STR(a->secInfo.encryptionKey, b->secInfo.encryptionKey);
_EQ_CHECK_STR(a->secInfo.integrityProtectionKey, b->secInfo.integrityProtectionKey);
// PDU Sessions
if (a->numPDUSessions != b->numPDUSessions)
return false;
@@ -810,10 +809,10 @@ bool eq_bearer_context_setup_request(const e1ap_bearer_setup_req_t *a, const e1a
if (!eq_pdu_session_item(&a->pduSession[i], &b->pduSession[i]))
return false;
// Check optional IEs
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, inactivityTimerUE);
_EQ_CHECK_OPTIONAL_PTR(a, b, inactivityTimerUE);
if (a->inactivityTimerUE && b->inactivityTimerUE)
_E1_EQ_CHECK_INT(*a->inactivityTimerUE, *b->inactivityTimerUE);
_E1_EQ_CHECK_OPTIONAL_IE(a, b, ueDlMaxIPBitRate, _E1_EQ_CHECK_LONG);
_EQ_CHECK_INT(*a->inactivityTimerUE, *b->inactivityTimerUE);
_EQ_CHECK_OPTIONAL_IE(a, b, ueDlMaxIPBitRate, _EQ_CHECK_LONG);
return true;
}
@@ -969,9 +968,9 @@ E1AP_E1AP_PDU_t *encode_E1_bearer_context_setup_response(const e1ap_bearer_setup
bool decode_E1_bearer_context_setup_response(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_resp_t *out)
{
// Check message type
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
_E1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
_E1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse);
const E1AP_BearerContextSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse;
E1AP_BearerContextSetupResponseIEs_t *ie;
@@ -985,27 +984,27 @@ bool decode_E1_bearer_context_setup_response(const E1AP_E1AP_PDU_t *pdu, e1ap_be
switch (ie->id) {
case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
out->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
break;
case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
out->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
break;
case E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse);
switch (ie->value.choice.System_BearerContextSetupResponse.present) {
case E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse: {
E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list =
(E1AP_ProtocolIE_Container_4932P22_t *)
ie->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse;
_E1_EQ_CHECK_INT(msgNGRAN_list->list.count, 1);
_EQ_CHECK_INT(msgNGRAN_list->list.count, 1);
E1AP_NG_RAN_BearerContextSetupResponse_t *msgNGRAN = msgNGRAN_list->list.array[0];
_E1_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List);
_E1_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List);
_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List);
_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List);
E1AP_PDU_Session_Resource_Setup_List_t *pduSetupList = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List;
out->numPDUSessions = pduSetupList->list.count;
for (int i = 0; i < pduSetupList->list.count; i++) {
@@ -1069,34 +1068,34 @@ e1ap_bearer_setup_resp_t cp_bearer_context_setup_response(const e1ap_bearer_setu
bool eq_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *a, const e1ap_bearer_setup_resp_t *b)
{
// Check basic members
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_E1_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
// Check PDU Sessions Setup
if (a->numPDUSessions != b->numPDUSessions)
return false;
for (int i = 0; i < a->numPDUSessions; i++) {
const pdu_session_setup_t *ps_a = &a->pduSession[i];
const pdu_session_setup_t *ps_b = &b->pduSession[i];
_E1_EQ_CHECK_LONG(ps_a->id, ps_b->id);
_EQ_CHECK_LONG(ps_a->id, ps_b->id);
eq_up_tl_info(&ps_a->tl_info, &ps_b->tl_info);
_E1_EQ_CHECK_INT(ps_a->numDRBSetup, ps_b->numDRBSetup);
_E1_EQ_CHECK_INT(ps_a->numDRBFailed, ps_b->numDRBFailed);
_EQ_CHECK_INT(ps_a->numDRBSetup, ps_b->numDRBSetup);
_EQ_CHECK_INT(ps_a->numDRBFailed, ps_b->numDRBFailed);
// Check DRB Setup
for (int j = 0; j < ps_a->numDRBSetup; j++) {
const DRB_nGRAN_setup_t *drb_a = &ps_a->DRBnGRanList[j];
const DRB_nGRAN_setup_t *drb_b = &ps_b->DRBnGRanList[j];
_E1_EQ_CHECK_LONG(drb_a->id, drb_b->id);
_E1_EQ_CHECK_INT(drb_a->numUpParam, drb_b->numUpParam);
_E1_EQ_CHECK_INT(drb_a->numQosFlowSetup, drb_b->numQosFlowSetup);
_EQ_CHECK_LONG(drb_a->id, drb_b->id);
_EQ_CHECK_INT(drb_a->numUpParam, drb_b->numUpParam);
_EQ_CHECK_INT(drb_a->numQosFlowSetup, drb_b->numQosFlowSetup);
}
// Check DRB Failed
for (int j = 0; j < ps_a->numDRBFailed; j++) {
const DRB_nGRAN_failed_t *drbf_a = &ps_a->DRBnGRanFailedList[j];
const DRB_nGRAN_failed_t *drbf_b = &ps_b->DRBnGRanFailedList[j];
_E1_EQ_CHECK_LONG(drbf_a->id, drbf_b->id);
_E1_EQ_CHECK_INT(drbf_a->cause.type, drbf_b->cause.type);
_E1_EQ_CHECK_INT(drbf_a->cause.value, drbf_b->cause.value);
_EQ_CHECK_LONG(drbf_a->id, drbf_b->id);
_EQ_CHECK_INT(drbf_a->cause.type, drbf_b->cause.type);
_EQ_CHECK_INT(drbf_a->cause.value, drbf_b->cause.value);
}
}
return true;
@@ -1163,10 +1162,10 @@ E1AP_E1AP_PDU_t *encode_E1_bearer_context_setup_failure(const e1ap_bearer_contex
bool decode_E1_bearer_context_setup_failure(e1ap_bearer_context_setup_failure_t *out, const E1AP_E1AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_unsuccessfulOutcome);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_unsuccessfulOutcome);
E1AP_UnsuccessfulOutcome_t *type = pdu->choice.unsuccessfulOutcome;
_E1_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
_E1_EQ_CHECK_INT(type->value.present, E1AP_UnsuccessfulOutcome__value_PR_BearerContextSetupFailure);
_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
_EQ_CHECK_INT(type->value.present, E1AP_UnsuccessfulOutcome__value_PR_BearerContextSetupFailure);
const E1AP_BearerContextSetupFailure_t *in = &type->value.choice.BearerContextSetupFailure;
// Check mandatory IEs first
@@ -1210,10 +1209,10 @@ e1ap_bearer_context_setup_failure_t cp_bearer_context_setup_failure(const e1ap_b
/** @brief Bearer Context Setup Failure equality check */
bool eq_bearer_context_setup_failure(const e1ap_bearer_context_setup_failure_t *a, const e1ap_bearer_context_setup_failure_t *b)
{
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_OPTIONAL_IE(a, b, gNB_cu_up_ue_id, _E1_EQ_CHECK_INT);
_E1_EQ_CHECK_INT(a->cause.type, b->cause.type);
_E1_EQ_CHECK_INT(a->cause.value, b->cause.value);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_OPTIONAL_IE(a, b, gNB_cu_up_ue_id, _EQ_CHECK_INT);
_EQ_CHECK_INT(a->cause.type, b->cause.type);
_EQ_CHECK_INT(a->cause.value, b->cause.value);
return true;
}
@@ -1271,10 +1270,10 @@ E1AP_E1AP_PDU_t *encode_e1_bearer_context_release_command(const e1ap_bearer_rele
bool decode_e1_bearer_context_release_command(e1ap_bearer_release_cmd_t *out, const E1AP_E1AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_initiatingMessage);
E1AP_InitiatingMessage_t *type = pdu->choice.initiatingMessage;
_E1_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextRelease);
_E1_EQ_CHECK_INT(type->value.present, E1AP_InitiatingMessage__value_PR_BearerContextReleaseCommand);
_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextRelease);
_EQ_CHECK_INT(type->value.present, E1AP_InitiatingMessage__value_PR_BearerContextReleaseCommand);
const E1AP_BearerContextReleaseCommand_t *in = &type->value.choice.BearerContextReleaseCommand;
// Check mandatory IEs
@@ -1297,7 +1296,7 @@ bool decode_e1_bearer_context_release_command(e1ap_bearer_release_cmd_t *out, co
out->cause = e1_decode_cause_ie(&ie->value.choice.Cause);
break;
default:
PRINT_ERROR("%s decoding failure: IE %ld is invalid\n", __func__, ie->id)
PRINT_ERROR("%s decoding failure: IE %ld is invalid\n", __func__, ie->id);
return false;
break;
}
@@ -1308,10 +1307,10 @@ bool decode_e1_bearer_context_release_command(e1ap_bearer_release_cmd_t *out, co
/** @brief Bearer Context Release Command equality check */
bool eq_bearer_context_release_command(const e1ap_bearer_release_cmd_t *a, const e1ap_bearer_release_cmd_t *b)
{
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_E1_EQ_CHECK_INT(a->cause.type, b->cause.type);
_E1_EQ_CHECK_INT(a->cause.value, b->cause.value);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_EQ_CHECK_INT(a->cause.type, b->cause.type);
_EQ_CHECK_INT(a->cause.value, b->cause.value);
return true;
}
@@ -1366,10 +1365,10 @@ E1AP_E1AP_PDU_t *encode_e1_bearer_context_release_complete(const e1ap_bearer_rel
bool decode_e1_bearer_context_release_complete(e1ap_bearer_release_cplt_t *out, const E1AP_E1AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
E1AP_SuccessfulOutcome_t *type = pdu->choice.successfulOutcome;
_E1_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextRelease);
_E1_EQ_CHECK_INT(type->value.present, E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete);
_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextRelease);
_EQ_CHECK_INT(type->value.present, E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete);
const E1AP_BearerContextReleaseComplete_t *in = &type->value.choice.BearerContextReleaseComplete;
// Check mandatory IEs
@@ -1388,7 +1387,7 @@ bool decode_e1_bearer_context_release_complete(e1ap_bearer_release_cplt_t *out,
out->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
break;
default:
PRINT_ERROR("%s decoding failure: IE %ld is not handled or invalid\n", __func__, ie->id)
PRINT_ERROR("%s decoding failure: IE %ld is not handled or invalid\n", __func__, ie->id);
break;
}
}
@@ -1398,8 +1397,8 @@ bool decode_e1_bearer_context_release_complete(e1ap_bearer_release_cplt_t *out,
/** @brief Bearer Context Release Complete equality check */
bool eq_bearer_context_release_complete(const e1ap_bearer_release_cplt_t *a, const e1ap_bearer_release_cplt_t *b)
{
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
return true;
}
@@ -1669,13 +1668,13 @@ static bool e1_decode_pdu_session_to_setup_mod_item(pdu_session_to_setup_t *out,
// Security Indication (M)
CHECK_E1AP_DEC(e1_decode_security_indication(&out->securityIndication, &item->securityIndication));
/* NG UL UP Transport Layer Information (M) */
_E1_EQ_CHECK_INT(item->nG_UL_UP_TNL_Information.present, E1AP_UP_TNL_Information_PR_gTPTunnel);
_EQ_CHECK_INT(item->nG_UL_UP_TNL_Information.present, E1AP_UP_TNL_Information_PR_gTPTunnel);
CHECK_E1AP_DEC(e1_decode_up_tnl_info(&out->UP_TL_information, &item->nG_UL_UP_TNL_Information));
/* DRB To Setup List ( > 1 item ) */
const E1AP_DRB_To_Setup_Mod_List_NG_RAN_t *drb2SetupList = &item->dRB_To_Setup_Mod_List_NG_RAN;
_E1_EQ_CHECK_GENERIC(drb2SetupList->list.count > 0, "%d", drb2SetupList->list.count, 0);
EQ_CHECK_GENERIC(drb2SetupList->list.count > 0, "%d", drb2SetupList->list.count, 0);
out->numDRB2Setup = drb2SetupList->list.count;
_E1_EQ_CHECK_INT(out->numDRB2Setup, 1); // can only handle one DRB per PDU session
_EQ_CHECK_INT(out->numDRB2Setup, 1); // can only handle one DRB per PDU session
for (int j = 0; j < drb2SetupList->list.count; j++) {
DRB_nGRAN_to_setup_t *drb = out->DRBnGRanList + j;
const E1AP_DRB_To_Setup_Mod_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j];
@@ -1687,7 +1686,7 @@ static bool e1_decode_pdu_session_to_setup_mod_item(pdu_session_to_setup_t *out,
CHECK_E1AP_DEC(e1_decode_pdcp_config(&drb->pdcp_config, &drb2Setup->pDCP_Configuration));
// Cell Group Information (M)
const E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information;
_E1_EQ_CHECK_GENERIC(cellGroupList->list.count > 0, "%d", cellGroupList->list.count, 0);
EQ_CHECK_GENERIC(cellGroupList->list.count > 0, "%d", cellGroupList->list.count, 0);
drb->numCellGroups = cellGroupList->list.count;
for (int k = 0; k < cellGroupList->list.count; k++) {
const E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k];
@@ -1774,10 +1773,10 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
{
DevAssert(pdu != NULL);
// Validate message type
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_initiatingMessage);
const E1AP_InitiatingMessage_t *im = pdu->choice.initiatingMessage;
_E1_EQ_CHECK_LONG(im->procedureCode, E1AP_ProcedureCode_id_bearerContextModification);
_E1_EQ_CHECK_INT(im->value.present, E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest);
_EQ_CHECK_LONG(im->procedureCode, E1AP_ProcedureCode_id_bearerContextModification);
_EQ_CHECK_INT(im->value.present, E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest);
const E1AP_BearerContextModificationRequest_t *in = &im->value.choice.BearerContextModificationRequest;
E1AP_BearerContextModificationRequestIEs_t *ie = NULL;
@@ -1794,12 +1793,12 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
switch (ie->id) {
case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
out->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
break;
case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
out->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
break;
@@ -1819,7 +1818,7 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
break;
case E1AP_ProtocolIE_ID_id_BearerContextStatusChange:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationRequestIEs__value_PR_BearerContextStatusChange);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationRequestIEs__value_PR_BearerContextStatusChange);
if (ie->value.choice.BearerContextStatusChange == E1AP_BearerContextStatusChange_suspend) {
out->bearerContextStatus = malloc_or_fail(sizeof(*out->bearerContextStatus));
*out->bearerContextStatus = BEARER_SUSPEND;
@@ -1836,8 +1835,8 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
break;
case E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest: {
_E1_EQ_CHECK_INT(ie->value.present,
E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest);
_EQ_CHECK_INT(ie->value.present,
E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest);
E1AP_System_BearerContextModificationRequest_t *modReq = &ie->value.choice.System_BearerContextModificationRequest;
DevAssert(ie->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest != NULL);
// System IE can contain either UTRAN or NG-RAN
@@ -1860,9 +1859,9 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
E1AP_NG_RAN_BearerContextModificationRequest_t *msgNGRAN = msgNGRAN_list->list.array[i];
switch (msgNGRAN->id) {
case E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_Mod_List:
_E1_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_Mod_List);
_E1_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Setup_Mod_List);
_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_Mod_List);
_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Setup_Mod_List);
E1AP_PDU_Session_Resource_To_Setup_Mod_List_t *setupList =
&msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_Mod_List;
// PDU Session Resource To Modify List
@@ -1876,8 +1875,8 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
break;
case E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List:
/* PDU Session Resource To Modify List (see 9.3.3.11 of TS 38.463) */
_E1_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List);
_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List);
E1AP_PDU_Session_Resource_To_Modify_List_t *modList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List;
out->numPDUSessionsMod = modList->list.count;
// Loop through all PDU sessions
@@ -1887,8 +1886,8 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
break;
case E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Remove_List:
/* PDU Session Resource To Remove List (see 9.3.3.12 of TS 38.463) */
_E1_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Remove_List);
_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Remove_List);
E1AP_PDU_Session_Resource_To_Remove_List_t *remList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Remove_List;
out->numPDUSessionsRem = remList->list.count;
// Loop through all PDU sessions to remove
@@ -1980,9 +1979,9 @@ e1ap_bearer_mod_req_t cp_bearer_context_mod_request(const e1ap_bearer_mod_req_t
/** @brief Equality check for Security Indication IE (3GPP TS 38.463 9.3.1.23) */
static bool eq_security_ind(security_indication_t *a, security_indication_t *b)
{
_E1_EQ_CHECK_INT(a->confidentialityProtectionIndication, b->confidentialityProtectionIndication);
_E1_EQ_CHECK_INT(a->integrityProtectionIndication, b->integrityProtectionIndication);
_E1_EQ_CHECK_LONG(a->maxIPrate, b->maxIPrate);
_EQ_CHECK_INT(a->confidentialityProtectionIndication, b->confidentialityProtectionIndication);
_EQ_CHECK_INT(a->integrityProtectionIndication, b->integrityProtectionIndication);
_EQ_CHECK_LONG(a->maxIPrate, b->maxIPrate);
return true;
}
@@ -1991,29 +1990,29 @@ static bool eq_security_ind(security_indication_t *a, security_indication_t *b)
*/
static bool eq_drb_to_mod(const DRB_nGRAN_to_mod_t *a, const DRB_nGRAN_to_mod_t *b)
{
_E1_EQ_CHECK_LONG(a->id, b->id);
_E1_EQ_CHECK_INT(a->numQosFlowsMod, b->numQosFlowsMod);
_EQ_CHECK_LONG(a->id, b->id);
_EQ_CHECK_INT(a->numQosFlowsMod, b->numQosFlowsMod);
for (int i = 0; i < a->numQosFlowsMod; i++) {
if (!eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]))
return false;
}
_E1_EQ_CHECK_INT(a->numDlUpParam, b->numDlUpParam);
_EQ_CHECK_INT(a->numDlUpParam, b->numDlUpParam);
for (int i = 0; i < a->numDlUpParam; i++) {
_E1_EQ_CHECK_INT(a->DlUpParamList[i].cell_group_id, b->DlUpParamList[i].cell_group_id);
_EQ_CHECK_INT(a->DlUpParamList[i].cell_group_id, b->DlUpParamList[i].cell_group_id);
if (!eq_up_tl_info(&a->DlUpParamList[i].tl_info, &b->DlUpParamList[i].tl_info))
return false;
}
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, pdcp_config);
_EQ_CHECK_OPTIONAL_PTR(a, b, pdcp_config);
if (a->pdcp_config && b->pdcp_config) {
if (!eq_pdcp_config(a->pdcp_config, b->pdcp_config))
return false;
}
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, sdap_config);
_EQ_CHECK_OPTIONAL_PTR(a, b, sdap_config);
if (a->sdap_config && b->sdap_config) {
if (!eq_sdap_config(a->sdap_config, b->sdap_config))
return false;
}
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, pdcp_status);
_EQ_CHECK_OPTIONAL_PTR(a, b, pdcp_status);
if (a->pdcp_status && b->pdcp_status) {
if (!eq_pdcp_info(a->pdcp_status, b->pdcp_status))
return false;
@@ -2024,26 +2023,26 @@ static bool eq_drb_to_mod(const DRB_nGRAN_to_mod_t *a, const DRB_nGRAN_to_mod_t
/** @brief Equality check for PDU session item to modify */
static bool eq_pdu_session_to_mod_item(const pdu_session_to_mod_t *a, const pdu_session_to_mod_t *b)
{
_E1_EQ_CHECK_LONG(a->sessionId, b->sessionId);
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, UP_TL_information);
_EQ_CHECK_LONG(a->sessionId, b->sessionId);
_EQ_CHECK_OPTIONAL_PTR(a, b, UP_TL_information);
if (a->UP_TL_information && b->UP_TL_information) {
if (!eq_up_tl_info(a->UP_TL_information, b->UP_TL_information))
return false;
}
_E1_EQ_CHECK_INT(a->numDRB2Setup, b->numDRB2Setup);
_EQ_CHECK_INT(a->numDRB2Setup, b->numDRB2Setup);
for (int i = 0; i < a->numDRB2Setup; i++) {
if (!eq_drb_to_setup(&a->DRBnGRanList[i], &b->DRBnGRanList[i]))
return false;
}
_E1_EQ_CHECK_LONG(a->numDRB2Modify, b->numDRB2Modify);
_EQ_CHECK_LONG(a->numDRB2Modify, b->numDRB2Modify);
for (int i = 0; i < a->numDRB2Modify; i++) {
if (!eq_drb_to_mod(&a->DRBnGRanModList[i], &b->DRBnGRanModList[i]))
return false;
}
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, securityIndication);
_E1_EQ_CHECK_INT(a->n_drb_to_remove, b->n_drb_to_remove);
_EQ_CHECK_OPTIONAL_PTR(a, b, securityIndication);
_EQ_CHECK_INT(a->n_drb_to_remove, b->n_drb_to_remove);
for (int r = 0; r < a->n_drb_to_remove; r++) {
_E1_EQ_CHECK_LONG(a->drbs_to_remove[r].id, b->drbs_to_remove[r].id);
_EQ_CHECK_LONG(a->drbs_to_remove[r].id, b->drbs_to_remove[r].id);
}
if (a->securityIndication && b->securityIndication) {
if (!eq_security_ind(a->securityIndication, b->securityIndication))
@@ -2058,24 +2057,24 @@ static bool eq_pdu_session_to_mod_item(const pdu_session_to_mod_t *a, const pdu_
bool eq_bearer_context_mod_request(const e1ap_bearer_mod_req_t *a, const e1ap_bearer_mod_req_t *b)
{
// basic members
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_E1_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
_E1_EQ_CHECK_INT(a->numPDUSessionsMod, b->numPDUSessionsMod);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
_EQ_CHECK_INT(a->numPDUSessionsMod, b->numPDUSessionsMod);
// Security Info
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, secInfo);
_EQ_CHECK_OPTIONAL_PTR(a, b, secInfo);
if (a->secInfo && b->secInfo) {
_E1_EQ_CHECK_LONG(a->secInfo->cipheringAlgorithm, b->secInfo->cipheringAlgorithm);
_E1_EQ_CHECK_LONG(a->secInfo->integrityProtectionAlgorithm, b->secInfo->integrityProtectionAlgorithm);
_E1_EQ_CHECK_STR(a->secInfo->encryptionKey, b->secInfo->encryptionKey);
_E1_EQ_CHECK_STR(a->secInfo->integrityProtectionKey, b->secInfo->integrityProtectionKey);
_EQ_CHECK_LONG(a->secInfo->cipheringAlgorithm, b->secInfo->cipheringAlgorithm);
_EQ_CHECK_LONG(a->secInfo->integrityProtectionAlgorithm, b->secInfo->integrityProtectionAlgorithm);
_EQ_CHECK_STR(a->secInfo->encryptionKey, b->secInfo->encryptionKey);
_EQ_CHECK_STR(a->secInfo->integrityProtectionKey, b->secInfo->integrityProtectionKey);
}
// Bearer Context Status (O)
_E1_EQ_CHECK_OPTIONAL_IE(a, b, bearerContextStatus, _E1_EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, bearerContextStatus, _EQ_CHECK_INT);
// Inactivity Timer (O)
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, inactivityTimer);
_EQ_CHECK_OPTIONAL_PTR(a, b, inactivityTimer);
if (a->inactivityTimer && b->inactivityTimer)
_E1_EQ_CHECK_INT(*a->inactivityTimer, *b->inactivityTimer);
_EQ_CHECK_INT(*a->inactivityTimer, *b->inactivityTimer);
// Activity Notification Level (O)
// PDU Sessions
if (a->numPDUSessions != b->numPDUSessions)
@@ -2092,13 +2091,13 @@ bool eq_bearer_context_mod_request(const e1ap_bearer_mod_req_t *a, const e1ap_be
return false;
}
// PDU Sessions to Remove
_E1_EQ_CHECK_INT(a->numPDUSessionsRem, b->numPDUSessionsRem);
_EQ_CHECK_INT(a->numPDUSessionsRem, b->numPDUSessionsRem);
for (int i = 0; i < a->numPDUSessionsRem; i++) {
const pdu_session_to_remove_t *pduRemA = &a->pduSessionRem[i];
const pdu_session_to_remove_t *pduRemB = &b->pduSessionRem[i];
_E1_EQ_CHECK_LONG(pduRemA->sessionId, pduRemB->sessionId);
_E1_EQ_CHECK_INT(pduRemA->cause.type, pduRemB->cause.type);
_E1_EQ_CHECK_INT(pduRemA->cause.value, pduRemB->cause.value);
_EQ_CHECK_LONG(pduRemA->sessionId, pduRemB->sessionId);
_EQ_CHECK_INT(pduRemA->cause.type, pduRemB->cause.type);
_EQ_CHECK_INT(pduRemA->cause.value, pduRemB->cause.value);
}
return true;
}
@@ -2324,10 +2323,10 @@ static qos_flow_failed_t decode_qos_flow_failed_item(const E1AP_QoS_Flow_Failed_
bool decode_E1_bearer_context_mod_response(e1ap_bearer_modif_resp_t *out, const E1AP_E1AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
E1AP_SuccessfulOutcome_t *type = pdu->choice.successfulOutcome;
_E1_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextModification);
_E1_EQ_CHECK_INT(type->value.present, E1AP_SuccessfulOutcome__value_PR_BearerContextModificationResponse);
_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextModification);
_EQ_CHECK_INT(type->value.present, E1AP_SuccessfulOutcome__value_PR_BearerContextModificationResponse);
const E1AP_BearerContextModificationResponse_t *in = &type->value.choice.BearerContextModificationResponse;
// Check mandatory IEs first
E1AP_BearerContextModificationResponseIEs_t *ie;
@@ -2339,28 +2338,30 @@ bool decode_E1_bearer_context_mod_response(e1ap_bearer_modif_resp_t *out, const
switch (ie->id) {
case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
// gNB-CU-CP UE E1AP ID (M)
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
out->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
break;
case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
// gNB-CU-UP UE E1AP ID (M)
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
out->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
break;
case E1AP_ProtocolIE_ID_id_System_BearerContextModificationResponse:
// CHOICE System (O)
_E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextModificationResponseIEs__value_PR_System_BearerContextModificationResponse);
_EQ_CHECK_INT(ie->value.present,
E1AP_BearerContextModificationResponseIEs__value_PR_System_BearerContextModificationResponse);
// NG-RAN System
E1AP_System_BearerContextModificationResponse_t *system = &ie->value.choice.System_BearerContextModificationResponse;
_E1_EQ_CHECK_INT(system->present, E1AP_System_BearerContextModificationResponse_PR_nG_RAN_BearerContextModificationResponse);
_EQ_CHECK_INT(system->present, E1AP_System_BearerContextModificationResponse_PR_nG_RAN_BearerContextModificationResponse);
// NG-RAN List
E1AP_ProtocolIE_Container_4932P29_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P29_t *)system->choice.nG_RAN_BearerContextModificationResponse;
_E1_EQ_CHECK_INT(msgNGRAN_list->list.count, 1);
_EQ_CHECK_INT(msgNGRAN_list->list.count, 1);
E1AP_NG_RAN_BearerContextModificationResponse_t *msgNGRAN = msgNGRAN_list->list.array[0];
_E1_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Modified_List);
_E1_EQ_CHECK_INT(msgNGRAN->value.present, E1AP_NG_RAN_BearerContextModificationResponse__value_PR_PDU_Session_Resource_Modified_List);
_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Modified_List);
_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationResponse__value_PR_PDU_Session_Resource_Modified_List);
// PDU Session Resource Modified list (O)
E1AP_PDU_Session_Resource_Modified_List_t *list = &msgNGRAN->value.choice.PDU_Session_Resource_Modified_List;
out->numPDUSessionsMod = list->list.count;
@@ -2501,36 +2502,36 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
if (!a || !b) return false; // Null-check both inputs
// Basic members
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_E1_EQ_CHECK_INT(a->numPDUSessionsMod, b->numPDUSessionsMod);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_EQ_CHECK_INT(a->numPDUSessionsMod, b->numPDUSessionsMod);
// PDU Session Modified List
for (int i = 0; i < a->numPDUSessionsMod; i++) {
const pdu_session_modif_t *pduA = &a->pduSessionMod[i];
const pdu_session_modif_t *pduB = &b->pduSessionMod[i];
_E1_EQ_CHECK_LONG(pduA->id, pduB->id);
_E1_EQ_CHECK_OPTIONAL_IE(pduA, pduB, confidentialityProtectionIndication, _E1_EQ_CHECK_INT);
_E1_EQ_CHECK_OPTIONAL_IE(pduA, pduB, integrityProtectionIndication, _E1_EQ_CHECK_INT);
_EQ_CHECK_LONG(pduA->id, pduB->id);
_EQ_CHECK_OPTIONAL_IE(pduA, pduB, confidentialityProtectionIndication, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(pduA, pduB, integrityProtectionIndication, _EQ_CHECK_INT);
_E1_EQ_CHECK_OPTIONAL_PTR(pduA, pduB, ng_DL_UP_TL_info);
_EQ_CHECK_OPTIONAL_PTR(pduA, pduB, ng_DL_UP_TL_info);
if (pduA->ng_DL_UP_TL_info && pduB->ng_DL_UP_TL_info) {
if (!eq_up_tl_info(pduA->ng_DL_UP_TL_info, pduB->ng_DL_UP_TL_info))
return false;
}
// DRB Modified List
_E1_EQ_CHECK_INT(pduA->numDRBModified, pduB->numDRBModified);
_EQ_CHECK_INT(pduA->numDRBModified, pduB->numDRBModified);
for (int j = 0; j < pduA->numDRBModified; j++) {
const DRB_nGRAN_modified_t *drbModA = &pduA->DRBnGRanModList[j];
const DRB_nGRAN_modified_t *drbModB = &pduB->DRBnGRanModList[j];
_E1_EQ_CHECK_LONG(drbModA->id, drbModB->id);
_E1_EQ_CHECK_INT(drbModA->numQosFlowSetup, drbModB->numQosFlowSetup);
_EQ_CHECK_LONG(drbModA->id, drbModB->id);
_EQ_CHECK_INT(drbModA->numQosFlowSetup, drbModB->numQosFlowSetup);
for (int j = 0; j < drbModA->numQosFlowSetup; j++) {
_E1_EQ_CHECK_LONG(drbModA->qosFlows[j].qfi, drbModB->qosFlows[j].qfi);
_EQ_CHECK_LONG(drbModA->qosFlows[j].qfi, drbModB->qosFlows[j].qfi);
}
_E1_EQ_CHECK_OPTIONAL_PTR(drbModA, drbModB, pdcp_status);
_EQ_CHECK_OPTIONAL_PTR(drbModA, drbModB, pdcp_status);
if (drbModA->pdcp_status && drbModB->pdcp_status) {
if (!eq_pdcp_info(drbModA->pdcp_status, drbModB->pdcp_status))
return false;
@@ -2538,32 +2539,32 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
}
// DRB Failed to Modify List
_E1_EQ_CHECK_INT(pduA->numDRBFailedToMod, pduB->numDRBFailedToMod);
_EQ_CHECK_INT(pduA->numDRBFailedToMod, pduB->numDRBFailedToMod);
for (int j = 0; j < pduA->numDRBFailedToMod; j++) {
_E1_EQ_CHECK_LONG(pduA->DRBnGRanFailedModList[j].id, pduB->DRBnGRanFailedModList[j].id);
_E1_EQ_CHECK_INT(pduA->DRBnGRanFailedModList[j].cause.value, pduB->DRBnGRanFailedModList[j].cause.value);
_E1_EQ_CHECK_INT(pduA->DRBnGRanFailedModList[j].cause.type, pduB->DRBnGRanFailedModList[j].cause.type);
_EQ_CHECK_LONG(pduA->DRBnGRanFailedModList[j].id, pduB->DRBnGRanFailedModList[j].id);
_EQ_CHECK_INT(pduA->DRBnGRanFailedModList[j].cause.value, pduB->DRBnGRanFailedModList[j].cause.value);
_EQ_CHECK_INT(pduA->DRBnGRanFailedModList[j].cause.type, pduB->DRBnGRanFailedModList[j].cause.type);
}
// DRB Setup List
_E1_EQ_CHECK_INT(pduA->numDRBSetup, pduB->numDRBSetup);
_EQ_CHECK_INT(pduA->numDRBSetup, pduB->numDRBSetup);
for (int j = 0; j < pduA->numDRBSetup; j++) {
const DRB_nGRAN_setup_t *drbSetupA = &pduA->DRBnGRanSetupList[j];
const DRB_nGRAN_setup_t *drbSetupB = &pduB->DRBnGRanSetupList[j];
_E1_EQ_CHECK_LONG(drbSetupA->id, drbSetupB->id);
_E1_EQ_CHECK_INT(drbSetupA->numQosFlowSetup, drbSetupB->numQosFlowSetup);
_EQ_CHECK_LONG(drbSetupA->id, drbSetupB->id);
_EQ_CHECK_INT(drbSetupA->numQosFlowSetup, drbSetupB->numQosFlowSetup);
for (int j = 0; j < drbSetupA->numQosFlowSetup; j++) {
_E1_EQ_CHECK_LONG(drbSetupA->qosFlows[j].qfi, drbSetupB->qosFlows[j].qfi);
_EQ_CHECK_LONG(drbSetupA->qosFlows[j].qfi, drbSetupB->qosFlows[j].qfi);
}
}
// DRB Failed to Setup List
_E1_EQ_CHECK_INT(pduA->numDRBFailed, pduB->numDRBFailed);
_EQ_CHECK_INT(pduA->numDRBFailed, pduB->numDRBFailed);
for (int j = 0; j < pduA->numDRBFailed; j++) {
_E1_EQ_CHECK_LONG(pduA->DRBnGRanFailedList[j].id, pduB->DRBnGRanFailedList[j].id);
_E1_EQ_CHECK_INT(pduA->DRBnGRanFailedList[j].cause.value, pduB->DRBnGRanFailedList[j].cause.value);
_E1_EQ_CHECK_INT(pduA->DRBnGRanFailedList[j].cause.type, pduB->DRBnGRanFailedList[j].cause.type);
_EQ_CHECK_LONG(pduA->DRBnGRanFailedList[j].id, pduB->DRBnGRanFailedList[j].id);
_EQ_CHECK_INT(pduA->DRBnGRanFailedList[j].cause.value, pduB->DRBnGRanFailedList[j].cause.value);
_EQ_CHECK_INT(pduA->DRBnGRanFailedList[j].cause.type, pduB->DRBnGRanFailedList[j].cause.type);
}
}
@@ -2627,10 +2628,10 @@ struct E1AP_E1AP_PDU *encode_E1_bearer_context_mod_failure(const e1ap_bearer_con
bool decode_E1_bearer_context_mod_failure(e1ap_bearer_context_mod_failure_t *out, const E1AP_E1AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_unsuccessfulOutcome);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_unsuccessfulOutcome);
E1AP_UnsuccessfulOutcome_t *type = pdu->choice.unsuccessfulOutcome;
_E1_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextModification);
_E1_EQ_CHECK_INT(type->value.present, E1AP_UnsuccessfulOutcome__value_PR_BearerContextModificationFailure);
_EQ_CHECK_LONG(type->procedureCode, E1AP_ProcedureCode_id_bearerContextModification);
_EQ_CHECK_INT(type->value.present, E1AP_UnsuccessfulOutcome__value_PR_BearerContextModificationFailure);
const E1AP_BearerContextModificationFailure_t *in = &type->value.choice.BearerContextModificationFailure;
// Check mandatory IEs first
E1AP_BearerContextModificationFailureIEs_t *ie;
@@ -2671,10 +2672,10 @@ bool eq_E1_bearer_context_mod_failure(const e1ap_bearer_context_mod_failure_t *a
{
if (!a || !b)
return false; // Null-check both inputs
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_E1_EQ_CHECK_INT(a->cause.type, b->cause.type);
_E1_EQ_CHECK_INT(a->cause.value, b->cause.value);
_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
_EQ_CHECK_INT(a->cause.type, b->cause.type);
_EQ_CHECK_INT(a->cause.value, b->cause.value);
return true;
}
+41 -41
View File
@@ -179,15 +179,15 @@ bool decode_e1ap_cuup_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_req_t
AssertFatal(ie != NULL, "in->protocolIEs.list.array[i] shall not be null");
switch (ie->id) {
case E1AP_ProtocolIE_ID_id_TransactionID:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_TransactionID);
_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_TransactionID);
out->transac_id = ie->value.choice.TransactionID;
break;
case E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_ID);
_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_ID);
asn_INTEGER2ulong(&ie->value.choice.GNB_CU_UP_ID, &out->gNB_cu_up_id);
break;
case E1AP_ProtocolIE_ID_id_gNB_CU_UP_Name:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_Name);
_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_Name);
// gNB-CU-UP Name (O)
E1AP_LIB_FIND_IE(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_UP_Name, false);
if (ie != NULL) {
@@ -196,12 +196,12 @@ bool decode_e1ap_cuup_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_req_t
}
break;
case E1AP_ProtocolIE_ID_id_CNSupport:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_CNSupport);
_E1_EQ_CHECK_INT(ie->value.choice.CNSupport, E1AP_CNSupport_c_5gc); // only 5GC CN Support supported
_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_CNSupport);
_EQ_CHECK_LONG((long)ie->value.choice.CNSupport, (long)E1AP_CNSupport_c_5gc); // only 5GC CN Support supported
out->cn_support = ie->value.choice.CNSupport;
break;
case E1AP_ProtocolIE_ID_id_SupportedPLMNs:
_E1_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_SupportedPLMNs_List);
_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_SupportedPLMNs_List);
out->supported_plmns = ie->value.choice.SupportedPLMNs_List.list.count;
for (int i = 0; i < out->supported_plmns; i++) {
@@ -275,19 +275,19 @@ void free_e1ap_cuup_setup_request(e1ap_setup_req_t *msg)
*/
bool eq_e1ap_cuup_setup_request(const e1ap_setup_req_t *a, const e1ap_setup_req_t *b)
{
_E1_EQ_CHECK_INT(a->transac_id, b->transac_id);
_E1_EQ_CHECK_INT(a->gNB_cu_up_id, b->gNB_cu_up_id);
_EQ_CHECK_UINT64(a->transac_id, b->transac_id);
_EQ_CHECK_UINT64(a->gNB_cu_up_id, b->gNB_cu_up_id);
if (a->gNB_cu_up_name && b->gNB_cu_up_name)
_E1_EQ_CHECK_STR(a->gNB_cu_up_name, b->gNB_cu_up_name)
_E1_EQ_CHECK_INT(a->supported_plmns, b->supported_plmns);
_EQ_CHECK_STR(a->gNB_cu_up_name, b->gNB_cu_up_name);
_EQ_CHECK_INT(a->supported_plmns, b->supported_plmns);
for (int i = 0; i < a->supported_plmns; i++) {
_E1_EQ_CHECK_INT(a->plmn[i].id.mcc, b->plmn[i].id.mcc);
_E1_EQ_CHECK_INT(a->plmn[i].id.mnc, b->plmn[i].id.mnc);
_E1_EQ_CHECK_INT(a->plmn[i].id.mnc_digit_length, b->plmn[i].id.mnc_digit_length);
_E1_EQ_CHECK_INT(a->plmn[i].supported_slices, b->plmn[i].supported_slices);
_EQ_CHECK_INT(a->plmn[i].id.mcc, b->plmn[i].id.mcc);
_EQ_CHECK_INT(a->plmn[i].id.mnc, b->plmn[i].id.mnc);
_EQ_CHECK_INT(a->plmn[i].id.mnc_digit_length, b->plmn[i].id.mnc_digit_length);
_EQ_CHECK_INT(a->plmn[i].supported_slices, b->plmn[i].supported_slices);
for (int s = 0; s < a->plmn[i].supported_slices; ++s) {
_E1_EQ_CHECK_INT(a->plmn[i].slice[s].sst, b->plmn[i].slice[s].sst);
_E1_EQ_CHECK_INT(a->plmn[i].slice[s].sd, b->plmn[i].slice[s].sd);
_EQ_CHECK_INT(a->plmn[i].slice[s].sst, b->plmn[i].slice[s].sst);
_EQ_CHECK_INT(a->plmn[i].slice[s].sd, b->plmn[i].slice[s].sd);
}
}
return true;
@@ -372,9 +372,9 @@ E1AP_E1AP_PDU_t *encode_e1ap_cuup_setup_response(const e1ap_setup_resp_t *msg)
*/
bool decode_e1ap_cuup_setup_response(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_resp_t *out)
{
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
_E1_EQ_CHECK_INT(pdu->choice.successfulOutcome->procedureCode, E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup);
_E1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, E1AP_SuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupResponse);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup);
_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, E1AP_SuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupResponse);
const E1AP_GNB_CU_UP_E1SetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.GNB_CU_UP_E1SetupResponse;
E1AP_GNB_CU_UP_E1SetupResponseIEs_t *ie;
// Transaction ID (M)
@@ -391,7 +391,7 @@ bool decode_e1ap_cuup_setup_response(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_resp
case E1AP_ProtocolIE_ID_id_gNB_CU_CP_Name:
// gNB-CU-CP Name (O)
E1AP_LIB_FIND_IE(E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_CP_Name, false);
_E1_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupResponseIEs__value_PR_GNB_CU_CP_Name);
_EQ_CHECK_INT(ie->value.present, E1AP_GNB_CU_UP_E1SetupResponseIEs__value_PR_GNB_CU_CP_Name);
if (ie != NULL) {
out->gNB_cu_cp_name = calloc_or_fail(ie->value.choice.GNB_CU_CP_Name.size + 1, sizeof(char));
memcpy(out->gNB_cu_cp_name, ie->value.choice.GNB_CU_CP_Name.buf, ie->value.choice.GNB_CU_CP_Name.size);
@@ -474,30 +474,30 @@ void free_e1ap_cuup_setup_response(e1ap_setup_resp_t *msg)
*/
bool eq_e1ap_cuup_setup_response(const e1ap_setup_resp_t *a, const e1ap_setup_resp_t *b)
{
_E1_EQ_CHECK_LONG(a->transac_id, b->transac_id);
_EQ_CHECK_LONG(a->transac_id, b->transac_id);
if ((a->gNB_cu_cp_name && !b->gNB_cu_cp_name) || (!a->gNB_cu_cp_name && b->gNB_cu_cp_name))
return false;
if (a->gNB_cu_cp_name && b->gNB_cu_cp_name)
_E1_EQ_CHECK_STR(a->gNB_cu_cp_name, b->gNB_cu_cp_name);
_EQ_CHECK_STR(a->gNB_cu_cp_name, b->gNB_cu_cp_name);
if ((a->tnla_info && !b->tnla_info) || (!a->tnla_info && b->tnla_info))
return false;
if (a->tnla_info && b->tnla_info) {
_E1_EQ_CHECK_INT(a->tnla_info->num_addresses_to_add, b->tnla_info->num_addresses_to_add);
_E1_EQ_CHECK_INT(a->tnla_info->num_addresses_to_remove, b->tnla_info->num_addresses_to_remove);
_EQ_CHECK_INT(a->tnla_info->num_addresses_to_add, b->tnla_info->num_addresses_to_add);
_EQ_CHECK_INT(a->tnla_info->num_addresses_to_remove, b->tnla_info->num_addresses_to_remove);
for (int i = 0; i < a->tnla_info->num_addresses_to_add; i++) {
tnl_address_info_item_t *a_to_add = &a->tnla_info->addresses_to_add[i];
tnl_address_info_item_t *b_to_add = &b->tnla_info->addresses_to_add[i];
_E1_EQ_CHECK_LONG(a_to_add->ipsec_tl_address, b_to_add->ipsec_tl_address);
_EQ_CHECK_UINT32(a_to_add->ipsec_tl_address, b_to_add->ipsec_tl_address);
for (int j = 0; j < a_to_add->num_gtp_tl_addresses; j++) {
_E1_EQ_CHECK_LONG(a_to_add->gtp_tl_addresses[j], b_to_add->gtp_tl_addresses[j]);
_EQ_CHECK_UINT32(a_to_add->gtp_tl_addresses[j], b_to_add->gtp_tl_addresses[j]);
}
}
for (int i = 0; i < a->tnla_info->num_addresses_to_remove; i++) {
tnl_address_info_item_t *a_to_rem = &a->tnla_info->addresses_to_remove[i];
tnl_address_info_item_t *b_to_rem = &b->tnla_info->addresses_to_remove[i];
_E1_EQ_CHECK_LONG(a_to_rem->ipsec_tl_address, b_to_rem->ipsec_tl_address);
_EQ_CHECK_UINT32(a_to_rem->ipsec_tl_address, b_to_rem->ipsec_tl_address);
for (int j = 0; j < a_to_rem->num_gtp_tl_addresses; j++) {
_E1_EQ_CHECK_LONG(a_to_rem->gtp_tl_addresses[j], b_to_rem->gtp_tl_addresses[j]);
_EQ_CHECK_UINT32(a_to_rem->gtp_tl_addresses[j], b_to_rem->gtp_tl_addresses[j]);
}
}
}
@@ -558,8 +558,8 @@ E1AP_E1AP_PDU_t *encode_e1ap_cuup_setup_failure(const e1ap_setup_fail_t *msg)
*/
bool decode_e1ap_cuup_setup_failure(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_fail_t *out)
{
_E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_unsuccessfulOutcome);
_E1_EQ_CHECK_INT(pdu->choice.unsuccessfulOutcome->procedureCode, E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup);
_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_unsuccessfulOutcome);
_EQ_CHECK_LONG(pdu->choice.unsuccessfulOutcome->procedureCode, E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup);
const E1AP_GNB_CU_UP_E1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie;
// Check mandatory IEs first
@@ -647,25 +647,25 @@ void free_e1ap_cuup_setup_failure(e1ap_setup_fail_t *msg)
*/
bool eq_e1ap_cuup_setup_failure(const e1ap_setup_fail_t *a, const e1ap_setup_fail_t *b)
{
_E1_EQ_CHECK_LONG(a->transac_id, b->transac_id);
_E1_EQ_CHECK_INT(a->cause.type, b->cause.type);
_E1_EQ_CHECK_INT(a->cause.value, b->cause.value);
_EQ_CHECK_LONG(a->transac_id, b->transac_id);
_EQ_CHECK_INT(a->cause.type, b->cause.type);
_EQ_CHECK_INT(a->cause.value, b->cause.value);
if (a->time_to_wait && b->time_to_wait)
_E1_EQ_CHECK_LONG(*a->time_to_wait, *b->time_to_wait);
_EQ_CHECK_LONG(*a->time_to_wait, *b->time_to_wait);
if (a->crit_diag && b->crit_diag) {
if (a->crit_diag->procedure_code && b->crit_diag->procedure_code)
_E1_EQ_CHECK_LONG(*(a->crit_diag->procedure_code), *(b->crit_diag->procedure_code));
_EQ_CHECK_INT(*(a->crit_diag->procedure_code), *(b->crit_diag->procedure_code));
if (a->crit_diag->triggering_msg && b->crit_diag->triggering_msg)
_E1_EQ_CHECK_LONG(*(a->crit_diag->triggering_msg), *(b->crit_diag->triggering_msg));
_EQ_CHECK_UINT32(*(a->crit_diag->triggering_msg), *(b->crit_diag->triggering_msg));
if (a->crit_diag->procedure_criticality && b->crit_diag->procedure_criticality)
_E1_EQ_CHECK_LONG(*(a->crit_diag->procedure_criticality), *(b->crit_diag->procedure_criticality));
_E1_EQ_CHECK_INT(a->crit_diag->num_errors, b->crit_diag->num_errors);
_EQ_CHECK_UINT32(*(a->crit_diag->procedure_criticality), *(b->crit_diag->procedure_criticality));
_EQ_CHECK_INT(a->crit_diag->num_errors, b->crit_diag->num_errors);
for (int i = 0; i < a->crit_diag->num_errors; i++) {
const criticality_diagnostics_ie_t *a_err = &a->crit_diag->errors[i];
const criticality_diagnostics_ie_t *b_err = &b->crit_diag->errors[i];
_E1_EQ_CHECK_INT(a_err->ie_id, b_err->ie_id);
_E1_EQ_CHECK_INT(a_err->error_type, b_err->error_type);
_E1_EQ_CHECK_INT(a_err->criticality, b_err->criticality);
_EQ_CHECK_INT(a_err->ie_id, b_err->ie_id);
_EQ_CHECK_INT(a_err->error_type, b_err->error_type);
_EQ_CHECK_INT(a_err->criticality, b_err->criticality);
}
}
return true;
+1 -45
View File
@@ -27,12 +27,7 @@
#include <stdio.h>
#include "openair3/UTILS/conversions.h"
#include "e1ap_messages_types.h"
#ifdef E1AP_LOG_ERRORS
#define PRINT_ERROR(fmt, ...) fprintf(stderr, "[%s] " fmt, __func__, ##__VA_ARGS__)
#else
#define PRINT_ERROR(...) // Do nothing
#endif
#include "common/utils/eq_check.h"
#define CHECK_E1AP_DEC(exp) \
do { \
@@ -42,22 +37,6 @@
} \
} while (0)
#define _E1_EQ_CHECK_GENERIC(condition, fmt, ...) \
do { \
if (!(condition)) { \
PRINT_ERROR("E1 Equality Check failure: %s:%d: Condition '%s' failed: " fmt " != " fmt "\n", \
__FILE__, \
__LINE__, \
#condition, \
##__VA_ARGS__); \
return false; \
} \
} while (0)
#define _E1_EQ_CHECK_LONG(A, B) _E1_EQ_CHECK_GENERIC(A == B, "%ld", A, B);
#define _E1_EQ_CHECK_INT(A, B) _E1_EQ_CHECK_GENERIC(A == B, "%d", A, B);
#define _E1_EQ_CHECK_STR(A, B) _E1_EQ_CHECK_GENERIC(strcmp(A, B) == 0, "'%s'", A, B);
// Macro to look up IE. If mandatory and not found, macro will log an error and return false.
#define E1AP_LIB_FIND_IE(IE_TYPE, ie, container, IE_ID, mandatory) \
do { \
@@ -84,29 +63,6 @@
} \
} while (0)
#define _E1_EQ_CHECK_OPTIONAL_IE(a, b, field, EQ_MACRO) \
do { \
if (((a)->field && !(b)->field) || (!(a)->field && (b)->field)) { \
return false; /* One of the two is not allocated */ \
} \
if ((a)->field && (b)->field) { \
EQ_MACRO(*(a)->field, *(b)->field) \
} \
} while (0)
#define _E1_EQ_CHECK_OPTIONAL_PTR(a, b, field) \
do { \
if (((a)->field && !(b)->field) || (!(a)->field && (b)->field)) { \
PRINT_ERROR("%s:%d: optional IE '%s' not allocated: %p, %p\n", \
__FILE__, \
__LINE__, \
#field, \
(void *)(a)->field, \
(void *)(b)->field); \
return false; /* One of the two is not allocated */ \
} \
} while (0)
struct E1AP_Cause;
struct E1AP_Cause e1_encode_cause_ie(const e1ap_cause_t *cause);
e1ap_cause_t e1_decode_cause_ie(const struct E1AP_Cause *ie);
+17 -78
View File
@@ -34,87 +34,26 @@
#include "f1ap_encoder.h"
#include "f1ap_itti_messaging.h"
#include "f1ap_cu_paging.h"
#include "lib/f1ap_paging.h"
#include "common/utils/ds/byte_array.h"
extern f1ap_setup_req_t *f1ap_du_data_from_du;
int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging)
int CU_send_Paging(sctp_assoc_t assoc_id, const f1ap_paging_t *paging)
{
F1AP_F1AP_PDU_t pdu = {0};
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu.choice.initiatingMessage, msg);
msg->procedureCode = F1AP_ProcedureCode_id_Paging;
msg->criticality = F1AP_Criticality_reject;
msg->value.present = F1AP_InitiatingMessage__value_PR_Paging;
/* mandatory */
/* UEIdentityIndexValue */
{
asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_UEIdentityIndexValue;
ie->criticality = F1AP_Criticality_reject;
ie->value.present = F1AP_PagingIEs__value_PR_UEIdentityIndexValue;
ie->value.choice.UEIdentityIndexValue.present =
F1AP_UEIdentityIndexValue_PR_indexLength10;
UEIDENTITYINDEX_TO_BIT_STRING(
paging->ueidentityindexvalue,
&ie->value.choice.UEIdentityIndexValue.choice.indexLength10);
}
/* mandatory */
/* PagingIdentity */
{
asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingIdentity;
ie->criticality = F1AP_Criticality_reject;
ie->value.present = F1AP_PagingIEs__value_PR_PagingIdentity;
ie->value.choice.PagingIdentity.present =
F1AP_PagingIdentity_PR_cNUEPagingIdentity;
asn1cCalloc(ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity, id);
id->present = F1AP_CNUEPagingIdentity_PR_fiveG_S_TMSI;
FIVEG_S_TMSI_TO_BIT_STRING(paging->fiveg_s_tmsi, &id->choice.fiveG_S_TMSI);
}
/* optional */
/* PagingDRX */
{
asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingDRX;
ie->criticality = F1AP_Criticality_ignore;
ie->value.present = F1AP_PagingIEs__value_PR_PagingDRX;
ie->value.choice.PagingDRX = paging->paging_drx;
}
/* mandatory */
/* PagingCell_list */
{
asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingCell_List;
ie->criticality = F1AP_Criticality_reject;
ie->value.present = F1AP_PagingIEs__value_PR_PagingCell_list;
asn1cSequenceAdd(ie->value.choice.PagingCell_list,
F1AP_PagingCell_ItemIEs_t, itemies);
itemies->id = F1AP_ProtocolIE_ID_id_PagingCell_Item;
itemies->criticality = F1AP_Criticality_reject;
itemies->value.present = F1AP_PagingCell_ItemIEs__value_PR_PagingCell_Item;
F1AP_NRCGI_t *nRCGI = &itemies->value.choice.PagingCell_Item.nRCGI;
MCC_MNC_TO_PLMNID(paging->plmn.mcc, paging->plmn.mnc, paging->plmn.mnc_digit_length, &nRCGI->pLMN_Identity);
NR_CELL_ID_TO_BIT_STRING(paging->nr_cellid, &nRCGI->nRCellIdentity);
}
uint8_t *buffer;
uint32_t len;
/* encode */
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 Paging failure\n");
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
F1AP_F1AP_PDU_t *pdu = encode_f1ap_paging(paging);
if (pdu == NULL) {
LOG_E(F1AP, "Failed to encode F1 Paging\n");
return -1;
}
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
byte_array_t ba = {0};
/* encode */
if (f1ap_encode_pdu(pdu, &ba.buf, (uint32_t *)&ba.len) < 0) {
LOG_E(F1AP, "Failed to encode F1 Paging PDU\n");
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
return -1;
}
ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu);
/* Ownership of ba.buf is transferred to SCTP task; do not free here. */
f1ap_itti_send_sctp_data_req(assoc_id, ba.buf, ba.len);
return 0;
}
+1 -1
View File
@@ -32,5 +32,5 @@
#ifndef F1AP_CU_PAGING_H_
#define F1AP_CU_PAGING_H_
int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging);
int CU_send_Paging(sctp_assoc_t assoc_id, const f1ap_paging_t *paging);
#endif /* F1AP_DU_PAGING_H_ */
+4 -3
View File
@@ -38,6 +38,7 @@
#include "lib/f1ap_interface_management.h"
#include "lib/f1ap_ue_context.h"
#include "f1ap_cu_paging.h"
#include "lib/f1ap_paging.h"
#include "f1ap_cu_task.h"
#include "openair2/RRC/NR/nr_rrc_defs.h"
#include <openair3/ocp-gtpu/gtp_itf.h>
@@ -202,9 +203,9 @@ void *F1AP_CU_task(void *arg) {
free_ue_context_rel_cmd(&F1AP_UE_CONTEXT_RELEASE_CMD(received_msg));
break;
case F1AP_PAGING_IND:
CU_send_Paging(assoc_id,
&F1AP_PAGING_IND(received_msg));
case F1AP_PAGING:
CU_send_Paging(assoc_id, &F1AP_PAGING(received_msg));
free_f1ap_paging(&F1AP_PAGING(received_msg));
break;
case F1AP_UE_CONTEXT_MODIFICATION_CONFIRM:
+15 -53
View File
@@ -19,75 +19,37 @@
* contact@openairinterface.org
*/
/*! \file f1ap_du_interface_management.h
* \brief f1ap interface management for DU
* \author EURECOM/NTUST
* \date 2018
* \version 0.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
* \note
* \warning
*/
#include "f1ap_common.h"
#include "f1ap_du_paging.h"
#include "lib/f1ap_paging.h"
#include "conversions.h"
#include "oai_asn1.h"
#include "openair2/RRC/LTE/rrc_proto.h"
/* @brief Handle F1AP Paging message at DU */
int DU_handle_Paging(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
F1AP_Paging_t *paging;
F1AP_PagingIEs_t *ie;
long tmsi;
uint8_t pagingdrx;
uint8_t *fiveg_tmsi_buf = NULL;
f1ap_paging_t decoded = {0};
DevAssert(pdu);
(void)instance;
(void)assoc_id;
(void)stream;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu);
}
paging = &pdu->choice.initiatingMessage->value.choice.Paging;
// get UEIdentityIndexValue
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
F1AP_ProtocolIE_ID_id_UEIdentityIndexValue, true);
LOG_D(F1AP, "indexLength10 %d\n", BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue.choice.indexLength10));
// get PagingIdentity
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
F1AP_ProtocolIE_ID_id_PagingIdentity, true);
if(ie != NULL){
fiveg_tmsi_buf = ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf;
tmsi = ((long)fiveg_tmsi_buf[0] << 40) +
((long)fiveg_tmsi_buf[1] << 32) +
(fiveg_tmsi_buf[2] << 24) +
(fiveg_tmsi_buf[3] << 16) +
(fiveg_tmsi_buf[4] << 8) +
fiveg_tmsi_buf[5];
LOG_D(F1AP, "tmsi %ld\n", tmsi);
if (!decode_f1ap_paging(&decoded, pdu)) {
LOG_E(F1AP, "Failed to decode F1AP Paging\n");
return -1;
}
// get PagingDRX
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
F1AP_ProtocolIE_ID_id_PagingDRX, true);
if(ie != NULL) {
pagingdrx = (uint8_t)ie->value.choice.PagingDRX;
}
LOG_D(F1AP, "pagingdrx %u\n", pagingdrx);
// get PagingCell_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
F1AP_ProtocolIE_ID_id_PagingCell_List, true);
AssertFatal(false, "not implemented\n");
/** @todo Build PCCH-Message (Paging) at DU per TS 38.331 §5.3.2; apply
* RRC padding per §8.5; deliver as RLC SDU per §8.2. For each
* cell in Paging Cell List that belongs to this DU, queue for MAC; MAC schedules
* at PF/PO per TS 38.304 §7. */
free_f1ap_paging(&decoded);
return 0;
}
+1 -11
View File
@@ -19,20 +19,10 @@
* contact@openairinterface.org
*/
/*! \file f1ap_du_interface_management.h
* \brief f1ap interface management for DU
* \author EURECOM/NTUST
* \date 2018
* \version 0.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
* \note
* \warning
*/
#ifndef F1AP_DU_PAGING_H_
#define F1AP_DU_PAGING_H_
/* Paging (gNB-CU initiated) */
int DU_handle_Paging(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
#endif /* F1AP_DU_PAGING_H_ */
+1
View File
@@ -4,6 +4,7 @@ add_library(f1ap_lib OBJECT
f1ap_interface_management.c
f1ap_ue_context.c
f1ap_positioning.c
f1ap_paging.c
)
target_link_libraries(f1ap_lib PRIVATE asn1_f1ap ds)
target_include_directories(f1ap_lib PUBLIC
+126 -129
View File
@@ -69,11 +69,11 @@ bool eq_f1ap_ue_to_reset(const f1ap_ue_to_reset_t *a, const f1ap_ue_to_reset_t *
if ((!a->gNB_CU_ue_id) ^ (!b->gNB_CU_ue_id))
return false;
if (a->gNB_CU_ue_id)
_F1_EQ_CHECK_INT(*a->gNB_CU_ue_id, *b->gNB_CU_ue_id);
_EQ_CHECK_INT(*a->gNB_CU_ue_id, *b->gNB_CU_ue_id);
if ((!a->gNB_DU_ue_id) ^ (!b->gNB_DU_ue_id))
return false;
if (a->gNB_DU_ue_id)
_F1_EQ_CHECK_INT(*a->gNB_DU_ue_id, *b->gNB_DU_ue_id);
_EQ_CHECK_INT(*a->gNB_DU_ue_id, *b->gNB_DU_ue_id);
return true;
}
@@ -148,10 +148,10 @@ F1AP_F1AP_PDU_t *encode_f1ap_reset(const f1ap_reset_t *msg)
/* @brief decode F1 Reset (9.2.1.1 in TS 38.473) */
bool decode_f1ap_reset(const F1AP_F1AP_PDU_t *pdu, f1ap_reset_t *out)
{
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
AssertError(pdu->choice.initiatingMessage != NULL, return false, "pdu->choice.initiatingMessage is NULL");
_F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_Reset);
_F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_Reset);
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_Reset);
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_Reset);
/* Check presence of mandatory IEs */
F1AP_Reset_t *in = &pdu->choice.initiatingMessage->value.choice.Reset;
@@ -167,12 +167,12 @@ bool decode_f1ap_reset(const F1AP_F1AP_PDU_t *pdu, f1ap_reset_t *out)
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_TransactionID:
// (M) Transaction ID
_F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_TransactionID);
_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_TransactionID);
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_Cause:
// (M) Cause
_F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_Cause);
_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_Cause);
if (!decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value)) {
PRINT_ERROR("could not decode F1AP Cause\n");
return false;
@@ -180,7 +180,7 @@ bool decode_f1ap_reset(const F1AP_F1AP_PDU_t *pdu, f1ap_reset_t *out)
break;
case F1AP_ProtocolIE_ID_id_ResetType:
// (M) Reset type
_F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_ResetType);
_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_ResetType);
if (ie->value.choice.ResetType.present == F1AP_ResetType_PR_f1_Interface) {
out->reset_type = F1AP_RESET_ALL;
} else if (ie->value.choice.ResetType.present == F1AP_ResetType_PR_partOfF1_Interface) {
@@ -192,9 +192,9 @@ bool decode_f1ap_reset(const F1AP_F1AP_PDU_t *pdu, f1ap_reset_t *out)
for (int i = 0; i < out->num_ue_to_reset; ++i) {
const F1AP_UE_associatedLogicalF1_ConnectionItemRes_t *it_res =
(const F1AP_UE_associatedLogicalF1_ConnectionItemRes_t *)con_list->list.array[i];
_F1_EQ_CHECK_LONG(it_res->id, F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem);
_F1_EQ_CHECK_INT(it_res->value.present,
F1AP_UE_associatedLogicalF1_ConnectionItemRes__value_PR_UE_associatedLogicalF1_ConnectionItem);
_EQ_CHECK_LONG(it_res->id, F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem);
_EQ_CHECK_INT(it_res->value.present,
F1AP_UE_associatedLogicalF1_ConnectionItemRes__value_PR_UE_associatedLogicalF1_ConnectionItem);
out->ue_to_reset[i] = decode_f1ap_ue_to_reset(&it_res->value.choice.UE_associatedLogicalF1_ConnectionItem);
}
} else {
@@ -220,12 +220,12 @@ void free_f1ap_reset(f1ap_reset_t *msg)
bool eq_f1ap_reset(const f1ap_reset_t *a, const f1ap_reset_t *b)
{
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_F1_EQ_CHECK_INT(a->cause, b->cause);
_F1_EQ_CHECK_LONG(a->cause_value, b->cause_value);
_F1_EQ_CHECK_INT(a->reset_type, b->reset_type);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_LONG(a->cause_value, b->cause_value);
_EQ_CHECK_INT(a->reset_type, b->reset_type);
if (a->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE) {
_F1_EQ_CHECK_INT(a->num_ue_to_reset, b->num_ue_to_reset);
_EQ_CHECK_INT(a->num_ue_to_reset, b->num_ue_to_reset);
for (int i = 0; i < a->num_ue_to_reset; ++i)
if (!eq_f1ap_ue_to_reset(&a->ue_to_reset[i], &b->ue_to_reset[i]))
return false;
@@ -295,10 +295,10 @@ struct F1AP_F1AP_PDU *encode_f1ap_reset_ack(const f1ap_reset_ack_t *msg)
/* @brief decode F1 Reset Ack (9.2.1.2 in TS 38.473) */
bool decode_f1ap_reset_ack(const struct F1AP_F1AP_PDU *pdu, f1ap_reset_ack_t *out)
{
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
AssertError(pdu->choice.successfulOutcome != NULL, return false, "pdu->choice.initiatingMessage is NULL");
_F1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_Reset);
_F1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, F1AP_SuccessfulOutcome__value_PR_ResetAcknowledge);
_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_Reset);
_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, F1AP_SuccessfulOutcome__value_PR_ResetAcknowledge);
/* Check presence of mandatory IEs */
F1AP_ResetAcknowledge_t *in = &pdu->choice.successfulOutcome->value.choice.ResetAcknowledge;
@@ -312,11 +312,11 @@ bool decode_f1ap_reset_ack(const struct F1AP_F1AP_PDU *pdu, f1ap_reset_ack_t *ou
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_TransactionID:
// (M) Transaction ID
_F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetAcknowledgeIEs__value_PR_TransactionID);
_EQ_CHECK_INT(ie->value.present, F1AP_ResetAcknowledgeIEs__value_PR_TransactionID);
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionListResAck:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetAcknowledgeIEs__value_PR_UE_associatedLogicalF1_ConnectionListResAck);
_EQ_CHECK_INT(ie->value.present, F1AP_ResetAcknowledgeIEs__value_PR_UE_associatedLogicalF1_ConnectionListResAck);
{
const F1AP_UE_associatedLogicalF1_ConnectionListResAck_t *conn_list = &ie->value.choice.UE_associatedLogicalF1_ConnectionListResAck;
AssertError(conn_list->list.count > 0, return false, "no UEs for partially reset F1 interface\n");
@@ -324,8 +324,9 @@ bool decode_f1ap_reset_ack(const struct F1AP_F1AP_PDU *pdu, f1ap_reset_ack_t *ou
out->ue_to_reset = calloc_or_fail(out->num_ue_to_reset, sizeof(*out->ue_to_reset));
for (int i = 0; i < out->num_ue_to_reset; ++i) {
const F1AP_UE_associatedLogicalF1_ConnectionItemResAck_t *it_res = (const F1AP_UE_associatedLogicalF1_ConnectionItemResAck_t *)conn_list->list.array[i];
_F1_EQ_CHECK_LONG(it_res->id, F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem);
_F1_EQ_CHECK_INT(it_res->value.present, F1AP_UE_associatedLogicalF1_ConnectionItemResAck__value_PR_UE_associatedLogicalF1_ConnectionItem);
_EQ_CHECK_LONG(it_res->id, F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem);
_EQ_CHECK_INT(it_res->value.present,
F1AP_UE_associatedLogicalF1_ConnectionItemResAck__value_PR_UE_associatedLogicalF1_ConnectionItem);
out->ue_to_reset[i] = decode_f1ap_ue_to_reset(&it_res->value.choice.UE_associatedLogicalF1_ConnectionItem);
}
}
@@ -347,8 +348,8 @@ void free_f1ap_reset_ack(f1ap_reset_ack_t *msg)
bool eq_f1ap_reset_ack(const f1ap_reset_ack_t *a, const f1ap_reset_ack_t *b)
{
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_F1_EQ_CHECK_INT(a->num_ue_to_reset, b->num_ue_to_reset);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_INT(a->num_ue_to_reset, b->num_ue_to_reset);
for (int i = 0; i < a->num_ue_to_reset; ++i) {
if (!eq_f1ap_ue_to_reset(&a->ue_to_reset[i], &b->ue_to_reset[i]))
return false;
@@ -806,10 +807,10 @@ F1AP_F1AP_PDU_t *encode_f1ap_setup_request(const f1ap_setup_req_t *msg)
bool decode_f1ap_setup_request(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_req_t *out)
{
/* Check presence of message type */
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
AssertError(pdu->choice.initiatingMessage != NULL, return false, "pdu->choice.initiatingMessage is NULL");
_F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_F1Setup);
_F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_F1SetupRequest);
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_F1Setup);
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_F1SetupRequest);
/* Check presence of mandatory IEs */
F1AP_F1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.F1SetupRequest;
F1AP_F1SetupRequestIEs_t *ie;
@@ -823,13 +824,13 @@ bool decode_f1ap_setup_request(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_req_t *out
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_TransactionID:
// Transaction ID (M)
_F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupRequestIEs__value_PR_TransactionID);
_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupRequestIEs__value_PR_TransactionID);
AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1");
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_ID:
// gNB-DU ID (M)
_F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID);
asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, &out->gNB_DU_id);
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_Name: {
@@ -971,19 +972,19 @@ f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg)
*/
bool eq_f1ap_setup_request(const f1ap_setup_req_t *a, const f1ap_setup_req_t *b)
{
_F1_EQ_CHECK_LONG(a->gNB_DU_id, b->gNB_DU_id);
_F1_EQ_CHECK_STR(a->gNB_DU_name, b->gNB_DU_name);
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_F1_EQ_CHECK_INT(a->num_cells_available, b->num_cells_available);
_EQ_CHECK_LONG(a->gNB_DU_id, b->gNB_DU_id);
_EQ_CHECK_STR(a->gNB_DU_name, b->gNB_DU_name);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_INT(a->num_cells_available, b->num_cells_available);
for (int i = 0; i < a->num_cells_available && i < F1AP_MAX_NB_CELLS; i++) {
if (!eq_f1ap_cell_info(&a->cell[i].info, &b->cell[i].info))
return false;
if (!eq_f1ap_sys_info(a->cell[i].sys_info, b->cell[i].sys_info))
return false;
}
_F1_EQ_CHECK_LONG(sizeofArray(a->rrc_ver), sizeofArray(b->rrc_ver));
_EQ_CHECK_LONG(sizeofArray(a->rrc_ver), sizeofArray(b->rrc_ver));
for (int i = 0; i < sizeofArray(a->rrc_ver); i++) {
_F1_EQ_CHECK_INT(a->rrc_ver[i], b->rrc_ver[i]);
_EQ_CHECK_INT(a->rrc_ver[i], b->rrc_ver[i]);
}
return true;
}
@@ -1087,9 +1088,9 @@ F1AP_F1AP_PDU_t *encode_f1ap_setup_response(const f1ap_setup_resp_t *msg)
bool decode_f1ap_setup_response(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_resp_t *out)
{
/* Check presence of message type */
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
_F1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_F1Setup);
_F1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, F1AP_SuccessfulOutcome__value_PR_F1SetupResponse);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_F1Setup);
_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, F1AP_SuccessfulOutcome__value_PR_F1SetupResponse);
/* Check presence of mandatory IEs */
F1AP_F1SetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse;
F1AP_F1SetupResponseIEs_t *ie;
@@ -1101,14 +1102,14 @@ bool decode_f1ap_setup_response(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_resp_t *o
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_TransactionID:
// Transaction ID (M)
_F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_TransactionID);
AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1");
out->transaction_id = ie->value.choice.TransactionID;
break;
_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_TransactionID);
AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1");
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_gNB_CU_Name: {
// gNB-CU Name (O)
_F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name);
_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name);
const F1AP_GNB_CU_Name_t *cu_name = &ie->value.choice.GNB_CU_Name;
out->gNB_CU_name = calloc_or_fail(cu_name->size + 1, sizeof(*out->gNB_CU_name));
strncpy(out->gNB_CU_name, (char *)cu_name->buf, cu_name->size);
@@ -1116,18 +1117,18 @@ bool decode_f1ap_setup_response(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_resp_t *o
case F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version:
// gNB-CU RRC version (M)
_F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_RRC_Version);
// RRC Version: "This IE is not used in this release."
if (ie->value.choice.RRC_Version.iE_Extensions) {
F1AP_ProtocolExtensionContainer_11023P233_t *ext =
(F1AP_ProtocolExtensionContainer_11023P233_t *)ie->value.choice.RRC_Version.iE_Extensions;
if (ext->list.count > 0) {
F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0];
OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_;
for (int i = 0; i < sizeofArray(out->rrc_ver); i++)
out->rrc_ver[i] = os->buf[i];
}
_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_RRC_Version);
// RRC Version: "This IE is not used in this release."
if (ie->value.choice.RRC_Version.iE_Extensions) {
F1AP_ProtocolExtensionContainer_11023P233_t *ext =
(F1AP_ProtocolExtensionContainer_11023P233_t *)ie->value.choice.RRC_Version.iE_Extensions;
if (ext->list.count > 0) {
F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0];
OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_;
for (int i = 0; i < sizeofArray(out->rrc_ver); i++)
out->rrc_ver[i] = os->buf[i];
}
}
break;
case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: {
@@ -1161,17 +1162,17 @@ bool decode_f1ap_setup_response(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_resp_t *o
*/
bool eq_f1ap_setup_response(const f1ap_setup_resp_t *a, const f1ap_setup_resp_t *b)
{
_F1_EQ_CHECK_STR(a->gNB_CU_name, b->gNB_CU_name);
_F1_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate);
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_STR(a->gNB_CU_name, b->gNB_CU_name);
_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
if (a->num_cells_to_activate) {
for (int i = 0; i < a->num_cells_to_activate && i < F1AP_MAX_NB_CELLS; i++) {
const served_cells_to_activate_t *a_cell = &a->cells_to_activate[i];
const served_cells_to_activate_t *b_cell = &b->cells_to_activate[i];
_F1_EQ_CHECK_LONG(a_cell->nr_cellid, b_cell->nr_cellid);
_F1_EQ_CHECK_INT(a_cell->nrpci, b_cell->nrpci);
_F1_EQ_CHECK_INT(a_cell->num_SI, b_cell->num_SI);
_F1_EQ_CHECK_LONG(a_cell->nr_cellid, b_cell->nr_cellid);
_EQ_CHECK_LONG(a_cell->nr_cellid, b_cell->nr_cellid);
_EQ_CHECK_INT(a_cell->nrpci, b_cell->nrpci);
_EQ_CHECK_INT(a_cell->num_SI, b_cell->num_SI);
_EQ_CHECK_LONG(a_cell->nr_cellid, b_cell->nr_cellid);
if (!eq_f1ap_plmn(&a_cell->plmn, &b_cell->plmn))
return false;
if (sizeofArray(a->cells_to_activate[i].SI_msg) != sizeofArray(b->cells_to_activate[i].SI_msg))
@@ -1179,15 +1180,15 @@ bool eq_f1ap_setup_response(const f1ap_setup_resp_t *a, const f1ap_setup_resp_t
for (int j = 0; j < b->cells_to_activate[i].num_SI; j++) {
const f1ap_sib_msg_t *a_SI_msg = &a->cells_to_activate[i].SI_msg[j];
const f1ap_sib_msg_t *b_SI_msg = &b->cells_to_activate[i].SI_msg[j];
_F1_EQ_CHECK_INT(*a_SI_msg->SI_container, *b_SI_msg->SI_container);
_F1_EQ_CHECK_INT(a_SI_msg->SI_container_length, b_SI_msg->SI_container_length);
_F1_EQ_CHECK_INT(a_SI_msg->SI_type, b_SI_msg->SI_type);
_EQ_CHECK_INT(*a_SI_msg->SI_container, *b_SI_msg->SI_container);
_EQ_CHECK_INT(a_SI_msg->SI_container_length, b_SI_msg->SI_container_length);
_EQ_CHECK_INT(a_SI_msg->SI_type, b_SI_msg->SI_type);
}
}
}
_F1_EQ_CHECK_LONG(sizeofArray(a->rrc_ver), sizeofArray(b->rrc_ver));
_EQ_CHECK_LONG(sizeofArray(a->rrc_ver), sizeofArray(b->rrc_ver));
for (int i = 0; i < sizeofArray(a->rrc_ver); i++) {
_F1_EQ_CHECK_INT(a->rrc_ver[i], b->rrc_ver[i]);
_EQ_CHECK_INT(a->rrc_ver[i], b->rrc_ver[i]);
}
return true;
}
@@ -1340,7 +1341,7 @@ bool decode_f1ap_setup_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_failure_t
*/
bool eq_f1ap_setup_failure(const f1ap_setup_failure_t *a, const f1ap_setup_failure_t *b)
{
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
return true;
}
@@ -1501,9 +1502,9 @@ F1AP_F1AP_PDU_t *encode_f1ap_du_configuration_update(const f1ap_gnb_du_configura
bool decode_f1ap_du_configuration_update(const F1AP_F1AP_PDU_t *pdu, f1ap_gnb_du_configuration_update_t *out)
{
/* Check presence of message type */
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
_F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_gNBDUConfigurationUpdate);
_F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_gNBDUConfigurationUpdate);
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate);
/* Check presence of mandatory IEs */
F1AP_GNBDUConfigurationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate;
F1AP_GNBDUConfigurationUpdateIEs_t *ie;
@@ -1638,10 +1639,10 @@ bool eq_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *a
if ((a->gNB_DU_ID != NULL) ^ (b->gNB_DU_ID != NULL))
return false;
if (a->gNB_DU_ID != NULL && b->gNB_DU_ID != NULL)
_F1_EQ_CHECK_LONG(*a->gNB_DU_ID, *b->gNB_DU_ID);
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_LONG(*a->gNB_DU_ID, *b->gNB_DU_ID);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
/* to add */
_F1_EQ_CHECK_INT(a->num_cells_to_add, b->num_cells_to_add);
_EQ_CHECK_INT(a->num_cells_to_add, b->num_cells_to_add);
for (int i = 0; i < a->num_cells_to_add && i < F1AP_MAX_NB_CELLS; i++) {
if (!eq_f1ap_cell_info(&a->cell_to_add[i].info, &b->cell_to_add[i].info))
return false;
@@ -1649,32 +1650,32 @@ bool eq_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *a
return false;
}
/* to delete */
_F1_EQ_CHECK_INT(a->num_cells_to_delete, b->num_cells_to_delete);
_EQ_CHECK_INT(a->num_cells_to_delete, b->num_cells_to_delete);
for (int i = 0; i < a->num_cells_to_delete && i < F1AP_MAX_NB_CELLS; i++) {
_F1_EQ_CHECK_LONG(a->cell_to_delete[i].nr_cellid, b->cell_to_delete[i].nr_cellid);
_EQ_CHECK_LONG(a->cell_to_delete[i].nr_cellid, b->cell_to_delete[i].nr_cellid);
if (!eq_f1ap_plmn(&a->cell_to_delete[i].plmn, &b->cell_to_delete[i].plmn))
return false;
}
/* to modify */
_F1_EQ_CHECK_INT(a->num_cells_to_modify, b->num_cells_to_modify);
_EQ_CHECK_INT(a->num_cells_to_modify, b->num_cells_to_modify);
for (int i = 0; i < a->num_cells_to_modify && i < F1AP_MAX_NB_CELLS; i++) {
if (!eq_f1ap_plmn(&a->cell_to_modify[i].old_plmn, &b->cell_to_modify[i].old_plmn))
return false;
_F1_EQ_CHECK_LONG(a->cell_to_modify[i].old_nr_cellid, b->cell_to_modify[i].old_nr_cellid);
_EQ_CHECK_LONG(a->cell_to_modify[i].old_nr_cellid, b->cell_to_modify[i].old_nr_cellid);
if (!eq_f1ap_cell_info(&a->cell_to_modify[i].info, &b->cell_to_modify[i].info))
return false;
if (!eq_f1ap_sys_info(a->cell_to_modify[i].sys_info, b->cell_to_modify[i].sys_info))
return false;
}
/* cell status */
_F1_EQ_CHECK_INT(a->num_status, b->num_status);
_EQ_CHECK_INT(a->num_status, b->num_status);
for (int i = 0; i < a->num_status && i < F1AP_MAX_NB_CELLS; ++i) {
const f1ap_cell_status_t *astatus = &a->status[i];
const f1ap_cell_status_t *bstatus = &b->status[i];
if (!eq_f1ap_plmn(&astatus->plmn, &bstatus->plmn))
return false;
_F1_EQ_CHECK_LONG(astatus->nr_cellid, bstatus->nr_cellid);
_F1_EQ_CHECK_INT(astatus->service_state, bstatus->service_state);
_EQ_CHECK_LONG(astatus->nr_cellid, bstatus->nr_cellid);
_EQ_CHECK_INT(astatus->service_state, bstatus->service_state);
}
return true;
}
@@ -1770,10 +1771,10 @@ F1AP_F1AP_PDU_t *encode_f1ap_cu_configuration_update(const f1ap_gnb_cu_configura
bool decode_f1ap_cu_configuration_update(const F1AP_F1AP_PDU_t *pdu, f1ap_gnb_cu_configuration_update_t *out)
{
/* Check presence of message type */
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
AssertError(pdu->choice.initiatingMessage != NULL, return false, "pdu->choice.initiatingMessage is NULL");
_F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_gNBCUConfigurationUpdate);
_F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate);
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_gNBCUConfigurationUpdate);
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate);
/* Check presence of mandatory IEs */
F1AP_GNBCUConfigurationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate;
F1AP_GNBCUConfigurationUpdateIEs_t *ie;
@@ -1783,13 +1784,13 @@ bool decode_f1ap_cu_configuration_update(const F1AP_F1AP_PDU_t *pdu, f1ap_gnb_cu
ie = in->protocolIEs.list.array[i];
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_TransactionID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID);
_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID);
AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1");
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: {
/* Cells to be Activated List (O) */
_F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List);
_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List);
/* Cells to be Activated List Item (count >= 1) */
F1AP_Cells_to_be_Activated_List_t *Cells_to_be_Activated_List = &ie->value.choice.Cells_to_be_Activated_List;
out->num_cells_to_activate = Cells_to_be_Activated_List->list.count;
@@ -1823,21 +1824,21 @@ void free_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t
*/
bool eq_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *a, const f1ap_gnb_cu_configuration_update_t *b)
{
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
/* to activate */
_F1_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate);
_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate);
for (int i = 0; i < a->num_cells_to_activate && i < F1AP_MAX_NB_CELLS; i++) {
_F1_EQ_CHECK_LONG(a->cells_to_activate[i].nr_cellid, b->cells_to_activate[i].nr_cellid);
_F1_EQ_CHECK_INT(a->cells_to_activate[i].nrpci, b->cells_to_activate[i].nrpci);
_EQ_CHECK_LONG(a->cells_to_activate[i].nr_cellid, b->cells_to_activate[i].nr_cellid);
_EQ_CHECK_INT(a->cells_to_activate[i].nrpci, b->cells_to_activate[i].nrpci);
if (!eq_f1ap_plmn(&a->cells_to_activate[i].plmn, &b->cells_to_activate[i].plmn))
return false;
_F1_EQ_CHECK_INT(a->cells_to_activate[i].num_SI, b->cells_to_activate[i].num_SI);
_EQ_CHECK_INT(a->cells_to_activate[i].num_SI, b->cells_to_activate[i].num_SI);
for (int s = 0; s < a->cells_to_activate[i].num_SI; s++) {
f1ap_sib_msg_t *a_sib_msg = &a->cells_to_activate[i].SI_msg[s];
f1ap_sib_msg_t *b_sib_msg = &b->cells_to_activate[i].SI_msg[s];
_F1_EQ_CHECK_INT(*a_sib_msg->SI_container, *b_sib_msg->SI_container);
_F1_EQ_CHECK_INT(a_sib_msg->SI_container_length, b_sib_msg->SI_container_length);
_F1_EQ_CHECK_INT(a_sib_msg->SI_type, b_sib_msg->SI_type);
_EQ_CHECK_INT(*a_sib_msg->SI_container, *b_sib_msg->SI_container);
_EQ_CHECK_INT(a_sib_msg->SI_container_length, b_sib_msg->SI_container_length);
_EQ_CHECK_INT(a_sib_msg->SI_type, b_sib_msg->SI_type);
}
}
return true;
@@ -1925,11 +1926,10 @@ bool decode_f1ap_cu_configuration_update_acknowledge(const F1AP_F1AP_PDU_t *pdu,
f1ap_gnb_cu_configuration_update_acknowledge_t *out)
{
/* Message type */
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
AssertError(pdu->choice.successfulOutcome != NULL, return false, "pdu->choice.successfulOutcome is NULL");
_F1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_gNBCUConfigurationUpdate);
_F1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present,
F1AP_SuccessfulOutcome__value_PR_GNBCUConfigurationUpdateAcknowledge);
_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_gNBCUConfigurationUpdate);
_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, F1AP_SuccessfulOutcome__value_PR_GNBCUConfigurationUpdateAcknowledge);
/* payload */
F1AP_GNBCUConfigurationUpdateAcknowledge_t *in = &pdu->choice.successfulOutcome->value.choice.GNBCUConfigurationUpdateAcknowledge;
F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t *ie;
@@ -1940,14 +1940,13 @@ bool decode_f1ap_cu_configuration_update_acknowledge(const F1AP_F1AP_PDU_t *pdu,
ie = in->protocolIEs.list.array[i];
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_TransactionID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID);
_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID);
AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1");
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_Cells_Failed_to_be_Activated_List: {
/* Decode Cells Failed to be Activated List */
_F1_EQ_CHECK_INT(ie->value.present,
F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_Failed_to_be_Activated_List);
_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_Failed_to_be_Activated_List);
F1AP_Cells_Failed_to_be_Activated_List_t *cell_fail_list = &ie->value.choice.Cells_Failed_to_be_Activated_List;
out->num_cells_failed_to_be_activated = cell_fail_list->list.count;
out->cells_failed_to_be_activated =
@@ -1996,36 +1995,36 @@ bool eq_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration
const f1ap_gnb_cu_configuration_update_acknowledge_t *b)
{
// Transaction ID
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
// number of cells failed to be activated
_F1_EQ_CHECK_INT(a->num_cells_failed_to_be_activated, b->num_cells_failed_to_be_activated);
_EQ_CHECK_INT(a->num_cells_failed_to_be_activated, b->num_cells_failed_to_be_activated);
for (int i = 0; i < a->num_cells_failed_to_be_activated && i < F1AP_MAX_NB_CELLS; i++) {
if (!eq_f1ap_plmn(&a->cells_failed_to_be_activated[i].plmn, &b->cells_failed_to_be_activated[i].plmn))
return false;
_F1_EQ_CHECK_LONG(a->cells_failed_to_be_activated[i].nr_cellid, b->cells_failed_to_be_activated[i].nr_cellid);
_F1_EQ_CHECK_INT(a->cells_failed_to_be_activated[i].cause, b->cells_failed_to_be_activated[i].cause);
_EQ_CHECK_LONG(a->cells_failed_to_be_activated[i].nr_cellid, b->cells_failed_to_be_activated[i].nr_cellid);
_EQ_CHECK_INT(a->cells_failed_to_be_activated[i].cause, b->cells_failed_to_be_activated[i].cause);
}
// TNL Associations to setup
_F1_EQ_CHECK_INT(a->noofTNLAssociations_to_setup, b->noofTNLAssociations_to_setup);
_EQ_CHECK_INT(a->noofTNLAssociations_to_setup, b->noofTNLAssociations_to_setup);
for (int i = 0; i < a->noofTNLAssociations_to_setup && i < F1AP_MAX_NO_OF_TNL_ASSOCIATIONS; i++) {
// Explicit comparison of TNL Association fields
_F1_EQ_CHECK_INT(a->tnlAssociations_to_setup[i].tl_address, b->tnlAssociations_to_setup[i].tl_address);
_F1_EQ_CHECK_INT(a->tnlAssociations_to_setup[i].port, b->tnlAssociations_to_setup[i].port);
_EQ_CHECK_INT(a->tnlAssociations_to_setup[i].tl_address, b->tnlAssociations_to_setup[i].tl_address);
_EQ_CHECK_INT(a->tnlAssociations_to_setup[i].port, b->tnlAssociations_to_setup[i].port);
}
// TNL Associations failed to setup
_F1_EQ_CHECK_INT(a->noofTNLAssociations_failed, b->noofTNLAssociations_failed);
_EQ_CHECK_INT(a->noofTNLAssociations_failed, b->noofTNLAssociations_failed);
for (int i = 0; i < a->noofTNLAssociations_failed && i < F1AP_MAX_NO_OF_TNL_ASSOCIATIONS; i++) {
// Explicit comparison of TNL Association fields
_F1_EQ_CHECK_INT(a->tnlAssociations_failed[i].tl_address, b->tnlAssociations_failed[i].tl_address);
_F1_EQ_CHECK_INT(a->tnlAssociations_failed[i].port, b->tnlAssociations_failed[i].port);
_EQ_CHECK_INT(a->tnlAssociations_failed[i].tl_address, b->tnlAssociations_failed[i].tl_address);
_EQ_CHECK_INT(a->tnlAssociations_failed[i].port, b->tnlAssociations_failed[i].port);
}
// Dedicated SI Delivery Needed UE List
_F1_EQ_CHECK_INT(a->noofDedicatedSIDeliveryNeededUEs, b->noofDedicatedSIDeliveryNeededUEs);
_EQ_CHECK_INT(a->noofDedicatedSIDeliveryNeededUEs, b->noofDedicatedSIDeliveryNeededUEs);
for (int i = 0; i < a->noofDedicatedSIDeliveryNeededUEs && i < F1AP_MAX_NO_UE_ID; i++) {
_F1_EQ_CHECK_INT(a->dedicatedSIDeliveryNeededUEs[i].gNB_CU_ue_id, b->dedicatedSIDeliveryNeededUEs[i].gNB_CU_ue_id);
_EQ_CHECK_INT(a->dedicatedSIDeliveryNeededUEs[i].gNB_CU_ue_id, b->dedicatedSIDeliveryNeededUEs[i].gNB_CU_ue_id);
if (!eq_f1ap_plmn(&a->dedicatedSIDeliveryNeededUEs[i].ue_plmn, &b->dedicatedSIDeliveryNeededUEs[i].ue_plmn))
return false;
_F1_EQ_CHECK_LONG(a->dedicatedSIDeliveryNeededUEs[i].ue_nr_cellid, b->dedicatedSIDeliveryNeededUEs[i].ue_nr_cellid);
_EQ_CHECK_LONG(a->dedicatedSIDeliveryNeededUEs[i].ue_nr_cellid, b->dedicatedSIDeliveryNeededUEs[i].ue_nr_cellid);
}
return true;
}
@@ -2115,11 +2114,10 @@ bool decode_f1ap_du_configuration_update_acknowledge(const F1AP_F1AP_PDU_t *pdu,
f1ap_gnb_du_configuration_update_acknowledge_t *out)
{
/* message type */
_F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome);
AssertError(pdu->choice.successfulOutcome != NULL, return false, "pdu->choice.successfulOutcome is NULL");
_F1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_gNBDUConfigurationUpdate);
_F1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present,
F1AP_SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge);
_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_gNBDUConfigurationUpdate);
_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, F1AP_SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge);
F1AP_GNBDUConfigurationUpdateAcknowledge_t *in = &pdu->choice.successfulOutcome->value.choice.GNBDUConfigurationUpdateAcknowledge;
F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t *ie;
/* Check mandatory IEs */
@@ -2129,13 +2127,13 @@ bool decode_f1ap_du_configuration_update_acknowledge(const F1AP_F1AP_PDU_t *pdu,
ie = in->protocolIEs.list.array[i];
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_TransactionID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID);
_EQ_CHECK_INT(ie->value.present, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID);
AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1");
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: {
/* Decode Cells Failed to be Activated List */
_F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_to_be_Activated_List);
_EQ_CHECK_INT(ie->value.present, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_to_be_Activated_List);
F1AP_Cells_to_be_Activated_List_t *list = &ie->value.choice.Cells_to_be_Activated_List;
out->num_cells_to_activate = list->list.count;
out->cells_to_activate = calloc_or_fail(out->num_cells_to_activate, sizeof(*out->cells_to_activate));
@@ -2161,21 +2159,20 @@ bool eq_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration
const f1ap_gnb_du_configuration_update_acknowledge_t *b)
{
// Transaction ID
_F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
// number of cells to activate
_F1_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate);
_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate);
// loop over cells to activate
for (int i = 0; i < a->num_cells_to_activate && i < F1AP_MAX_NB_CELLS; i++) {
_F1_EQ_CHECK_LONG(a->cells_to_activate[i].nr_cellid, b->cells_to_activate[i].nr_cellid);
_F1_EQ_CHECK_INT(a->cells_to_activate[i].nrpci, b->cells_to_activate[i].nrpci);
_EQ_CHECK_LONG(a->cells_to_activate[i].nr_cellid, b->cells_to_activate[i].nr_cellid);
_EQ_CHECK_INT(a->cells_to_activate[i].nrpci, b->cells_to_activate[i].nrpci);
if (!eq_f1ap_plmn(&a->cells_to_activate[i].plmn, &b->cells_to_activate[i].plmn))
return false;
_F1_EQ_CHECK_INT(a->cells_to_activate[i].num_SI, b->cells_to_activate[i].num_SI);
_EQ_CHECK_INT(a->cells_to_activate[i].num_SI, b->cells_to_activate[i].num_SI);
for (int s = 0; s < a->cells_to_activate[i].num_SI; s++) {
_F1_EQ_CHECK_INT(*a->cells_to_activate[i].SI_msg[s].SI_container, *b->cells_to_activate[i].SI_msg[s].SI_container);
_F1_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_container_length,
b->cells_to_activate[i].SI_msg[s].SI_container_length);
_F1_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_type, b->cells_to_activate[i].SI_msg[s].SI_type);
_EQ_CHECK_INT(*a->cells_to_activate[i].SI_msg[s].SI_container, *b->cells_to_activate[i].SI_msg[s].SI_container);
_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_container_length, b->cells_to_activate[i].SI_msg[s].SI_container_length);
_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_type, b->cells_to_activate[i].SI_msg[s].SI_type);
}
}
return true;
+20 -20
View File
@@ -29,40 +29,40 @@
bool eq_f1ap_plmn(const plmn_id_t *a, const plmn_id_t *b)
{
_F1_EQ_CHECK_INT(a->mcc, b->mcc);
_F1_EQ_CHECK_INT(a->mnc, b->mnc);
_F1_EQ_CHECK_INT(a->mnc_digit_length, b->mnc_digit_length);
_EQ_CHECK_INT(a->mcc, b->mcc);
_EQ_CHECK_INT(a->mnc, b->mnc);
_EQ_CHECK_INT(a->mnc_digit_length, b->mnc_digit_length);
return true;
}
bool eq_f1ap_freq_info(const f1ap_nr_frequency_info_t *a, const f1ap_nr_frequency_info_t *b)
{
_F1_EQ_CHECK_INT(a->arfcn, b->arfcn);
_F1_EQ_CHECK_INT(a->band, b->band);
_EQ_CHECK_INT(a->arfcn, b->arfcn);
_EQ_CHECK_INT(a->band, b->band);
return true;
}
bool eq_f1ap_tx_bandwidth(const f1ap_transmission_bandwidth_t *a, const f1ap_transmission_bandwidth_t *b)
{
_F1_EQ_CHECK_INT(a->nrb, b->nrb);
_F1_EQ_CHECK_INT(a->scs, b->scs);
_EQ_CHECK_INT(a->nrb, b->nrb);
_EQ_CHECK_INT(a->scs, b->scs);
return true;
}
bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_info_t *b)
{
_F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
_F1_EQ_CHECK_INT(a->nr_pci, b->nr_pci);
_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
_EQ_CHECK_INT(a->nr_pci, b->nr_pci);
if ((!a->tac) ^ (!b->tac))
return false;
if (a->tac)
_F1_EQ_CHECK_INT(*a->tac, *b->tac);
_F1_EQ_CHECK_INT(a->num_ssi, b->num_ssi);
_EQ_CHECK_INT(*a->tac, *b->tac);
_EQ_CHECK_INT(a->num_ssi, b->num_ssi);
for (int i = 0; i < a->num_ssi; ++i) {
_F1_EQ_CHECK_INT(a->nssai[i].sst, b->nssai[i].sst);
_F1_EQ_CHECK_INT(a->nssai[i].sd, b->nssai[i].sd);
_EQ_CHECK_INT(a->nssai[i].sst, b->nssai[i].sst);
_EQ_CHECK_INT(a->nssai[i].sd, b->nssai[i].sd);
}
_F1_EQ_CHECK_INT(a->mode, b->mode);
_EQ_CHECK_INT(a->mode, b->mode);
if (a->mode == F1AP_MODE_TDD) {
/* TDD */
if (!eq_f1ap_tx_bandwidth(&a->tdd.tbw, &b->tdd.tbw))
@@ -80,8 +80,8 @@ bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_
if (!eq_f1ap_freq_info(&a->fdd.ul_freqinfo, &b->fdd.ul_freqinfo))
return false;
}
_F1_EQ_CHECK_INT(a->measurement_timing_config_len, b->measurement_timing_config_len);
_F1_EQ_CHECK_INT(*a->measurement_timing_config, *b->measurement_timing_config);
_EQ_CHECK_INT(a->measurement_timing_config_len, b->measurement_timing_config_len);
_EQ_CHECK_INT(*a->measurement_timing_config, *b->measurement_timing_config);
if (!eq_f1ap_plmn(&a->plmn, &b->plmn))
return false;
return true;
@@ -97,13 +97,13 @@ bool eq_f1ap_sys_info(const f1ap_gnb_du_system_info_t *a, const f1ap_gnb_du_syst
return false;
/* MIB */
_F1_EQ_CHECK_INT(a->mib_length, b->mib_length);
_EQ_CHECK_INT(a->mib_length, b->mib_length);
for (int i = 0; i < a->mib_length; i++)
_F1_EQ_CHECK_INT(a->mib[i], b->mib[i]);
_EQ_CHECK_INT(a->mib[i], b->mib[i]);
/* SIB1 */
_F1_EQ_CHECK_INT(a->sib1_length, b->sib1_length);
_EQ_CHECK_INT(a->sib1_length, b->sib1_length);
for (int i = 0; i < a->sib1_length; i++)
_F1_EQ_CHECK_INT(a->sib1[i], b->sib1[i]);
_EQ_CHECK_INT(a->sib1[i], b->sib1[i]);
return true;
}
+1 -25
View File
@@ -32,24 +32,7 @@
#include "F1AP_Cause.h"
#include "F1AP_SNSSAI.h"
#include "f1ap_messages_types.h"
#ifdef ENABLE_TESTS
#define PRINT_ERROR(fmt, ...) fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define PRINT_ERROR(...) // Do nothing
#endif
#define _F1_EQ_CHECK_GENERIC(condition, fmt, ...) \
do { \
if (!(condition)) { \
PRINT_ERROR("Equality condition '%s' failed: " fmt " != " fmt "\n", #condition, ##__VA_ARGS__); \
return false; \
} \
} while (0)
#define _F1_EQ_CHECK_LONG(A, B) _F1_EQ_CHECK_GENERIC(A == B, "%ld", A, B);
#define _F1_EQ_CHECK_INT(A, B) _F1_EQ_CHECK_GENERIC(A == B, "%d", A, B);
#define _F1_EQ_CHECK_STR(A, B) _F1_EQ_CHECK_GENERIC(strcmp(A, B) == 0, "'%s'", A, B);
#include "common/utils/eq_check.h"
#define _F1_CHECK_EXP(EXP) \
do { \
@@ -59,13 +42,6 @@
} \
} while (0)
#define _F1_EQ_CHECK_OPTIONAL_IE(A, B, FIELD, EQ_MACRO) \
do { \
_F1_CHECK_EXP(((A)->FIELD && (B)->FIELD) || (!(A)->FIELD && !(B)->FIELD)); \
if ((A)->FIELD && (B)->FIELD) \
EQ_MACRO(*(A)->FIELD, *(B)->FIELD); \
} while (0)
/* macro to look up IE. If mandatory and not found, macro will print
* descriptive debug message to stderr and force exit in calling function */
#define F1AP_LIB_FIND_IE(IE_TYPE, ie, IE_LIST, IE_ID, mandatory) \
+4
View File
@@ -90,5 +90,9 @@
#include "F1AP_UL-RTOA-Measurement.h"
#include "F1AP_GNB-RxTxTimeDiff.h"
#include "F1AP_LCS-to-GCS-TranslationAoA.h"
#include "F1AP_CNUEPagingIdentity.h"
#include "F1AP_RANUEPagingIdentity.h"
#include "F1AP_PagingIdentity.h"
#include "F1AP_Paging.h"
#endif /* F1AP_LIB_INCLUDES_H_ */
+349
View File
@@ -0,0 +1,349 @@
/*
* 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 <string.h>
#include "common/utils/assertions.h"
#include "openair3/UTILS/conversions.h"
#include "common/utils/oai_asn1.h"
#include "common/utils/utils.h"
#include "f1ap_paging.h"
#include "f1ap_lib_common.h"
#include "f1ap_lib_includes.h"
#include "f1ap_messages_types.h"
/** @brief encode to F1AP_PagingDRX_t */
static F1AP_PagingDRX_t encode_f1_paging_drx(const f1ap_paging_drx_t drx)
{
switch (drx) {
case F1AP_PAGING_DRX_32:
return F1AP_PagingDRX_v32;
case F1AP_PAGING_DRX_64:
return F1AP_PagingDRX_v64;
case F1AP_PAGING_DRX_128:
return F1AP_PagingDRX_v128;
case F1AP_PAGING_DRX_256:
return F1AP_PagingDRX_v256;
default:
AssertFatal(1 == 0, "Unknown Paging DRX: %u\n", drx);
}
return 0;
}
/** @brief decode from F1AP_PagingDRX_t */
static f1ap_paging_drx_t decode_f1_paging_drx(const F1AP_PagingDRX_t drx)
{
switch (drx) {
case F1AP_PagingDRX_v32:
return F1AP_PAGING_DRX_32;
case F1AP_PagingDRX_v64:
return F1AP_PAGING_DRX_64;
case F1AP_PagingDRX_v128:
return F1AP_PAGING_DRX_128;
case F1AP_PagingDRX_v256:
return F1AP_PAGING_DRX_256;
default:
AssertFatal(1 == 0, "Unknown Paging DRX: %ld\n", drx);
}
return 0;
}
/** @brief encode F1 Paging (9.2.6 Paging 3GPP TS 38.473) */
F1AP_F1AP_PDU_t *encode_f1ap_paging(const f1ap_paging_t *msg)
{
DevAssert(msg);
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu->choice.initiatingMessage, initMsg);
initMsg->procedureCode = F1AP_ProcedureCode_id_Paging;
initMsg->criticality = F1AP_Criticality_reject;
initMsg->value.present = F1AP_InitiatingMessage__value_PR_Paging;
F1AP_Paging_t *paging = &initMsg->value.choice.Paging;
/* UEIdentityIndexValue (Mandatory) 10 bits */
{
AssertFatal(msg->ue_identity_index_value <= 1023,
"UE Identity Index Value exceeds 10 bits: %d\n",
msg->ue_identity_index_value);
asn1cSequenceAdd(paging->protocolIEs.list, F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_UEIdentityIndexValue;
ie->criticality = F1AP_Criticality_reject;
ie->value.present = F1AP_PagingIEs__value_PR_UEIdentityIndexValue;
F1AP_UEIdentityIndexValue_t *ue_identity_index = &ie->value.choice.UEIdentityIndexValue;
ue_identity_index->present = F1AP_UEIdentityIndexValue_PR_indexLength10;
UEIDENTITYINDEX_TO_BIT_STRING(msg->ue_identity_index_value, &ue_identity_index->choice.indexLength10);
}
/* PagingIdentity (Mandatory) */
{
asn1cSequenceAdd(paging->protocolIEs.list, F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingIdentity;
ie->criticality = F1AP_Criticality_reject;
ie->value.present = F1AP_PagingIEs__value_PR_PagingIdentity;
F1AP_PagingIdentity_t *paging_identity = &ie->value.choice.PagingIdentity;
const f1ap_paging_identity_t *paging_id = &msg->identity;
if (msg->identity_type == F1AP_PAGING_IDENTITY_CN_UE) {
// CN UE Paging Identity (5G-S-TMSI)
paging_identity->present = F1AP_PagingIdentity_PR_cNUEPagingIdentity;
asn1cCalloc(paging_identity->choice.cNUEPagingIdentity, id);
id->present = F1AP_CNUEPagingIdentity_PR_fiveG_S_TMSI;
FIVEG_S_TMSI_TO_BIT_STRING(paging_id->cn_ue_paging_identity, &id->choice.fiveG_S_TMSI);
} else {
// RAN UE Paging Identity (I-RNTI)
paging_identity->present = F1AP_PagingIdentity_PR_rANUEPagingIdentity;
asn1cCalloc(paging_identity->choice.rANUEPagingIdentity, ran_id);
// I-RNTI is 40 bits, stored in 5 bytes
IRNTI_TO_BIT_STRING(paging_id->ran_ue_paging_identity, &ran_id->iRNTI);
}
}
/* Paging Priority (Optional) */
if (msg->priority != NULL) {
AssertFatal(*msg->priority >= F1AP_PAGING_PRIO_LEVEL1 && *msg->priority <= F1AP_PAGING_PRIO_LEVEL8,
"Unknown Paging Priority: %d\n",
*msg->priority);
asn1cSequenceAdd(paging->protocolIEs.list, F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingPriority;
ie->criticality = F1AP_Criticality_ignore;
ie->value.present = F1AP_PagingIEs__value_PR_PagingPriority;
ie->value.choice.PagingPriority = (F1AP_PagingPriority_t)*msg->priority;
}
/* Paging Origin (Optional) */
if (msg->origin != NULL) {
AssertFatal(*msg->origin == F1AP_PAGING_ORIGIN_NON_3GPP, "Unknown Paging Origin: %d\n", *msg->origin);
asn1cSequenceAdd(paging->protocolIEs.list, F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingOrigin;
ie->criticality = F1AP_Criticality_ignore;
ie->value.present = F1AP_PagingIEs__value_PR_PagingOrigin;
ie->value.choice.PagingOrigin = F1AP_PagingOrigin_non_3gpp;
}
/* PagingDRX (Optional) */
if (msg->drx != NULL) {
asn1cSequenceAdd(paging->protocolIEs.list, F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingDRX;
ie->criticality = F1AP_Criticality_ignore;
ie->value.present = F1AP_PagingIEs__value_PR_PagingDRX;
ie->value.choice.PagingDRX = encode_f1_paging_drx(*msg->drx);
}
/* PagingCell_list (Mandatory) */
{
AssertFatal(msg->n_cells > 0 && msg->n_cells <= F1AP_MAX_NB_CELLS,
"invalid n_cells %u (must be 1..%d)\n",
msg->n_cells,
F1AP_MAX_NB_CELLS);
DevAssert(msg->cells != NULL);
asn1cSequenceAdd(paging->protocolIEs.list, F1AP_PagingIEs_t, ie);
ie->id = F1AP_ProtocolIE_ID_id_PagingCell_List;
ie->criticality = F1AP_Criticality_reject;
ie->value.present = F1AP_PagingIEs__value_PR_PagingCell_list;
// Add all cells in the paging cell list
for (uint16_t cell_idx = 0; cell_idx < msg->n_cells; cell_idx++) {
asn1cSequenceAdd(ie->value.choice.PagingCell_list, F1AP_PagingCell_ItemIEs_t, item);
item->id = F1AP_ProtocolIE_ID_id_PagingCell_Item;
item->criticality = F1AP_Criticality_reject;
item->value.present = F1AP_PagingCell_ItemIEs__value_PR_PagingCell_Item;
// NRCGI (Mandatory)
F1AP_NRCGI_t *nRCGI = &item->value.choice.PagingCell_Item.nRCGI;
const f1ap_paging_cell_item_t *cell = &msg->cells[cell_idx];
MCC_MNC_TO_PLMNID(cell->plmn.mcc, cell->plmn.mnc, cell->plmn.mnc_digit_length, &nRCGI->pLMN_Identity);
NR_CELL_ID_TO_BIT_STRING(cell->nr_cellid, &nRCGI->nRCellIdentity);
}
}
return pdu;
}
/** @brief decode F1 Paging (9.2.6 Paging 3GPP TS 38.473) */
bool decode_f1ap_paging(f1ap_paging_t *out, const F1AP_F1AP_PDU_t *pdu)
{
DevAssert(out);
DevAssert(pdu);
DevAssert(pdu->choice.initiatingMessage);
memset(out, 0, sizeof(*out));
_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage);
_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_Paging);
_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_Paging);
/* Check presence of mandatory IEs */
const F1AP_Paging_t *in = &pdu->choice.initiatingMessage->value.choice.Paging;
F1AP_PagingIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PagingIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_UEIdentityIndexValue, true);
F1AP_LIB_FIND_IE(F1AP_PagingIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_PagingIdentity, true);
F1AP_LIB_FIND_IE(F1AP_PagingIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_PagingCell_List, true);
/* Loop over all IEs */
for (int i = 0; i < in->protocolIEs.list.count; i++) {
DevAssert(in->protocolIEs.list.array[i] != NULL);
ie = in->protocolIEs.list.array[i];
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_UEIdentityIndexValue:
// (M) UE Identity Index Value
_EQ_CHECK_INT(ie->value.present, F1AP_PagingIEs__value_PR_UEIdentityIndexValue);
out->ue_identity_index_value = BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue.choice.indexLength10);
break;
case F1AP_ProtocolIE_ID_id_PagingIdentity:
// (M) Paging Identity
_EQ_CHECK_INT(ie->value.present, F1AP_PagingIEs__value_PR_PagingIdentity);
if (ie->value.choice.PagingIdentity.present == F1AP_PagingIdentity_PR_cNUEPagingIdentity) {
// CN UE Paging Identity (5G-S-TMSI)
out->identity_type = F1AP_PAGING_IDENTITY_CN_UE;
BIT_STRING_t *fiveg_tmsi = &ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI;
out->identity.cn_ue_paging_identity = BIT_STRING_to_uint64(fiveg_tmsi);
} else if (ie->value.choice.PagingIdentity.present == F1AP_PagingIdentity_PR_rANUEPagingIdentity) {
// RAN UE Paging Identity (I-RNTI)
out->identity_type = F1AP_PAGING_IDENTITY_RAN_UE;
BIT_STRING_t *irnti = &ie->value.choice.PagingIdentity.choice.rANUEPagingIdentity->iRNTI;
out->identity.ran_ue_paging_identity = BIT_STRING_to_uint64(irnti);
} else {
PRINT_ERROR("Unknown PagingIdentity type: %d\n", ie->value.choice.PagingIdentity.present);
return false;
}
break;
case F1AP_ProtocolIE_ID_id_PagingDRX:
// (O) Paging DRX
_EQ_CHECK_INT(ie->value.present, F1AP_PagingIEs__value_PR_PagingDRX);
out->drx = malloc_or_fail(sizeof(*out->drx));
*out->drx = decode_f1_paging_drx(ie->value.choice.PagingDRX);
break;
case F1AP_ProtocolIE_ID_id_PagingPriority:
// (O) Paging Priority
_EQ_CHECK_INT(ie->value.present, F1AP_PagingIEs__value_PR_PagingPriority);
AssertFatal(ie->value.choice.PagingPriority >= F1AP_PagingPriority_priolevel1
&& ie->value.choice.PagingPriority <= F1AP_PagingPriority_priolevel8,
"Unknown Paging Priority: %ld\n",
ie->value.choice.PagingPriority);
out->priority = malloc_or_fail(sizeof(*out->priority));
*out->priority = (f1ap_paging_priority_t)ie->value.choice.PagingPriority;
break;
case F1AP_ProtocolIE_ID_id_PagingOrigin:
// (O) Paging Origin
_EQ_CHECK_INT(ie->value.present, F1AP_PagingIEs__value_PR_PagingOrigin);
AssertFatal(ie->value.choice.PagingOrigin == F1AP_PagingOrigin_non_3gpp,
"Unknown Paging Origin: %ld\n",
ie->value.choice.PagingOrigin);
out->origin = malloc_or_fail(sizeof(*out->origin));
*out->origin = F1AP_PAGING_ORIGIN_NON_3GPP;
break;
case F1AP_ProtocolIE_ID_id_PagingCell_List:
// (M) Paging Cell List (max 512 cells)
_EQ_CHECK_INT(ie->value.present, F1AP_PagingIEs__value_PR_PagingCell_list);
out->n_cells = ie->value.choice.PagingCell_list.list.count;
AssertError(out->n_cells > 0, return false, "at least 1 cell must be present");
AssertError(out->n_cells <= F1AP_MAX_NB_CELLS, return false, "too many cells");
out->cells = calloc_or_fail(out->n_cells, sizeof(*out->cells));
for (int j = 0; j < out->n_cells; j++) {
F1AP_PagingCell_ItemIEs_t *cell_item = (F1AP_PagingCell_ItemIEs_t *)ie->value.choice.PagingCell_list.list.array[j];
DevAssert(cell_item);
F1AP_NRCGI_t *nRCGI = &cell_item->value.choice.PagingCell_Item.nRCGI;
f1ap_paging_cell_item_t *cell = &out->cells[j];
PLMNID_TO_MCC_MNC(&nRCGI->pLMN_Identity, cell->plmn.mcc, cell->plmn.mnc, cell->plmn.mnc_digit_length);
BIT_STRING_TO_NR_CELL_IDENTITY(&nRCGI->nRCellIdentity, cell->nr_cellid);
}
break;
default:
AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", ie->id);
break;
}
}
return true;
}
/** @brief free F1 Paging */
void free_f1ap_paging(f1ap_paging_t *msg)
{
DevAssert(msg);
free(msg->drx);
free(msg->priority);
free(msg->origin);
free(msg->cells);
}
/** @brief Equality check for two F1 Paging */
bool eq_f1ap_paging(const f1ap_paging_t *a, const f1ap_paging_t *b)
{
DevAssert(a);
DevAssert(b);
_EQ_CHECK_INT(a->ue_identity_index_value, b->ue_identity_index_value);
_EQ_CHECK_INT(a->identity_type, b->identity_type);
if (a->identity_type == F1AP_PAGING_IDENTITY_CN_UE) {
_EQ_CHECK_LONG(a->identity.cn_ue_paging_identity, b->identity.cn_ue_paging_identity);
} else {
_EQ_CHECK_LONG(a->identity.ran_ue_paging_identity, b->identity.ran_ue_paging_identity);
}
_EQ_CHECK_OPTIONAL_IE(a, b, drx, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, priority, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, origin, _EQ_CHECK_INT);
_EQ_CHECK_INT(a->n_cells, b->n_cells);
if ((a->n_cells > 0 && (a->cells == NULL || b->cells == NULL)))
return false;
for (int i = 0; i < a->n_cells; i++) {
if (!eq_f1ap_plmn(&a->cells[i].plmn, &b->cells[i].plmn))
return false;
_EQ_CHECK_LONG(a->cells[i].nr_cellid, b->cells[i].nr_cellid);
}
return true;
}
/** @brief deep copy F1 Paging */
f1ap_paging_t cp_f1ap_paging(const f1ap_paging_t *orig)
{
DevAssert(orig);
f1ap_paging_t cp = {0};
cp.ue_identity_index_value = orig->ue_identity_index_value;
cp.identity_type = orig->identity_type;
cp.identity = orig->identity;
if (orig->drx != NULL) {
cp.drx = malloc_or_fail(sizeof(*cp.drx));
*cp.drx = *orig->drx;
}
if (orig->priority != NULL) {
cp.priority = malloc_or_fail(sizeof(*cp.priority));
*cp.priority = *orig->priority;
}
if (orig->origin != NULL) {
cp.origin = malloc_or_fail(sizeof(*cp.origin));
*cp.origin = *orig->origin;
}
cp.n_cells = orig->n_cells;
if (cp.n_cells > 0) {
DevAssert(orig->cells != NULL);
cp.cells = calloc_or_fail(cp.n_cells, sizeof(*cp.cells));
for (int i = 0; i < cp.n_cells; i++) {
cp.cells[i] = orig->cells[i];
}
}
return cp;
}
+37
View File
@@ -0,0 +1,37 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef F1AP_PAGING_H_
#define F1AP_PAGING_H_
#include <stdbool.h>
#include "f1ap_messages_types.h"
struct F1AP_F1AP_PDU;
/* F1 Paging */
struct F1AP_F1AP_PDU *encode_f1ap_paging(const f1ap_paging_t *msg);
bool decode_f1ap_paging(f1ap_paging_t *out, const struct F1AP_F1AP_PDU *pdu);
void free_f1ap_paging(f1ap_paging_t *msg);
bool eq_f1ap_paging(const f1ap_paging_t *a, const f1ap_paging_t *b);
f1ap_paging_t cp_f1ap_paging(const f1ap_paging_t *orig);
#endif /* F1AP_PAGING_H_ */
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -172,19 +172,19 @@ f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_init
*/
bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, const f1ap_initial_ul_rrc_message_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
if (!eq_f1ap_plmn(&a->plmn, &b->plmn))
return false;
_F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
_F1_EQ_CHECK_INT(a->crnti, b->crnti);
_F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
_F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
_EQ_CHECK_INT(a->crnti, b->crnti);
_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0)
return false;
_F1_EQ_CHECK_INT(a->du2cu_rrc_container_length, b->du2cu_rrc_container_length);
_EQ_CHECK_INT(a->du2cu_rrc_container_length, b->du2cu_rrc_container_length);
if (memcmp(a->du2cu_rrc_container, b->du2cu_rrc_container, a->du2cu_rrc_container_length) != 0)
return false;
_F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
return true;
}
@@ -300,10 +300,10 @@ f1ap_ul_rrc_message_t cp_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *ms
*/
bool eq_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *a, const f1ap_ul_rrc_message_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0)
return false;
return true;
@@ -456,16 +456,16 @@ f1ap_dl_rrc_message_t cp_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *ms
*/
bool eq_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *a, const f1ap_dl_rrc_message_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
if (!(a->old_gNB_DU_ue_id == NULL && b->old_gNB_DU_ue_id == NULL))
_F1_EQ_CHECK_INT(*a->old_gNB_DU_ue_id, *b->old_gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->srb_id, b->srb_id);
_F1_EQ_CHECK_INT(a->execute_duplication, b->execute_duplication);
_F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
_EQ_CHECK_INT(*a->old_gNB_DU_ue_id, *b->old_gNB_DU_ue_id);
_EQ_CHECK_INT(a->srb_id, b->srb_id);
_EQ_CHECK_INT(a->execute_duplication, b->execute_duplication);
_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length);
if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0)
return false;
return true;
+159 -159
View File
@@ -144,11 +144,11 @@ static bool eq_ba(const byte_array_t a, const byte_array_t b)
static bool eq_cu_to_du_rrc_info(const f1ap_cu_to_du_rrc_info_t *a, const f1ap_cu_to_du_rrc_info_t *b)
{
_F1_EQ_CHECK_OPTIONAL_IE(a, b, cg_configinfo, eq_ba);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, ue_cap, eq_ba);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, meas_config, eq_ba);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, meas_timing_config, eq_ba);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, ho_prep_info, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, cg_configinfo, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, ue_cap, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, meas_config, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, meas_timing_config, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, ho_prep_info, eq_ba);
return true;
}
@@ -203,7 +203,7 @@ static f1ap_du_to_cu_rrc_info_t cp_du_to_cu_rrc_info(const f1ap_du_to_cu_rrc_inf
static bool eq_du_to_cu_rrc_info(const f1ap_du_to_cu_rrc_info_t *a, const f1ap_du_to_cu_rrc_info_t *b)
{
_F1_CHECK_EXP(eq_byte_array(&a->cell_group_config, &b->cell_group_config));
_F1_EQ_CHECK_OPTIONAL_IE(a, b, meas_gap_config, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, meas_gap_config, eq_ba);
return true;
}
@@ -257,8 +257,8 @@ static bool decode_srbs_to_setup(const F1AP_SRBs_ToBeSetup_List_t *f1ap, int *n,
f1ap_srb_to_setup_t *srbs = *out = calloc_or_fail(count, sizeof(*srbs));
for (int i = 0; i < count; ++i) {
const F1AP_SRBs_ToBeSetup_ItemIEs_t *itie = (F1AP_SRBs_ToBeSetup_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item);
srbs[i].id = itie->value.choice.SRBs_ToBeSetup_Item.sRBID;
}
@@ -279,8 +279,8 @@ static bool decode_srbs_to_setupmod(const F1AP_SRBs_ToBeSetupMod_List_t *f1ap, i
f1ap_srb_to_setup_t *srbs = *out = calloc_or_fail(count, sizeof(*srbs));
for (int i = 0; i < count; ++i) {
const F1AP_SRBs_ToBeSetupMod_ItemIEs_t *itie = (F1AP_SRBs_ToBeSetupMod_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item);
srbs[i].id = itie->value.choice.SRBs_ToBeSetupMod_Item.sRBID;
}
@@ -297,7 +297,7 @@ static f1ap_srb_to_setup_t cp_srb_to_setup(const f1ap_srb_to_setup_t *orig)
static bool eq_srb_to_setup(const f1ap_srb_to_setup_t *a, const f1ap_srb_to_setup_t *b)
{
_F1_EQ_CHECK_INT(a->id, b->id);
_EQ_CHECK_INT(a->id, b->id);
return true;
}
@@ -347,8 +347,8 @@ static bool decode_srbs_setup(const F1AP_SRBs_Setup_List_t *f1ap, int *n, f1ap_s
f1ap_srb_setup_t *srbs = *out = calloc_or_fail(count, sizeof(*srbs));
for (int i = 0; i < count; ++i) {
const F1AP_SRBs_Setup_ItemIEs_t *itie = (F1AP_SRBs_Setup_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_Setup_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_Setup_ItemIEs__value_PR_SRBs_Setup_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_Setup_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_Setup_ItemIEs__value_PR_SRBs_Setup_Item);
const F1AP_SRBs_Setup_Item_t *it = &itie->value.choice.SRBs_Setup_Item;
srbs[i].id = it->sRBID;
srbs[i].lcid = it->lCID;
@@ -367,8 +367,8 @@ static bool decode_srbs_setupmod(const F1AP_SRBs_SetupMod_List_t *f1ap, int *n,
f1ap_srb_setup_t *srbs = *out = calloc_or_fail(count, sizeof(*srbs));
for (int i = 0; i < count; ++i) {
const F1AP_SRBs_SetupMod_ItemIEs_t *itie = (F1AP_SRBs_SetupMod_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_SetupMod_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_SetupMod_ItemIEs__value_PR_SRBs_SetupMod_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_SRBs_SetupMod_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_SRBs_SetupMod_ItemIEs__value_PR_SRBs_SetupMod_Item);
const F1AP_SRBs_SetupMod_Item_t *it = &itie->value.choice.SRBs_SetupMod_Item;
srbs[i].id = it->sRBID;
srbs[i].lcid = it->lCID;
@@ -384,8 +384,8 @@ static f1ap_srb_setup_t cp_srb_setup(const f1ap_srb_setup_t *orig)
static bool eq_srb_setup(const f1ap_srb_setup_t *a, const f1ap_srb_setup_t *b)
{
_F1_EQ_CHECK_INT(a->id, b->id);
_F1_EQ_CHECK_INT(a->lcid, b->lcid);
_EQ_CHECK_INT(a->id, b->id);
_EQ_CHECK_INT(a->lcid, b->lcid);
return true;
}
@@ -437,7 +437,7 @@ static bool decode_qos_flow_param(const F1AP_QoSFlowLevelQoSParameters_t *f1ap,
const F1AP_NonDynamic5QIDescriptor_t *nondyn = f1ap->qoS_Characteristics.choice.non_Dynamic_5QI;
out->nondyn.fiveQI = nondyn->fiveQI;
} else {
_F1_EQ_CHECK_INT(f1ap->qoS_Characteristics.present, F1AP_QoS_Characteristics_PR_dynamic_5QI);
_EQ_CHECK_INT(f1ap->qoS_Characteristics.present, F1AP_QoS_Characteristics_PR_dynamic_5QI);
const F1AP_Dynamic5QIDescriptor_t *d = f1ap->qoS_Characteristics.choice.dynamic_5QI;
out->qos_type = DYNAMIC;
out->dyn.prio = d->qoSPriorityLevel;
@@ -488,23 +488,23 @@ static f1ap_qos_flow_param_t cp_qos_flow_param(const f1ap_qos_flow_param_t *orig
static bool eq_qos_flow_param(const f1ap_qos_flow_param_t *a, const f1ap_qos_flow_param_t *b)
{
_F1_EQ_CHECK_INT(a->qos_type, b->qos_type);
_EQ_CHECK_INT(a->qos_type, b->qos_type);
if (a->qos_type == NON_DYNAMIC) {
_F1_EQ_CHECK_INT(a->nondyn.fiveQI, b->nondyn.fiveQI);
_EQ_CHECK_INT(a->nondyn.fiveQI, b->nondyn.fiveQI);
} else {
DevAssert(a->qos_type == DYNAMIC);
DevAssert(b->qos_type == DYNAMIC);
const f1ap_dynamic_5qi_t *adyn = &a->dyn, *bdyn = &b->dyn;
_F1_EQ_CHECK_INT(adyn->prio, bdyn->prio);
_F1_EQ_CHECK_INT(adyn->pdb, bdyn->pdb);
_F1_EQ_CHECK_INT(adyn->per.scalar, bdyn->per.scalar);
_F1_EQ_CHECK_INT(adyn->per.exponent, bdyn->per.exponent);
_F1_EQ_CHECK_OPTIONAL_IE(adyn, bdyn, delay_critical, _F1_EQ_CHECK_INT);
_F1_EQ_CHECK_OPTIONAL_IE(adyn, bdyn, avg_win, _F1_EQ_CHECK_INT);
_EQ_CHECK_INT(adyn->prio, bdyn->prio);
_EQ_CHECK_INT(adyn->pdb, bdyn->pdb);
_EQ_CHECK_INT(adyn->per.scalar, bdyn->per.scalar);
_EQ_CHECK_INT(adyn->per.exponent, bdyn->per.exponent);
_EQ_CHECK_OPTIONAL_IE(adyn, bdyn, delay_critical, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(adyn, bdyn, avg_win, _EQ_CHECK_INT);
}
_F1_EQ_CHECK_INT(a->arp.prio, b->arp.prio);
_F1_EQ_CHECK_INT(a->arp.preempt_cap, b->arp.preempt_cap);
_F1_EQ_CHECK_INT(a->arp.preempt_vuln, b->arp.preempt_vuln);
_EQ_CHECK_INT(a->arp.prio, b->arp.prio);
_EQ_CHECK_INT(a->arp.preempt_cap, b->arp.preempt_cap);
_EQ_CHECK_INT(a->arp.preempt_vuln, b->arp.preempt_vuln);
return true;
}
@@ -569,11 +569,11 @@ static f1ap_drb_info_nr_t cp_drb_info_nr(const f1ap_drb_info_nr_t *orig)
static bool eq_drb_info_nr(const f1ap_drb_info_nr_t *a, const f1ap_drb_info_nr_t *b)
{
_F1_CHECK_EXP(eq_qos_flow_param(&a->drb_qos, &b->drb_qos));
_F1_EQ_CHECK_INT(a->nssai.sst, b->nssai.sst);
_F1_EQ_CHECK_INT(a->nssai.sd, b->nssai.sd);
_F1_EQ_CHECK_INT(a->flows_len, b->flows_len);
_EQ_CHECK_INT(a->nssai.sst, b->nssai.sst);
_EQ_CHECK_INT(a->nssai.sd, b->nssai.sd);
_EQ_CHECK_INT(a->flows_len, b->flows_len);
for (int i = 0; i < a->flows_len; ++i) {
_F1_EQ_CHECK_INT(a->flows[i].qfi, b->flows[i].qfi);
_EQ_CHECK_INT(a->flows[i].qfi, b->flows[i].qfi);
_F1_CHECK_EXP(eq_qos_flow_param(&a->flows[i].param, &b->flows[i].param));
}
return true;
@@ -629,7 +629,7 @@ static F1AP_UPTransportLayerInformation_t encode_up_tnl(const f1ap_up_tnl_t *tnl
static bool decode_up_tnl(const F1AP_UPTransportLayerInformation_t *tnl_info, f1ap_up_tnl_t *out)
{
_F1_EQ_CHECK_INT(tnl_info->present, F1AP_UPTransportLayerInformation_PR_gTPTunnel);
_EQ_CHECK_INT(tnl_info->present, F1AP_UPTransportLayerInformation_PR_gTPTunnel);
const F1AP_GTPTunnel_t *gtp_tnl = tnl_info->choice.gTPTunnel;
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gtp_tnl->transportLayerAddress, out->tl_address);
OCTET_STRING_TO_UINT32(&gtp_tnl->gTP_TEID, out->teid);
@@ -649,7 +649,7 @@ static bool eq_up_tnl(const f1ap_up_tnl_t *a, const f1ap_up_tnl_t *b)
PRINT_ERROR("tl_address mismatch\n");
return false;
}
_F1_EQ_CHECK_INT(a->teid, b->teid);
_EQ_CHECK_INT(a->teid, b->teid);
return true;
}
@@ -780,22 +780,22 @@ static bool decode_drbs_to_setup(const F1AP_DRBs_ToBeSetup_List_t *f1ap, int *n,
f1ap_drb_to_setup_t *drbs = *out = calloc_or_fail(count, sizeof(*drbs));
for (int i = 0; i < count; ++i) {
const F1AP_DRBs_ToBeSetup_ItemIEs_t *itie = (const F1AP_DRBs_ToBeSetup_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item);
const F1AP_DRBs_ToBeSetup_Item_t *it = &itie->value.choice.DRBs_ToBeSetup_Item;
f1ap_drb_to_setup_t *drb = &drbs[i];
drb->id = it->dRBID;
_F1_EQ_CHECK_INT(it->qoSInformation.present, F1AP_QoSInformation_PR_choice_extension);
_EQ_CHECK_INT(it->qoSInformation.present, F1AP_QoSInformation_PR_choice_extension);
const F1AP_QoSInformation_ExtIEs_t *qos_ext = (F1AP_QoSInformation_ExtIEs_t *)it->qoSInformation.choice.choice_extension;
_F1_EQ_CHECK_LONG(qos_ext->id, F1AP_ProtocolIE_ID_id_DRB_Information);
_F1_EQ_CHECK_INT(qos_ext->value.present, F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information);
_EQ_CHECK_LONG(qos_ext->id, F1AP_ProtocolIE_ID_id_DRB_Information);
_EQ_CHECK_INT(qos_ext->value.present, F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information);
drb->qos_choice = F1AP_QOS_CHOICE_NR;
_F1_CHECK_EXP(decode_drb_info_nr(&qos_ext->value.choice.DRB_Information, &drb->nr));
drb->up_ul_tnl_len = it->uLUPTNLInformation_ToBeSetup_List.list.count;
_F1_EQ_CHECK_GENERIC(drb->up_ul_tnl_len > 0 && drb->up_ul_tnl_len <= 2, "%d", drb->up_ul_tnl_len, 1);
EQ_CHECK_GENERIC(drb->up_ul_tnl_len > 0 && drb->up_ul_tnl_len <= 2, "%d", drb->up_ul_tnl_len, 1);
for (int j = 0; j < drb->up_ul_tnl_len; ++j) {
const F1AP_ULUPTNLInformation_ToBeSetup_Item_t *it_tnl = it->uLUPTNLInformation_ToBeSetup_List.list.array[j];
_F1_CHECK_EXP(decode_up_tnl(&it_tnl->uLUPTNLInformation, &drb->up_ul_tnl[j]));
@@ -813,11 +813,11 @@ static bool decode_drbs_to_setup(const F1AP_DRBs_ToBeSetup_List_t *f1ap, int *n,
AssertError(ie != NULL, return false, "ext->list.array[j] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_DLPDCPSNLength:
_F1_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetup_ItemExtIEs__extensionValue_PR_PDCPSNLength);
_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetup_ItemExtIEs__extensionValue_PR_PDCPSNLength);
_F1_MALLOC(drb->dl_pdcp_sn_len, ie->extensionValue.choice.PDCPSNLength);
break;
case F1AP_ProtocolIE_ID_id_ULPDCPSNLength:
_F1_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetup_ItemExtIEs__extensionValue_PR_PDCPSNLength_1);
_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetup_ItemExtIEs__extensionValue_PR_PDCPSNLength_1);
_F1_MALLOC(drb->ul_pdcp_sn_len, ie->extensionValue.choice.PDCPSNLength_1);
break;
default:
@@ -845,22 +845,22 @@ static bool decode_drbs_to_setupmod(const F1AP_DRBs_ToBeSetupMod_List_t *f1ap, i
f1ap_drb_to_setup_t *drbs = *out = calloc_or_fail(count, sizeof(*drbs));
for (int i = 0; i < count; ++i) {
const F1AP_DRBs_ToBeSetupMod_ItemIEs_t *itie = (const F1AP_DRBs_ToBeSetupMod_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item);
const F1AP_DRBs_ToBeSetupMod_Item_t *it = &itie->value.choice.DRBs_ToBeSetupMod_Item;
f1ap_drb_to_setup_t *drb = &drbs[i];
drb->id = it->dRBID;
_F1_EQ_CHECK_INT(it->qoSInformation.present, F1AP_QoSInformation_PR_choice_extension);
_EQ_CHECK_INT(it->qoSInformation.present, F1AP_QoSInformation_PR_choice_extension);
const F1AP_QoSInformation_ExtIEs_t *qos_ext = (F1AP_QoSInformation_ExtIEs_t *)it->qoSInformation.choice.choice_extension;
_F1_EQ_CHECK_LONG(qos_ext->id, F1AP_ProtocolIE_ID_id_DRB_Information);
_F1_EQ_CHECK_INT(qos_ext->value.present, F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information);
_EQ_CHECK_LONG(qos_ext->id, F1AP_ProtocolIE_ID_id_DRB_Information);
_EQ_CHECK_INT(qos_ext->value.present, F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information);
drb->qos_choice = F1AP_QOS_CHOICE_NR;
_F1_CHECK_EXP(decode_drb_info_nr(&qos_ext->value.choice.DRB_Information, &drb->nr));
drb->up_ul_tnl_len = it->uLUPTNLInformation_ToBeSetup_List.list.count;
_F1_EQ_CHECK_GENERIC(drb->up_ul_tnl_len > 0 && drb->up_ul_tnl_len <= 2, "%d", drb->up_ul_tnl_len, 1);
EQ_CHECK_GENERIC(drb->up_ul_tnl_len > 0 && drb->up_ul_tnl_len <= 2, "%d", drb->up_ul_tnl_len, 1);
for (int j = 0; j < drb->up_ul_tnl_len; ++j) {
const F1AP_ULUPTNLInformation_ToBeSetup_Item_t *it_tnl = it->uLUPTNLInformation_ToBeSetup_List.list.array[j];
_F1_CHECK_EXP(decode_up_tnl(&it_tnl->uLUPTNLInformation, &drb->up_ul_tnl[j]));
@@ -878,11 +878,11 @@ static bool decode_drbs_to_setupmod(const F1AP_DRBs_ToBeSetupMod_List_t *f1ap, i
AssertError(ie != NULL, return false, "ext->list.array[j] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_DLPDCPSNLength:
_F1_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetupMod_ItemExtIEs__extensionValue_PR_PDCPSNLength);
_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetupMod_ItemExtIEs__extensionValue_PR_PDCPSNLength);
_F1_MALLOC(drb->dl_pdcp_sn_len, ie->extensionValue.choice.PDCPSNLength);
break;
case F1AP_ProtocolIE_ID_id_ULPDCPSNLength:
_F1_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetupMod_ItemExtIEs__extensionValue_PR_PDCPSNLength_1);
_EQ_CHECK_INT(ie->extensionValue.present, F1AP_DRBs_ToBeSetupMod_ItemExtIEs__extensionValue_PR_PDCPSNLength_1);
_F1_MALLOC(drb->ul_pdcp_sn_len, ie->extensionValue.choice.PDCPSNLength_1);
break;
default:
@@ -922,18 +922,18 @@ static f1ap_drb_to_setup_t cp_drb_to_setup(const f1ap_drb_to_setup_t *orig)
static bool eq_drb_to_setup(const f1ap_drb_to_setup_t *a, const f1ap_drb_to_setup_t *b)
{
_F1_EQ_CHECK_INT(a->id, b->id);
_F1_EQ_CHECK_INT(a->qos_choice, b->qos_choice);
_EQ_CHECK_INT(a->id, b->id);
_EQ_CHECK_INT(a->qos_choice, b->qos_choice);
AssertFatal(a->qos_choice == F1AP_QOS_CHOICE_NR, "only NR QoS choice implemented\n");
if (a->qos_choice == F1AP_QOS_CHOICE_NR)
eq_drb_info_nr(&a->nr, &b->nr);
_F1_EQ_CHECK_INT(a->up_ul_tnl_len, b->up_ul_tnl_len);
_EQ_CHECK_INT(a->up_ul_tnl_len, b->up_ul_tnl_len);
for (int i = 0; i < a->up_ul_tnl_len; ++i) {
_F1_CHECK_EXP(eq_up_tnl(&a->up_ul_tnl[i], &b->up_ul_tnl[i]));
}
_F1_EQ_CHECK_INT(a->rlc_mode, b->rlc_mode);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, dl_pdcp_sn_len, _F1_EQ_CHECK_INT);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, ul_pdcp_sn_len, _F1_EQ_CHECK_INT);
_EQ_CHECK_INT(a->rlc_mode, b->rlc_mode);
_EQ_CHECK_OPTIONAL_IE(a, b, dl_pdcp_sn_len, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, ul_pdcp_sn_len, _EQ_CHECK_INT);
return true;
}
@@ -1004,8 +1004,8 @@ static bool decode_drbs_setup(const F1AP_DRBs_Setup_List_t *f1ap, int *n, f1ap_d
f1ap_drb_setup_t *drbs = *out = calloc_or_fail(count, sizeof(*drbs));
for (int i = 0; i < count; ++i) {
const F1AP_DRBs_Setup_ItemIEs_t *itie = (const F1AP_DRBs_Setup_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_Setup_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_Setup_ItemIEs__value_PR_DRBs_Setup_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_Setup_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_Setup_ItemIEs__value_PR_DRBs_Setup_Item);
const F1AP_DRBs_Setup_Item_t *it = &itie->value.choice.DRBs_Setup_Item;
f1ap_drb_setup_t *drb = &drbs[i];
@@ -1014,7 +1014,7 @@ static bool decode_drbs_setup(const F1AP_DRBs_Setup_List_t *f1ap, int *n, f1ap_d
_F1_MALLOC(drb->lcid, *it->lCID);
drb->up_dl_tnl_len = it->dLUPTNLInformation_ToBeSetup_List.list.count;
_F1_EQ_CHECK_GENERIC(drb->up_dl_tnl_len > 0 && drb->up_dl_tnl_len <= 2, "%d", drb->up_dl_tnl_len, 1);
EQ_CHECK_GENERIC(drb->up_dl_tnl_len > 0 && drb->up_dl_tnl_len <= 2, "%d", drb->up_dl_tnl_len, 1);
for (int j = 0; j < drb->up_dl_tnl_len; ++j) {
F1AP_DLUPTNLInformation_ToBeSetup_Item_t *it_tnl = it->dLUPTNLInformation_ToBeSetup_List.list.array[j];
_F1_CHECK_EXP(decode_up_tnl(&it_tnl->dLUPTNLInformation, &drb->up_dl_tnl[j]));
@@ -1035,8 +1035,8 @@ static bool decode_drbs_setupmod(const F1AP_DRBs_SetupMod_List_t *f1ap, int *n,
f1ap_drb_setup_t *drbs = *out = calloc_or_fail(count, sizeof(*drbs));
for (int i = 0; i < count; ++i) {
const F1AP_DRBs_SetupMod_ItemIEs_t *itie = (const F1AP_DRBs_SetupMod_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item);
const F1AP_DRBs_SetupMod_Item_t *it = &itie->value.choice.DRBs_SetupMod_Item;
f1ap_drb_setup_t *drb = &drbs[i];
@@ -1045,7 +1045,7 @@ static bool decode_drbs_setupmod(const F1AP_DRBs_SetupMod_List_t *f1ap, int *n,
_F1_MALLOC(drb->lcid, *it->lCID);
drb->up_dl_tnl_len = it->dLUPTNLInformation_ToBeSetup_List.list.count;
_F1_EQ_CHECK_GENERIC(drb->up_dl_tnl_len > 0 && drb->up_dl_tnl_len <= 2, "%d", drb->up_dl_tnl_len, 1);
EQ_CHECK_GENERIC(drb->up_dl_tnl_len > 0 && drb->up_dl_tnl_len <= 2, "%d", drb->up_dl_tnl_len, 1);
for (int j = 0; j < drb->up_dl_tnl_len; ++j) {
F1AP_DLUPTNLInformation_ToBeSetup_Item_t *it_tnl = it->dLUPTNLInformation_ToBeSetup_List.list.array[j];
_F1_CHECK_EXP(decode_up_tnl(&it_tnl->dLUPTNLInformation, &drb->up_dl_tnl[j]));
@@ -1070,9 +1070,9 @@ static f1ap_drb_setup_t cp_drb_setup(const f1ap_drb_setup_t *orig)
static bool eq_drb_setup(const f1ap_drb_setup_t *a, const f1ap_drb_setup_t *b)
{
_F1_EQ_CHECK_INT(a->id, b->id);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, lcid, _F1_EQ_CHECK_INT);
_F1_EQ_CHECK_INT(a->up_dl_tnl_len, b->up_dl_tnl_len);
_EQ_CHECK_INT(a->id, b->id);
_EQ_CHECK_OPTIONAL_IE(a, b, lcid, _EQ_CHECK_INT);
_EQ_CHECK_INT(a->up_dl_tnl_len, b->up_dl_tnl_len);
for (int i = 0; i < a->up_dl_tnl_len; ++i)
_F1_CHECK_EXP(eq_up_tnl(&a->up_dl_tnl[i], &b->up_dl_tnl[i]));
return true;
@@ -1107,8 +1107,8 @@ static bool decode_drbs_to_release(const F1AP_DRBs_ToBeReleased_List_t *f1ap, in
f1ap_drb_to_release_t *drbs = *out = calloc_or_fail(count, sizeof(*drbs));
for (int i = 0; i < count; ++i) {
const F1AP_DRBs_ToBeReleased_ItemIEs_t *itie = (F1AP_DRBs_ToBeReleased_ItemIEs_t *)f1ap->list.array[i];
_F1_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item);
_F1_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item);
_EQ_CHECK_LONG(itie->id, F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item);
_EQ_CHECK_INT(itie->value.present, F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item);
drbs[i].id = itie->value.choice.DRBs_ToBeReleased_Item.dRBID;
}
@@ -1125,7 +1125,7 @@ static f1ap_drb_to_release_t cp_drb_to_release(const f1ap_drb_to_release_t *orig
static bool eq_drb_to_release(const f1ap_drb_to_release_t *a, const f1ap_drb_to_release_t *b)
{
_F1_EQ_CHECK_INT(a->id, b->id);
_EQ_CHECK_INT(a->id, b->id);
return true;
}
@@ -1249,33 +1249,33 @@ bool decode_ue_context_setup_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_set
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
_F1_MALLOC(out->gNB_DU_ue_id, ie->value.choice.GNB_DU_UE_F1AP_ID);
break;
case F1AP_ProtocolIE_ID_id_SpCell_ID: {
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_NRCGI);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_NRCGI);
const F1AP_NRCGI_t *nrcgi = &ie->value.choice.NRCGI;
PLMNID_TO_MCC_MNC(&nrcgi->pLMN_Identity, out->plmn.mcc, out->plmn.mnc, out->plmn.mnc_digit_length);
BIT_STRING_TO_NR_CELL_IDENTITY(&nrcgi->nRCellIdentity, out->nr_cellid);
} break;
case F1AP_ProtocolIE_ID_id_ServCellIndex:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_ServCellIndex);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_ServCellIndex);
out->servCellIndex = ie->value.choice.ServCellIndex;
break;
case F1AP_ProtocolIE_ID_id_CUtoDURRCInformation:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation);
_F1_CHECK_EXP(decode_cu_to_du_rrc_info(&out->cu_to_du_rrc_info, &ie->value.choice.CUtoDURRCInformation));
break;
case F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List);
_F1_CHECK_EXP(decode_srbs_to_setup(&ie->value.choice.SRBs_ToBeSetup_List, &out->srbs_len, &out->srbs));
break;
case F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List);
{
// gNB-DU UE Aggregate Maximum Bit Rate Uplink is C-ifDRBSetup
// below, check that gNB-DU UE AMBR UL IE is present if we have DRB
@@ -1287,7 +1287,7 @@ bool decode_ue_context_setup_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_set
_F1_CHECK_EXP(decode_drbs_to_setup(&ie->value.choice.DRBs_ToBeSetup_List, &out->drbs_len, &out->drbs));
break;
case F1AP_ProtocolIE_ID_id_RRCContainer:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer);
out->rrc_container = malloc_or_fail(sizeof(*out->rrc_container));
{
OCTET_STRING_t *os = &ie->value.choice.RRCContainer;
@@ -1295,7 +1295,7 @@ bool decode_ue_context_setup_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_set
}
break;
case F1AP_ProtocolIE_ID_id_GNB_DU_UE_AMBR_UL:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_BitRate);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupRequestIEs__value_PR_BitRate);
out->gnb_du_ue_agg_mbr_ul = malloc_or_fail(sizeof(*out->gnb_du_ue_agg_mbr_ul));
asn_INTEGER2uint64(&ie->value.choice.BitRate, out->gnb_du_ue_agg_mbr_ul);
break;
@@ -1346,26 +1346,26 @@ f1ap_ue_context_setup_req_t cp_ue_context_setup_req(const f1ap_ue_context_setup_
*/
bool eq_ue_context_setup_req(const f1ap_ue_context_setup_req_t *a, const f1ap_ue_context_setup_req_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, gNB_DU_ue_id, _F1_EQ_CHECK_INT);
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_OPTIONAL_IE(a, b, gNB_DU_ue_id, _EQ_CHECK_INT);
_F1_CHECK_EXP(eq_f1ap_plmn(&a->plmn, &b->plmn));
_F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
_F1_EQ_CHECK_INT(a->servCellIndex, b->servCellIndex);
_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid);
_EQ_CHECK_INT(a->servCellIndex, b->servCellIndex);
_F1_CHECK_EXP(eq_cu_to_du_rrc_info(&a->cu_to_du_rrc_info, &b->cu_to_du_rrc_info));
_F1_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_F1_CHECK_EXP(a->srbs_len == 0 || (a->srbs && b->srbs));
for (int i = 0; i < a->srbs_len; ++i)
_F1_CHECK_EXP(eq_srb_to_setup(&a->srbs[i], &b->srbs[i]));
_F1_EQ_CHECK_INT(a->drbs_len, b->drbs_len);
_EQ_CHECK_INT(a->drbs_len, b->drbs_len);
_F1_CHECK_EXP(a->drbs_len == 0 || (a->drbs && b->drbs));
for (int i = 0; i < a->drbs_len; ++i)
_F1_CHECK_EXP(eq_drb_to_setup(&a->drbs[i], &b->drbs[i]));
_F1_EQ_CHECK_OPTIONAL_IE(a, b, rrc_container, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, rrc_container, eq_ba);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, gnb_du_ue_agg_mbr_ul, _F1_EQ_CHECK_LONG);
_EQ_CHECK_OPTIONAL_IE(a, b, gnb_du_ue_agg_mbr_ul, _EQ_CHECK_LONG);
return true;
}
@@ -1472,27 +1472,27 @@ bool decode_ue_context_setup_resp(const struct F1AP_F1AP_PDU *pdu, f1ap_ue_conte
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_DUtoCURRCInformation:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation);
_F1_CHECK_EXP(decode_du_to_cu_rrc_info(&out->du_to_cu_rrc_info, &ie->value.choice.DUtoCURRCInformation));
break;
case F1AP_ProtocolIE_ID_id_C_RNTI:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI);
_F1_MALLOC(out->crnti, ie->value.choice.C_RNTI);
break;
case F1AP_ProtocolIE_ID_id_DRBs_Setup_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List);
_F1_CHECK_EXP(decode_drbs_setup(&ie->value.choice.DRBs_Setup_List, &out->drbs_len, &out->drbs));
break;
case F1AP_ProtocolIE_ID_id_SRBs_Setup_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_SRBs_Setup_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextSetupResponseIEs__value_PR_SRBs_Setup_List);
_F1_CHECK_EXP(decode_srbs_setup(&ie->value.choice.SRBs_Setup_List, &out->srbs_len, &out->srbs));
break;
default:
@@ -1541,17 +1541,17 @@ f1ap_ue_context_setup_resp_t cp_ue_context_setup_resp(const f1ap_ue_context_setu
*/
bool eq_ue_context_setup_resp(const f1ap_ue_context_setup_resp_t *a, const f1ap_ue_context_setup_resp_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_CHECK_EXP(eq_du_to_cu_rrc_info(&a->du_to_cu_rrc_info, &b->du_to_cu_rrc_info));
_F1_EQ_CHECK_OPTIONAL_IE(a, b, crnti, _F1_EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, crnti, _EQ_CHECK_INT);
_F1_EQ_CHECK_INT(a->drbs_len, b->drbs_len);
_EQ_CHECK_INT(a->drbs_len, b->drbs_len);
_F1_CHECK_EXP(a->drbs_len == 0 || (a->drbs && b->drbs));
for (int i = 0; i < a->drbs_len; ++i)
_F1_CHECK_EXP(eq_drb_setup(&a->drbs[i], &b->drbs[i]));
_F1_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_F1_CHECK_EXP(a->srbs_len == 0 || (a->srbs && b->srbs));
for (int i = 0; i < a->srbs_len; ++i)
_F1_CHECK_EXP(eq_srb_setup(&a->srbs[i], &b->srbs[i]));
@@ -1735,15 +1735,15 @@ bool decode_ue_context_mod_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_mod_r
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_SpCell_ID: {
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_NRCGI);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_NRCGI);
const F1AP_NRCGI_t *nrcgi = &ie->value.choice.NRCGI;
out->plmn = malloc_or_fail(sizeof(*out->plmn));
PLMNID_TO_MCC_MNC(&nrcgi->pLMN_Identity, out->plmn->mcc, out->plmn->mnc, out->plmn->mnc_digit_length);
@@ -1751,16 +1751,16 @@ bool decode_ue_context_mod_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_mod_r
BIT_STRING_TO_NR_CELL_IDENTITY(&nrcgi->nRCellIdentity, *out->nr_cellid);
} break;
case F1AP_ProtocolIE_ID_id_ServCellIndex:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex);
_F1_MALLOC(out->servCellIndex, ie->value.choice.ServCellIndex);
break;
case F1AP_ProtocolIE_ID_id_CUtoDURRCInformation:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation);
out->cu_to_du_rrc_info = calloc(1, sizeof(*out->cu_to_du_rrc_info));
_F1_CHECK_EXP(decode_cu_to_du_rrc_info(out->cu_to_du_rrc_info, &ie->value.choice.CUtoDURRCInformation));
break;
case F1AP_ProtocolIE_ID_id_TransmissionActionIndicator:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator);
{
TransmActionInd_t v = ie->value.choice.TransmissionActionIndicator == F1AP_TransmissionActionIndicator_stop
? TransmActionInd_STOP
@@ -1769,7 +1769,7 @@ bool decode_ue_context_mod_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_mod_r
}
break;
case F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_RRCReconfigurationCompleteIndicator);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_RRCReconfigurationCompleteIndicator);
{
ReconfigurationCompl_t v =
ie->value.choice.RRCReconfigurationCompleteIndicator == F1AP_RRCReconfigurationCompleteIndicator_true
@@ -1779,7 +1779,7 @@ bool decode_ue_context_mod_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_mod_r
}
break;
case F1AP_ProtocolIE_ID_id_RRCContainer:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer);
out->rrc_container = malloc_or_fail(sizeof(*out->rrc_container));
{
OCTET_STRING_t *os = &ie->value.choice.RRCContainer;
@@ -1787,26 +1787,26 @@ bool decode_ue_context_mod_req(const F1AP_F1AP_PDU_t *pdu, f1ap_ue_context_mod_r
}
break;
case F1AP_ProtocolIE_ID_id_GNB_DUConfigurationQuery:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_GNB_DUConfigurationQuery);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_GNB_DUConfigurationQuery);
{
bool v = ie->value.choice.GNB_DUConfigurationQuery == F1AP_GNB_DUConfigurationQuery_true;
_F1_MALLOC(out->gNB_DU_Configuration_Query, v);
}
break;
case F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List);
_F1_CHECK_EXP(decode_srbs_to_setupmod(&ie->value.choice.SRBs_ToBeSetupMod_List, &out->srbs_len, &out->srbs));
break;
case F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List);
_F1_CHECK_EXP(decode_drbs_to_setupmod(&ie->value.choice.DRBs_ToBeSetupMod_List, &out->drbs_len, &out->drbs));
break;
case F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List);
_F1_CHECK_EXP(decode_drbs_to_release(&ie->value.choice.DRBs_ToBeReleased_List, &out->drbs_rel_len, &out->drbs_rel));
break;
case F1AP_ProtocolIE_ID_id_LowerLayerPresenceStatusChange:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_LowerLayerPresenceStatusChange);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationRequestIEs__value_PR_LowerLayerPresenceStatusChange);
{
lower_layer_status_t v = ie->value.choice.LowerLayerPresenceStatusChange == F1AP_LowerLayerPresenceStatusChange_suspend_lower_layers
? LOWER_LAYERS_SUSPEND : LOWER_LAYERS_RESUME;
@@ -1888,35 +1888,35 @@ f1ap_ue_context_mod_req_t cp_ue_context_mod_req(const f1ap_ue_context_mod_req_t
*/
bool eq_ue_context_mod_req(const f1ap_ue_context_mod_req_t *a, const f1ap_ue_context_mod_req_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_CHECK_EXP((a->plmn && b->plmn) || (!a->plmn && !b->plmn));
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_OPTIONAL_PTR(a, b, plmn);
_F1_CHECK_EXP(!a->plmn || eq_f1ap_plmn(a->plmn, b->plmn));
_F1_EQ_CHECK_OPTIONAL_IE(a, b, nr_cellid, _F1_EQ_CHECK_LONG);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, servCellIndex, _F1_EQ_CHECK_INT);
_F1_CHECK_EXP((a->cu_to_du_rrc_info && b->cu_to_du_rrc_info) || (!a->cu_to_du_rrc_info && !b->cu_to_du_rrc_info));
_EQ_CHECK_OPTIONAL_IE(a, b, nr_cellid, _EQ_CHECK_LONG);
_EQ_CHECK_OPTIONAL_IE(a, b, servCellIndex, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_PTR(a, b, cu_to_du_rrc_info);
_F1_CHECK_EXP(!a->cu_to_du_rrc_info || eq_cu_to_du_rrc_info(a->cu_to_du_rrc_info, b->cu_to_du_rrc_info));
_F1_EQ_CHECK_OPTIONAL_IE(a, b, transm_action_ind, _F1_EQ_CHECK_INT);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, reconfig_compl, _F1_EQ_CHECK_INT);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, rrc_container, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, transm_action_ind, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, reconfig_compl, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, rrc_container, eq_ba);
_F1_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_F1_CHECK_EXP(a->srbs_len == 0 || (a->srbs && b->srbs));
for (int i = 0; i < a->srbs_len; ++i)
_F1_CHECK_EXP(eq_srb_to_setup(&a->srbs[i], &b->srbs[i]));
_F1_EQ_CHECK_INT(a->drbs_len, b->drbs_len);
_EQ_CHECK_INT(a->drbs_len, b->drbs_len);
_F1_CHECK_EXP(a->drbs_len == 0 || (a->drbs && b->drbs));
for (int i = 0; i < a->drbs_len; ++i)
_F1_CHECK_EXP(eq_drb_to_setup(&a->drbs[i], &b->drbs[i]));
_F1_EQ_CHECK_INT(a->drbs_rel_len, b->drbs_rel_len);
_EQ_CHECK_INT(a->drbs_rel_len, b->drbs_rel_len);
_F1_CHECK_EXP(a->drbs_rel_len == 0 || (a->drbs_rel_len && b->drbs_rel_len));
for (int i = 0; i < a->drbs_rel_len; ++i)
_F1_CHECK_EXP(eq_drb_to_release(&a->drbs_rel[i], &b->drbs_rel[i]));
_F1_EQ_CHECK_OPTIONAL_IE(a, b, status, _F1_EQ_CHECK_INT);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, gNB_DU_Configuration_Query, _F1_EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, status, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, gNB_DU_Configuration_Query, _EQ_CHECK_INT);
return true;
}
@@ -2024,24 +2024,24 @@ bool decode_ue_context_mod_resp(const struct F1AP_F1AP_PDU *pdu, f1ap_ue_context
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_DUtoCURRCInformation:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_DUtoCURRCInformation);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_DUtoCURRCInformation);
out->du_to_cu_rrc_info = calloc(1, sizeof(*out->du_to_cu_rrc_info));
_F1_CHECK_EXP(decode_du_to_cu_rrc_info(out->du_to_cu_rrc_info, &ie->value.choice.DUtoCURRCInformation));
break;
case F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List);
_F1_CHECK_EXP(decode_drbs_setupmod(&ie->value.choice.DRBs_SetupMod_List, &out->drbs_len, &out->drbs));
break;
case F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_SRBs_SetupMod_List);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextModificationResponseIEs__value_PR_SRBs_SetupMod_List);
_F1_CHECK_EXP(decode_srbs_setupmod(&ie->value.choice.SRBs_SetupMod_List, &out->srbs_len, &out->srbs));
break;
default:
@@ -2097,17 +2097,17 @@ f1ap_ue_context_mod_resp_t cp_ue_context_mod_resp(const f1ap_ue_context_mod_resp
*/
bool eq_ue_context_mod_resp(const f1ap_ue_context_mod_resp_t *a, const f1ap_ue_context_mod_resp_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
//_F1_EQ_CHECK_OPTIONAL_IE(a, b, du_to_cu_rrc_info, eq_du_to_cu_rrc_info);
_F1_CHECK_EXP((a->du_to_cu_rrc_info && b->du_to_cu_rrc_info) || (!a->du_to_cu_rrc_info && !b->du_to_cu_rrc_info));
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
//_EQ_CHECK_OPTIONAL_IE(a, b, du_to_cu_rrc_info, eq_du_to_cu_rrc_info);
_EQ_CHECK_OPTIONAL_PTR(a, b, du_to_cu_rrc_info);
_F1_CHECK_EXP(!a->du_to_cu_rrc_info || eq_du_to_cu_rrc_info(a->du_to_cu_rrc_info, b->du_to_cu_rrc_info));
_F1_CHECK_EXP(a->drbs_len == 0 || (a->drbs && b->drbs));
for (int i = 0; i < a->drbs_len; ++i)
_F1_CHECK_EXP(eq_drb_setup(&a->drbs[i], &b->drbs[i]));
_F1_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_EQ_CHECK_INT(a->srbs_len, b->srbs_len);
_F1_CHECK_EXP(a->srbs_len == 0 || (a->srbs && b->srbs));
for (int i = 0; i < a->srbs_len; ++i)
_F1_CHECK_EXP(eq_srb_setup(&a->srbs[i], &b->srbs[i]));
@@ -2189,15 +2189,15 @@ bool decode_ue_context_rel_req(const struct F1AP_F1AP_PDU *pdu, f1ap_ue_context_
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_Cause:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseRequestIEs__value_PR_Cause);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseRequestIEs__value_PR_Cause);
_F1_CHECK_EXP(decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value));
break;
default:
@@ -2228,10 +2228,10 @@ f1ap_ue_context_rel_req_t cp_ue_context_rel_req(const f1ap_ue_context_rel_req_t
*/
bool eq_ue_context_rel_req(const f1ap_ue_context_rel_req_t *a, const f1ap_ue_context_rel_req_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->cause, b->cause);
_F1_EQ_CHECK_LONG(a->cause_value, b->cause_value);
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_LONG(a->cause_value, b->cause_value);
return true;
}
@@ -2327,27 +2327,27 @@ bool decode_ue_context_rel_cmd(const struct F1AP_F1AP_PDU *pdu, f1ap_ue_context_
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_Cause:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_Cause);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_Cause);
_F1_CHECK_EXP(decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value));
break;
case F1AP_ProtocolIE_ID_id_RRCContainer:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer);
out->rrc_container = malloc_or_fail(sizeof(*out->rrc_container));
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer);
out->rrc_container = malloc_or_fail(sizeof(*out->rrc_container));
{
OCTET_STRING_t *os = &ie->value.choice.RRCContainer;
*out->rrc_container = create_byte_array(os->size, os->buf);
}
break;
case F1AP_ProtocolIE_ID_id_SRBID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_SRBID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_SRBID);
{
// SRB-ID
F1AP_UEContextReleaseCommandIEs_t *check_ie;
@@ -2356,7 +2356,7 @@ bool decode_ue_context_rel_cmd(const struct F1AP_F1AP_PDU *pdu, f1ap_ue_context_
_F1_MALLOC(out->srb_id, ie->value.choice.SRBID);
break;
case F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID_1);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID_1);
_F1_MALLOC(out->old_gNB_DU_ue_id, ie->value.choice.GNB_DU_UE_F1AP_ID_1);
break;
default:
@@ -2394,13 +2394,13 @@ f1ap_ue_context_rel_cmd_t cp_ue_context_rel_cmd(const f1ap_ue_context_rel_cmd_t
*/
bool eq_ue_context_rel_cmd(const f1ap_ue_context_rel_cmd_t *a, const f1ap_ue_context_rel_cmd_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->cause, b->cause);
_F1_EQ_CHECK_LONG(a->cause_value, b->cause_value);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, rrc_container, eq_ba);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, srb_id, _F1_EQ_CHECK_INT);
_F1_EQ_CHECK_OPTIONAL_IE(a, b, old_gNB_DU_ue_id, _F1_EQ_CHECK_INT);
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_LONG(a->cause_value, b->cause_value);
_EQ_CHECK_OPTIONAL_IE(a, b, rrc_container, eq_ba);
_EQ_CHECK_OPTIONAL_IE(a, b, srb_id, _EQ_CHECK_INT);
_EQ_CHECK_OPTIONAL_IE(a, b, old_gNB_DU_ue_id, _EQ_CHECK_INT);
return true;
}
@@ -2464,11 +2464,11 @@ bool decode_ue_context_rel_cplt(const struct F1AP_F1AP_PDU *pdu, f1ap_ue_context
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
switch (ie->id) {
case F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID);
_EQ_CHECK_INT(ie->value.present, F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
default:
@@ -2497,8 +2497,8 @@ f1ap_ue_context_rel_cplt_t cp_ue_context_rel_cplt(const f1ap_ue_context_rel_cplt
*/
bool eq_ue_context_rel_cplt(const f1ap_ue_context_rel_cplt_t *a, const f1ap_ue_context_rel_cplt_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
return true;
}
+75
View File
@@ -44,6 +44,7 @@
#include "lib/f1ap_interface_management.h"
#include "lib/f1ap_ue_context.h"
#include "lib/f1ap_positioning.h"
#include "lib/f1ap_paging.h"
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
@@ -2383,6 +2384,79 @@ static void test_f1ap_positioning_measurement_update()
printf("%s() successful\n", __func__);
}
/** @brief Test F1 Paging encode/decode roundtrip and copy operations */
static void test_f1ap_paging_rt(f1ap_paging_t *orig)
{
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_paging(orig);
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
f1ap_msg_free(f1enc);
f1ap_paging_t decoded = {0};
bool ret = decode_f1ap_paging(&decoded, f1dec);
AssertFatal(ret, "decode_f1ap_paging(): could not decode message\n");
f1ap_msg_free(f1dec);
ret = eq_f1ap_paging(orig, &decoded);
AssertFatal(ret, "eq_f1ap_paging(): decoded message doesn't match\n");
free_f1ap_paging(&decoded);
f1ap_paging_t cp = cp_f1ap_paging(orig);
ret = eq_f1ap_paging(orig, &cp);
AssertFatal(ret, "eq_f1ap_paging(): copied message doesn't match\n");
free_f1ap_paging(&cp);
}
/** @brief Test F1 Paging encoding/decoding */
static void test_f1ap_paging(void)
{
// Test with CN UE Paging Identity (5G-S-TMSI)
{
f1ap_paging_t orig = {0};
orig.ue_identity_index_value = 123;
orig.identity_type = F1AP_PAGING_IDENTITY_CN_UE;
orig.identity.cn_ue_paging_identity = 0x1234567890AB;
orig.drx = malloc_or_fail(sizeof(*orig.drx));
*orig.drx = F1AP_PAGING_DRX_32;
orig.n_cells = 2;
orig.cells = calloc_or_fail(orig.n_cells, sizeof(*orig.cells));
orig.cells[0].plmn.mcc = 208;
orig.cells[0].plmn.mnc = 95;
orig.cells[0].plmn.mnc_digit_length = 2;
orig.cells[0].nr_cellid = 123456;
orig.cells[1].plmn.mcc = 208;
orig.cells[1].plmn.mnc = 93;
orig.cells[1].plmn.mnc_digit_length = 2;
orig.cells[1].nr_cellid = 789012;
test_f1ap_paging_rt(&orig);
free_f1ap_paging(&orig);
}
// Test with RAN UE Paging Identity (I-RNTI)
{
f1ap_paging_t orig = {0};
orig.ue_identity_index_value = 456;
orig.identity_type = F1AP_PAGING_IDENTITY_RAN_UE;
orig.identity.ran_ue_paging_identity = 0x1234567890;
orig.drx = NULL;
orig.priority = malloc_or_fail(sizeof(*orig.priority));
*orig.priority = F1AP_PAGING_PRIO_LEVEL3;
orig.origin = malloc_or_fail(sizeof(*orig.origin));
*orig.origin = F1AP_PAGING_ORIGIN_NON_3GPP;
orig.n_cells = 1;
orig.cells = calloc_or_fail(orig.n_cells, sizeof(*orig.cells));
orig.cells[0].plmn.mcc = 1;
orig.cells[0].plmn.mnc = 1;
orig.cells[0].plmn.mnc_digit_length = 2;
orig.cells[0].nr_cellid = 987654;
test_f1ap_paging_rt(&orig);
free_f1ap_paging(&orig);
}
printf("%s() successful\n", __func__);
}
int main()
{
test_initial_ul_rrc_message_transfer();
@@ -2427,5 +2501,6 @@ int main()
test_f1ap_positioning_measurement_abort();
test_f1ap_positioning_measurement_failure_indication();
test_f1ap_positioning_measurement_update();
test_f1ap_paging();
return 0;
}
@@ -663,8 +663,12 @@ static NR_CellGroupConfig_t *get_cellgroup_config(NR_UE_info_t *UE)
static void update_cellgroup_for_reestablishment(NR_UE_info_t *UE, NR_CellGroupConfig_t *new_CellGroup)
{
DevAssert(new_CellGroup);
DevAssert(new_CellGroup->spCellConfig);
DevAssert(UE->reestablish_rlc);
if (!new_CellGroup->spCellConfig) {
LOG_E(NR_MAC, "UE %04x: CellGroupConfig has no spCellConfig during reestablishment "
"(possible double reestablishment race), skipping reestablishRLC update\n", UE->rnti);
return;
}
LOG_I(NR_MAC, "UE %04x: Re-establishment detected, setting reestablishRLC flags\n", UE->rnti);
struct NR_CellGroupConfig__rlc_BearerToAddModList *addmod = new_CellGroup->rlc_BearerToAddModList;
if (addmod && addmod->list.count > 0) {
@@ -1079,6 +1083,10 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
UE->CellGroup = oldUE->CellGroup;
oldUE->CellGroup = NULL;
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup);
UE->reconfigCellGroup = oldUE->reconfigCellGroup;
oldUE->reconfigCellGroup = NULL;
UE->reestablish_rlc = oldUE->reestablish_rlc;
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability);
UE->capability = oldUE->capability;
oldUE->capability = NULL;
@@ -1095,10 +1103,18 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
}
/* Per TS 38.331 5.3.7.2: the UE releases the spCellConfig, so we drop it
* from the current configuration. It will be reapplied when the
* reconfiguration has succeeded (indicated by the CU) */
asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&UE->reconfigCellGroup, UE->CellGroup);
ASN_STRUCT_FREE(asn_DEF_NR_SpCellConfig, UE->CellGroup->spCellConfig);
UE->CellGroup->spCellConfig = NULL;
* reconfiguration has succeeded (indicated by the CU).
* Guard against double reestablishment: if reestablish_rlc is already set,
* reconfigCellGroup was saved by the first reestablishment and
* CellGroup.spCellConfig is already NULL — don't overwrite. */
if (!UE->reestablish_rlc) {
asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&UE->reconfigCellGroup, UE->CellGroup);
ASN_STRUCT_FREE(asn_DEF_NR_SpCellConfig, UE->CellGroup->spCellConfig);
UE->CellGroup->spCellConfig = NULL;
} else {
LOG_W(NR_MAC, "UE %04x: reestablishment while previous reestablishment still pending, "
"keeping saved reconfigCellGroup with spCellConfig\n", UE->rnti);
}
UE->reestablish_rlc = true;
/* Per TS 38.331 clause 5.3.7.4: apply gNB RLC configuration for SRB1 to match the UE RLC configuration defined in 9.2.1.
* Use configuration file values for timers t_poll_retransmit, t_reassembly and t_status_prohibit */
-162
View File
@@ -82,168 +82,6 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
}
}
//------------------------------------------------------------------------------
bool gtpv_data_req(const protocol_ctxt_t* const ctxt_pP,
const rb_id_t rb_idP,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_sizeP,
uint8_t* const buffer_pP,
const pdcp_transmission_mode_t modeP,
uint32_t task_id)
//------------------------------------------------------------------------------
{
if(sdu_sizeP == 0)
{
LOG_I(GTPU,"gtpv_data_req sdu_sizeP == 0");
return false;
}
LOG_D(GTPU, "gtpv_data_req ue rnti %lx sdu_sizeP %d rb id %ld", ctxt_pP->rntiMaybeUEid, sdu_sizeP, rb_idP);
MessageDef *message_p;
// Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
uint8_t *message_buffer;
if(task_id == TASK_DATA_FORWARDING){
LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n");
message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP);
memcpy (message_buffer, buffer_pP, sdu_sizeP);
message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND);
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id;
GTPV1U_ENB_DATA_FORWARDING_IND(message_p).rnti = ctxt_pP->rntiMaybeUEid;
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index;
itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p);
return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
} else if (task_id == TASK_END_MARKER){
LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n");
message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP);
memcpy (message_buffer, buffer_pP, sdu_sizeP);
message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND);
GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame;
GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag;
GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP;
GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP;
GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP;
GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP;
GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer;
GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP;
GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id;
GTPV1U_ENB_END_MARKER_IND(message_p).rnti = ctxt_pP->rntiMaybeUEid;
GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index;
itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p);
return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
}
LOG_E(RRC, "Impossible state\n");
return false;
}
bool gtpv_data_req_new(protocol_ctxt_t *ctxt,
const srb_flag_t srb_flagP,
const rb_id_t rb_idP,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_buffer_sizeP,
unsigned char *const sdu_buffer_pP,
const pdcp_transmission_mode_t modeP,
const uint32_t *sourceL2Id,
const uint32_t *destinationL2Id) {
int task;
if (sdu_buffer_sizeP==0)
task=TASK_END_MARKER;
else
task=TASK_DATA_FORWARDING;
struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt->module_id], ctxt->rntiMaybeUEid);
if(ue_context_p == NULL || ue_context_p->ue_context.handover_info == NULL ||
ue_context_p->ue_context.StatusRrc != RRC_HO_EXECUTION) {
LOG_E(RRC,"incoming GTP-U for X2 in non HO context\n");
return false;
}
/* in the source enb, UE in RRC_HO_EXECUTION mode */
// We have 2*2=4 cases (data or end marker) * (from slave, from EPC)
if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
LOG_I(GTPU, "source receive END MARKER\n");
/* set handover state */
//ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
MessageDef *msg;
// Configure end marker
msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_REQ);
GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + sdu_buffer_sizeP);
memcpy(&GTPV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], sdu_buffer_pP, sdu_buffer_sizeP);
GTPV1U_ENB_END_MARKER_REQ(msg).length = sdu_buffer_sizeP;
GTPV1U_ENB_END_MARKER_REQ(msg).rnti = ctxt->rntiMaybeUEid;
GTPV1U_ENB_END_MARKER_REQ(msg).rab_id = rb_idP;
GTPV1U_ENB_END_MARKER_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX;
LOG_I(GTPU, "Send End Marker to GTPV1-U at frame %d and subframe %d \n", ctxt->frame,ctxt->subframe);
itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt->module_id), msg);
return 0;
}
/* target enb */
// We have 2*2=4 cases (data or end marker) * (from source, from EPC)
if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED) {
// It should come from remote eNB
// case end marker by EPC is not possible ?
if (task==TASK_END_MARKER) {
LOG_I(GTPU, "target end receive END MARKER\n");
// We close the HO, nothing to send to remote ?
ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req;
memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req));
delete_tunnel_req.rnti = ctxt->rntiMaybeUEid;
gtpv1u_delete_x2u_tunnel(ctxt->module_id, &delete_tunnel_req);
return true;
} else {
/* data packet */
LOG_I(GTPU, "Received a message data forwarding length %d\n", sdu_buffer_sizeP);
// Is it from remote ENB
// We have to push it to the UE ?
if(ue_context_p->ue_context.handover_info->state != HO_COMPLETE) {
int result = pdcp_data_req(
ctxt,
srb_flagP,
rb_idP,
muiP, // mui
confirmP, // confirm
sdu_buffer_sizeP,
sdu_buffer_pP,
modeP,
sourceL2Id,
destinationL2Id
);
ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_NO_EMPTY;
return result;
} else { /* It is from from epc message */
/* in the source enb, UE in RRC_HO_EXECUTION mode */
// ?????
return true;
}
}
}
LOG_E(RRC,"This function should return before the end\n");
return false;
}
void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
module_id_t enb_mod_idP,
rrc_eNB_ue_context_t* ue_context_pP
-9
View File
@@ -54,13 +54,4 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
rrc_eNB_ue_context_t* ue_context_pP
);
bool gtpv_data_req(const protocol_ctxt_t* const ctxt_pP,
const rb_id_t rb_idP,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_sizeP,
uint8_t* const buffer_pP,
const pdcp_transmission_mode_t modeP,
uint32_t task_id);
#endif /* RRC_ENB_GTPV1U_H_ */
+2 -2
View File
@@ -716,7 +716,7 @@ int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_
str->buf[3] = rv[3];
str->buf[4] = rv[4] & 0xfe;
} else {
uint64_t fiveG_S_TMSI_part1 = fiveG_S_TMSI & ((1ULL << 39) - 1);
uint64_t fiveG_S_TMSI_part1 = nr_extract_5g_s_tmsi_part1(fiveG_S_TMSI);
/** set the ue-Identity to ng-5G-S-TMSI-Part1
* ng-5G-S-TMSI-Part1: the rightmost 39 bits of 5G-S-TMSI
* BIT STRING (SIZE (39)) - 3GPP TS 38.331 */
@@ -840,7 +840,7 @@ int do_RRCSetupComplete(uint8_t *buffer,
str->size = 2;
str->bits_unused = 7;
str->buf = calloc_or_fail(str->size, sizeof(str->buf[0]));
uint16_t fiveG_s_tmsi_part2 = (fiveG_s_tmsi >> 39) & ((1ULL << 9) - 1);
uint16_t fiveG_s_tmsi_part2 = nr_extract_5g_s_tmsi_part2(fiveG_s_tmsi);
str->buf[0] = (fiveG_s_tmsi_part2 >> (8 - str->bits_unused)) & 0xFF;
str->buf[1] = (fiveG_s_tmsi_part2 << str->bits_unused) & 0xFF;
LOG_D(NR_RRC, "5G-S-TMSI part 2 %d in RRCSetupComplete (5G-S-TMSI %ld)\n", fiveG_s_tmsi_part2, fiveG_s_tmsi);
@@ -2,7 +2,7 @@ add_executable(test_asn1_msg
test_asn1_msg.cpp
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c)
target_link_libraries(test_asn1_msg PRIVATE nr_rrc SECURITY minimal_lib GTest::gtest UTIL)
target_link_libraries(test_asn1_msg PRIVATE nr_rrc SECURITY minimal_lib GTest::gtest UTIL nr_common)
add_dependencies(tests test_asn1_msg)
add_test(NAME test_asn1_msg
COMMAND ./test_asn1_msg)
+1
View File
@@ -40,6 +40,7 @@ typedef void (*ue_context_modification_refuse_func_t)(sctp_assoc_t assoc_id, con
typedef void (*ue_context_release_command_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_rel_cmd_t *cmd);
typedef void (*dl_rrc_message_transfer_func_t)(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc);
typedef void (*f1_paging_transfer_func_t)(sctp_assoc_t assoc_id, const f1ap_paging_t *paging);
struct nr_mac_rrc_dl_if_s;
void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc);
+11
View File
@@ -94,6 +94,16 @@ static void dl_rrc_message_transfer_direct(sctp_assoc_t assoc_id, const f1ap_dl_
dl_rrc_message_transfer(dl_rrc);
}
static void f1_paging_transfer_direct(sctp_assoc_t assoc_id, const f1ap_paging_t *paging)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
/** @todo Build PCCH-Message (Paging) at DU per TS 38.331 §5.3.2; apply
* RRC padding per §8.5; deliver as RLC SDU per §8.2. For each
* cell in Paging Cell List that belongs to this DU, queue for MAC;
* MAC schedules at PF/PO per TS 38.304 §7. */
(void)paging;
}
void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
mac_rrc->f1_reset = f1_reset_cu_initiated_direct;
@@ -107,4 +117,5 @@ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse_direct;
mac_rrc->ue_context_release_command = ue_context_release_command_direct;
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct;
mac_rrc->paging_transfer = f1_paging_transfer_direct;
}
+11
View File
@@ -30,6 +30,7 @@
#include "intertask_interface.h"
#include "mac_rrc_dl.h"
#include "nr_rrc_defs.h"
#include "lib/f1ap_paging.h"
#include "lib/f1ap_rrc_message_transfer.h"
#include "lib/f1ap_interface_management.h"
#include "lib/f1ap_ue_context.h"
@@ -138,6 +139,15 @@ static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rr
itti_send_msg_to_task (TASK_CU_F1, 0, message_p);
}
static void paging_f1ap(sctp_assoc_t assoc_id, const f1ap_paging_t *paging)
{
MessageDef *message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING);
message_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_paging_t *msg = &F1AP_PAGING(message_p);
*msg = cp_f1ap_paging(paging);
itti_send_msg_to_task(TASK_CU_F1, 0, message_p);
}
void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
mac_rrc->f1_reset = f1_reset_cu_initiated_f1ap;
@@ -151,4 +161,5 @@ void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse_f1ap;
mac_rrc->ue_context_release_command = ue_context_release_command_f1ap;
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap;
mac_rrc->paging_transfer = paging_f1ap;
}
+1
View File
@@ -362,6 +362,7 @@ typedef struct nr_mac_rrc_dl_if_s {
ue_context_modification_refuse_func_t ue_context_modification_refuse;
ue_context_release_command_func_t ue_context_release_command;
dl_rrc_message_transfer_func_t dl_rrc_message_transfer;
f1_paging_transfer_func_t paging_transfer;
} nr_mac_rrc_dl_if_t;
typedef struct cucp_cuup_if_s {
+19
View File
@@ -409,3 +409,22 @@ nr_rrc_cell_container_t *rrc_get_pcell_for_ue(gNB_RRC_INST *rrc, const gNB_RRC_U
return get_cell_by_cell_id(&rrc->cells, pcell_entry->nci);
}
/** @brief Update UE's PCell in serving_cells array
* @param[in] UE UE context
* @param[in] cell Cell container to set as PCell
* @return Pointer to added serving cell entry, or NULL on failure
* @note If UE already has a PCell, removes all serving cells from the old PCell's DU first */
ue_serving_cell_t *rrc_update_ue_pcell(gNB_RRC_UE_t *UE, const nr_rrc_cell_container_t *cell)
{
DevAssert(UE != NULL);
DevAssert(cell != NULL);
// If UE already has a PCell, remove all serving cells from that DU first
const ue_serving_cell_t *existing_pcell = ue_get_pcell_entry(UE);
if (existing_pcell != NULL) {
rrc_remove_ue_scells_from_du(UE, existing_pcell->assoc_id);
}
// Add the new PCell
return rrc_add_ue_serving_cell(UE, cell, RRC_PCELL_INDEX);
}
+1
View File
@@ -69,5 +69,6 @@ void rrc_remove_ue_scells_from_du(gNB_RRC_UE_t *ue, sctp_assoc_t assoc_id);
ue_serving_cell_t *rrc_get_ue_serving_cell_by_id(const gNB_RRC_UE_t *ue, uint8_t serving_cell_id);
const ue_serving_cell_t *ue_get_pcell_entry(const gNB_RRC_UE_t *ue);
nr_rrc_cell_container_t *rrc_get_pcell_for_ue(gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue);
ue_serving_cell_t *rrc_update_ue_pcell(gNB_RRC_UE_t *UE, const nr_rrc_cell_container_t *cell);
#endif /* RRC_CELL_MANAGEMENT_H_ */
+26 -20
View File
@@ -60,6 +60,7 @@
#include "common/openairinterface5g_limits.h"
#include "common/platform_constants.h"
#include "common/ran_context.h"
#include "common/utils/nr/nr_common.h"
#include "common_lib.h"
#include "constr_SEQUENCE.h"
#include "constr_TYPE.h"
@@ -1416,8 +1417,13 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc,
rrc_gNB_generate_RRCReject(rrc, ue_context_p);
return;
}
/* Add PCell to serving_cells array */
rrc_add_ue_serving_cell(UE, cell, RRC_PCELL_INDEX);
/* Update PCell in serving_cells array */
ue_serving_cell_t *added = rrc_update_ue_pcell(UE, cell);
if (added == NULL) {
LOG_E(NR_RRC, "RRCSetup: failed to add PCell (cell %ld)\n", cell->info.cell_id);
rrc_gNB_generate_RRCReject(rrc, ue_context_p);
return;
}
UE->ongoing_reconfiguration = false;
UE->measConfig = nr_rrc_get_measconfig(rrc, msg->nr_cellid);
activate_srb(UE, 1);
@@ -1501,6 +1507,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
long ngap_cause = NGAP_CAUSE_RADIO_NETWORK_UNSPECIFIED; /* cause in case of NGAP release req */
const rnti_t old_rnti = req->ue_Identity.c_RNTI;
rrc_gNB_ue_context_t *ue_context_p = NULL;
ue_serving_cell_t *added = NULL;
LOG_I(NR_RRC,
"Reestablishment RNTI %04x req C-RNTI %04x physCellId %ld cause %s\n",
msg->crnti,
@@ -1514,12 +1521,6 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
return;
}
// Validate C-RNTI range (3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1)
if (old_rnti < 0x1 || old_rnti > 0xffef) {
LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI %04x range error, fallback to RRC setup\n", old_rnti);
goto fallback_rrc_setup;
}
// Fetch current cell: where the reestablishment request was received
nr_rrc_cell_container_t *current_cell = get_cell_by_cell_id(&rrc->cells, msg->nr_cellid);
if (current_cell == NULL || current_cell->assoc_id != du->assoc_id) {
@@ -1530,6 +1531,12 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
return;
}
// Validate C-RNTI range (3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1)
if (old_rnti < 0x1 || old_rnti > 0xffef) {
LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI %04x range error, fallback to RRC setup\n", old_rnti);
goto fallback_rrc_setup;
}
if (current_cell->mtc == NULL) {
// some UEs don't send MeasurementTimingConfiguration, so we don't know the
// SSB ARFCN and can't do reestablishment. handle it gracefully by doing
@@ -1660,14 +1667,10 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
/* Update PCell in serving_cells array */
DevAssert(cell->info.cell_id == msg->nr_cellid);
// Reset the serving set to the new PCell, remove all serving cells from the current PCell's DU.
const ue_serving_cell_t *existing_pcell = ue_get_pcell_entry(UE);
DevAssert(existing_pcell != NULL);
rrc_remove_ue_scells_from_du(UE, existing_pcell->assoc_id);
ue_serving_cell_t *added = rrc_add_ue_serving_cell(UE, cell, RRC_PCELL_INDEX);
added = rrc_update_ue_pcell(UE, cell);
if (added == NULL) {
LOG_E(NR_RRC, "Reestablishment: failed to add PCell (cell %ld), rejecting reestablishment\n", cell->info.cell_id);
goto fallback_rrc_setup;
LOG_E(NR_RRC, "Reestablishment: failed to add PCell (cell %ld)\n", cell->info.cell_id);
return;
}
ue_data.secondary_ue = msg->gNB_DU_ue_id;
@@ -1688,6 +1691,8 @@ fallback_rrc_setup:
rrc_gNB_ue_context_t *new = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id);
activate_srb(&new->ue_context, 1);
added = rrc_update_ue_pcell(&new->ue_context, current_cell);
DevAssert(added);
rrc_gNB_generate_RRCSetup(0, msg->crnti, new, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length);
return;
}
@@ -2073,7 +2078,7 @@ static void handle_rrcSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const N
uint16_t stmsi_part2 = BIT_STRING_to_uint16(part2);
LOG_I(RRC, "s_tmsi part2 %d (%02x %02x)\n", stmsi_part2, part2->buf[0], part2->buf[1]);
// Part2 is leftmost 9, Part1 is rightmost 39 bits of 5G-S-TMSI
fiveg_s_TMSI = ((uint64_t) stmsi_part2) << 39 | UE->ng_5G_S_TMSI_Part1;
fiveg_s_TMSI = nr_build_full_5g_s_tmsi(UE->ng_5G_S_TMSI_Part1, stmsi_part2);
} else {
LOG_W(RRC, "UE %d received 5G-S-TMSI-Part2, but no 5G-S-TMSI-Part1 present, won't send 5G-S-TMSI to core\n", UE->rrc_ue_id);
UE->Initialue_identity_5g_s_TMSI.presence = false;
@@ -2090,9 +2095,10 @@ static void handle_rrcSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const N
}
if (UE->Initialue_identity_5g_s_TMSI.presence) {
uint16_t amf_set_id = fiveg_s_TMSI >> 38;
uint8_t amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F;
uint32_t fiveg_tmsi = (uint32_t) fiveg_s_TMSI;
uint16_t amf_set_id;
uint8_t amf_pointer;
uint32_t fiveg_tmsi;
nr_deconstruct_5g_s_tmsi(fiveg_s_TMSI, &amf_set_id, &amf_pointer, &fiveg_tmsi);
LOG_I(NR_RRC,
"5g_s_TMSI: 0x%lX, amf_set_id: 0x%X (%d), amf_pointer: 0x%X (%d), 5g TMSI: 0x%X \n",
fiveg_s_TMSI,
@@ -3521,7 +3527,7 @@ void *rrc_gnb_task(void *args_p) {
break;
case NGAP_PAGING_IND:
rrc_gNB_process_PAGING_IND(msg_p, instance);
rrc_gNB_process_PAGING_IND(RC.nrrrc[instance], instance, &NGAP_PAGING_IND(msg_p));
break;
case NGAP_HANDOVER_REQUEST:
+60 -48
View File
@@ -84,6 +84,7 @@
#include "nr_pdcp/nr_pdcp_oai_api.h"
#include "oai_asn1.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/F1AP/lib/f1ap_paging.h"
#include "openair3/SECU/key_nas_deriver.h"
#include "rrc_messages_types.h"
#include "s1ap_messages_types.h"
@@ -1629,56 +1630,67 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(ngap_pdusession_release_comm
return 0;
}
int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance)
/** @brief Handle NGAP Paging Indication from the AMF.
* For each TAI in the message, matches (PLMN + TAC) against the gNB configuration; on match,
* builds an F1AP Paging message and distributes it to all DUs that serve cells in that PLMN. */
int rrc_gNB_process_PAGING_IND(gNB_RRC_INST *rrc, const instance_t instance, const ngap_paging_ind_t *msg)
{
ngap_paging_ind_t *msg = &NGAP_PAGING_IND(msg_p);
for (uint16_t tai_size = 0; tai_size < msg->tai_size; tai_size++) {
plmn_id_t *p = &msg->plmn_identity[tai_size];
LOG_I(NR_RRC,
"[gNB %ld] TAI List for Paging: MCC=%03d, MNC=%0*d, TAC=%d\n",
DevAssert(rrc);
DevAssert(msg);
// Construct 5G-S-TMSI from paging identity components
const fiveg_s_tmsi_t *s_tmsi = &msg->ue_paging_identity.s_tmsi;
const uint64_t fiveg_s_tmsi = nr_construct_5g_s_tmsi(s_tmsi->amf_set_id, s_tmsi->amf_pointer, s_tmsi->m_tmsi);
const nr_rrc_config_t *req = &rrc->configuration;
DevAssert(req->num_plmn > 0);
LOG_D(NR_RRC, "[gNB %ld] Processing NGAP Paging Indication for %d TAIs\n", instance, msg->n_tai);
// Paging Attempt Information (TS 38.413 §9.3.1.72, TS 38.300 §9.2.5)
// AMF provides attempt count and intended attempts for paging optimization (area expansion, retransmission logic).
if (msg->paging_attempt_info != NULL) {
LOG_D(NR_RRC,
"[gNB %ld] Paging Attempt Count: %u, Intended Number of Attempts: %u\n",
instance,
p->mcc,
p->mnc_digit_length,
p->mnc,
msg->tac[tai_size]);
nr_rrc_config_t *req = &RC.nrrrc[instance]->configuration;
for (uint8_t j = 0; j < req->num_plmn; j++) {
plmn_id_t *req_plmn = &req->plmn[j];
if (req_plmn->mcc == p->mcc && req_plmn->mnc == p->mnc && req->tac == msg->tac[tai_size]) {
for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
AssertFatal(false, "to be implemented properly\n");
if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) {
MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND);
F1AP_PAGING_IND(m).plmn = *req_plmn;
// Construct 5G-S-TMSI-Part1 from paging identity to find UE
const fiveg_s_tmsi_t *s_tmsi = &msg->ue_paging_identity.s_tmsi;
uint64_t s_tmsi_part1 = nr_construct_5g_s_tmsi_part1(s_tmsi->amf_set_id, s_tmsi->amf_pointer, s_tmsi->m_tmsi);
// Try to find UE by 5G-S-TMSI-Part1
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(RC.nrrrc[instance], s_tmsi_part1);
if (ue_context_p == NULL) {
LOG_W(NR_RRC, "UE not found by paging identity\n");
return -1;
}
// UE found: use its associated cell
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
nr_rrc_cell_container_t *cell = rrc_get_pcell_for_ue(RC.nrrrc[instance], UE);
if (cell == NULL) {
LOG_W(NR_RRC, "UE %d (rnti %04x) found by paging identity but has no valid cell\n", UE->rrc_ue_id, UE->rnti);
return -1;
}
F1AP_PAGING_IND(m).nr_cellid = cell->info.cell_id;
F1AP_PAGING_IND(m).ueidentityindexvalue = (uint16_t)(msg->ue_paging_identity.s_tmsi.m_tmsi % 1024);
F1AP_PAGING_IND(m).fiveg_s_tmsi = msg->ue_paging_identity.s_tmsi.m_tmsi;
F1AP_PAGING_IND(m).paging_drx = msg->paging_drx;
LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx);
itti_send_msg_to_task(TASK_CU_F1, instance, m);
} else {
//rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id);
} // end of nodetype check
} // end of cc loop
} // end of mcc mnc check
} // end of num_plmn
} // end of tai size
msg->paging_attempt_info->paging_attempt_count,
msg->paging_attempt_info->intended_paging_attempts);
}
if (msg->n_tai > NGAP_MAX_NO_TAI_PAGING) {
LOG_E(NR_RRC,
"[gNB %ld] Paging message error: n_tai (%d) exceeds NGAP_MAX_NO_TAI_PAGING (%d)\n",
instance,
msg->n_tai,
NGAP_MAX_NO_TAI_PAGING);
return -1;
}
// Build F1AP paging message once for all TAIs
f1ap_paging_t f1ap_msg = {0};
f1ap_msg.ue_identity_index_value = s_tmsi->m_tmsi % 1024;
f1ap_msg.identity_type = F1AP_PAGING_IDENTITY_CN_UE;
f1ap_msg.identity.cn_ue_paging_identity = fiveg_s_tmsi;
if (msg->paging_drx != NULL) {
/* Mapping 1:1 between NGAP and F1AP Paging DRX */
f1ap_msg.drx = malloc_or_fail(sizeof(*f1ap_msg.drx));
*f1ap_msg.drx = (f1ap_paging_drx_t)*msg->paging_drx;
}
if (msg->paging_priority != NULL) {
/* Mapping 1:1 between NGAP and F1AP Paging Priority */
f1ap_msg.priority = malloc_or_fail(sizeof(*f1ap_msg.priority));
*f1ap_msg.priority = (f1ap_paging_priority_t)*msg->paging_priority;
}
if (msg->origin != NULL) {
/* Mapping 1:1 between NGAP and F1AP Paging Origin */
f1ap_msg.origin = malloc_or_fail(sizeof(*f1ap_msg.origin));
*f1ap_msg.origin = (f1ap_paging_origin_t)*msg->origin;
}
// For each DU, collect cells matching any AMF TAI (PLMN+TAC) and send
// one Paging with that cell list.
rrc_send_paging_to_dus(rrc, msg->tai_list, msg->n_tai, &f1ap_msg);
free_f1ap_paging(&f1ap_msg);
return 0;
}
+1 -1
View File
@@ -84,7 +84,7 @@ void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE
void nr_rrc_pdcp_config_security(gNB_RRC_UE_t *UE, bool enable_ciphering);
int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance);
int rrc_gNB_process_PAGING_IND(gNB_RRC_INST *rrc, const instance_t instance, const ngap_paging_ind_t *msg);
void rrc_gNB_send_NGAP_HANDOVER_REQUIRED(gNB_RRC_INST *rrc,
gNB_RRC_UE_t *UE,
+68
View File
@@ -820,3 +820,71 @@ void trigger_f1_reset(gNB_RRC_INST *rrc, sctp_assoc_t du_assoc_id)
};
rrc->mac_rrc.f1_reset(du_assoc_id, &reset);
}
/** @brief Distribute paging to DUs serving cells matching any of the requested TAIs.
* Loops DUs once, collects matching cells per DU, sends one message per DU.
* Each cell is added at most once per DU (cells are unique by cell_id within a DU).
* Per 3GPP TS 23.003, TAI is uniquely identified by (PLMN, TAC) combination.
* @param rrc RRC instance
* @param tais Array of TAIs (PLMN + TAC) to match against
* @param n_tai Number of TAIs in the array (must be > 0)
* @param msg Pre-filled F1AP paging message */
void rrc_send_paging_to_dus(gNB_RRC_INST *rrc, const nr_tai_t tais[], uint8_t n_tai, f1ap_paging_t *msg)
{
DevAssert(msg && !msg->cells);
DevAssert(n_tai > 0);
nr_rrc_du_container_t *du = NULL;
// Loop over DUs once, for each DU, collects matching cells
RB_FOREACH (du, rrc_du_tree, &rrc->dus) {
RETURN_IF_INVALID_ASSOC_ID(du->assoc_id);
// Stack-allocated cell list for this DU iteration
f1ap_paging_cell_item_t cells[F1AP_MAX_NB_CELLS] = {0};
msg->cells = cells;
msg->n_cells = 0;
// For each cell in this DU, check if it matches any of the matching TAIs
FOR_EACH_SEQ_ARR (nr_rrc_cell_container_t **, cell, &du->cells) {
if (msg->n_cells >= F1AP_MAX_NB_CELLS) {
LOG_W(F1AP,
"[gNB] Paging: DU assoc_id %d has more than %d matching cells, skipping next cells\n",
du->assoc_id,
F1AP_MAX_NB_CELLS);
break;
}
const nr_rrc_cell_info_t *info = &(*cell)->info;
const plmn_id_t *cell_plmn = &info->plmn;
const uint16_t cell_tac = info->tac;
// Check if this cell's TAI (PLMN + TAC) matches any of the matching TAIs
for (uint8_t j = 0; j < n_tai; j++) {
const nr_tai_t *req_tai = &tais[j];
const plmn_id_t *req_plmn = &req_tai->plmn;
const uint16_t req_tac = req_tai->tac;
if (cell_plmn->mcc == req_plmn->mcc && cell_plmn->mnc == req_plmn->mnc
&& cell_plmn->mnc_digit_length == req_plmn->mnc_digit_length && cell_tac == req_tac) {
f1ap_paging_cell_item_t *paging_cell = &msg->cells[msg->n_cells++];
paging_cell->plmn = *cell_plmn;
paging_cell->nr_cellid = info->cell_id;
break; // Found match, no need to check other TAIs
}
}
}
// Skip DUs with no matching cells
if (msg->n_cells == 0)
continue;
DevAssert(msg->n_cells <= F1AP_MAX_NB_CELLS);
LOG_I(F1AP,
"[gNB] Paging transfer to DU assoc_id %d: ue_identity_index_value=%u, paging_identity=%lu, n_cells=%u\n",
du->assoc_id,
msg->ue_identity_index_value,
msg->identity.cn_ue_paging_identity,
msg->n_cells);
// Send one message to the DU with all matching cells
rrc->mac_rrc.paging_transfer(du->assoc_id, msg);
}
msg->cells = NULL; // Stack allocation, no need to free
}
+5
View File
@@ -34,6 +34,9 @@ struct nr_rrc_cell_container_t;
struct f1ap_gnb_du_configuration_update_s;
struct f1ap_served_cell_info_t;
#include "f1ap_messages_types.h"
#include "ngap_messages_types.h"
void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id);
void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id);
void rrc_gNB_process_f1_du_configuration_update(struct f1ap_gnb_du_configuration_update_s *conf_up, sctp_assoc_t assoc_id);
@@ -58,4 +61,6 @@ struct nr_rrc_du_container_t *find_target_du(struct gNB_RRC_INST_s *rrc, sctp_as
void trigger_f1_reset(struct gNB_RRC_INST_s *rrc, sctp_assoc_t du_assoc_id);
void rrc_send_paging_to_dus(struct gNB_RRC_INST_s *rrc, const nr_tai_t tais[], uint8_t n_tai, f1ap_paging_t *f1ap_msg);
#endif /* RRC_GNB_DU_H_ */
+12 -26
View File
@@ -453,36 +453,22 @@ bool nr_rrc_update_cell_assoc_after_ho(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
return false;
}
if (UE->ho_context->source) {
/* F1 HO (intra-CU): migrate serving cells from source DU to target cell */
nr_ho_source_cu_t *source_ctx = UE->ho_context->source;
// Remove SCells that belong to the source DU during handover (cell group changes)
// This also removes PCell if it was on the source DU
rrc_remove_ue_scells_from_du(UE, source_ctx->cell->assoc_id);
// Update PCell in serving_cells
ue_serving_cell_t *added = rrc_add_ue_serving_cell(UE, target_ctx->cell, RRC_PCELL_INDEX);
if (added == NULL) {
LOG_E(NR_RRC,
"UE %d handover: failed to add PCell (cell %ld) to serving cells\n",
UE->rrc_ue_id,
target_ctx->cell->info.cell_id);
return false;
}
} else {
if (!UE->ho_context->source) {
/* Inter-CU (N2/Xn target): this UE context has no serving cells yet */
const ue_serving_cell_t *existing_pcell = ue_get_pcell_entry(UE);
AssertFatal(existing_pcell == NULL, "UE context should not have PCell yet (inter-CU target)\n");
}
ue_serving_cell_t *added = rrc_add_ue_serving_cell(UE, target_ctx->cell, RRC_PCELL_INDEX);
if (added == NULL) {
LOG_E(NR_RRC,
"UE %d handover: failed to add PCell (cell %ld) to serving cells\n",
UE->rrc_ue_id,
target_ctx->cell->info.cell_id);
return false;
}
/* Update PCell: removes all serving cells from existing PCell's DU (if any)
* and adds the target cell as the new PCell. For F1 HO (intra-CU), this
* migrates serving cells from source DU to target DU. */
ue_serving_cell_t *added = rrc_update_ue_pcell(UE, target_ctx->cell);
if (added == NULL) {
LOG_E(NR_RRC,
"UE %d handover: failed to add PCell (cell %ld) to serving cells\n",
UE->rrc_ue_id,
target_ctx->cell->info.cell_id);
return false;
}
return true;
+1 -1
View File
@@ -100,7 +100,7 @@ $(OBJ) : %.o : %.c
$(L2_OBJS) : %.o : %.c
$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 -I$(TOP_DIR) $(L2_incl) -o $@ $<
physim : $(OBJ) $(L2_OBJS) OMG.c common.c static.c job.c rwp.c rwalk.c hashtable.c mobility_parser.c trace.c -I$(TOP_DIR) $(L2_incl) -o physim $(CFLAGS) $(EXTRA_CFLAGS) $(OBJ) $(L2_OBJS) -lm -lforms -L/usr/local/lib -lforms -lX11 -L/usr/X11R6/lib -lXpm -lblas -lpthread
physim : $(OBJ) $(L2_OBJS) OMG.c common.c static.c job.c rwp.c rwalk.c hashtable.c mobility_parser.c trace.c -I$(TOP_DIR) $(L2_incl) -o physim $(CFLAGS) $(EXTRA_CFLAGS) $(OBJ) $(L2_OBJS) -lm -lforms -L/usr/local/lib -lforms -lX11 -L/usr/X11R6/lib -lXpm -lpthread
clean:
rm -f physim
+1
View File
@@ -1,4 +1,5 @@
add_subdirectory(LPP)
add_subdirectory(ocp-gtpu)
add_subdirectory(M3AP)
add_subdirectory(S1AP)
add_subdirectory(NAS)
@@ -32,6 +32,7 @@
#include <stdint.h>
#include "OctetString.h"
#include "fgs_nas_utils.h"
#include "common/utils/utils.h" // text_info_t, TO_ENUM, TO_TEXT
#ifndef FGS_MOBILE_IDENTITY_H_
#define FGS_MOBILE_IDENTITY_H_
@@ -22,6 +22,7 @@
#include <stdint.h>
#include "FGSNASSecurityModeReject.h"
#include "common/utils/ds/byte_array.h"
#include "common/utils/eq_check.h"
#include "fgmm_lib.h"
int encode_fgs_security_mode_reject(byte_array_t *buffer, const fgs_security_mode_reject_msg *msg)
@@ -45,6 +46,6 @@ int decode_fgs_security_mode_reject(fgs_security_mode_reject_msg *msg, const byt
bool eq_sec_mode_reject(const fgs_security_mode_reject_msg *a, const fgs_security_mode_reject_msg *b)
{
_NAS_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_INT(a->cause, b->cause);
return true;
}
@@ -35,6 +35,7 @@
#include "conversions.h"
#include "RegistrationAccept.h"
#include "fgs_nas_utils.h"
#include "common/utils/eq_check.h"
#include "common/utils/utils.h"
#include "ds/byte_array.h"
#include "fgmm_lib.h"
@@ -47,7 +48,7 @@
static int decode_fgs_registration_result(registration_accept_msg *out, const byte_array_t buffer)
{
if (buffer.len < FGS_REGISTRATION_RESULT_LEN) {
PRINT_NAS_ERROR("5GS registration result decoding failure: invalid buffer length\n");
PRINT_ERROR("5GS registration result decoding failure: invalid buffer length\n");
return -1;
}
out->result = buffer.buf[1] & 0x7; // skip length of contents octet
@@ -58,7 +59,7 @@ static int decode_fgs_registration_result(registration_accept_msg *out, const by
static int encode_fgs_registration_result(byte_array_t buffer, const registration_accept_msg *out)
{
if (buffer.len < FGS_REGISTRATION_RESULT_LEN) {
PRINT_NAS_ERROR("5GS registration result encoding failure: invalid buffer length\n");
PRINT_ERROR("5GS registration result encoding failure: invalid buffer length\n");
return -1;
}
uint8_t *buf = buffer.buf;
@@ -125,7 +126,7 @@ static int decode_nssai_ie(nr_nas_msg_snssai_t *nssai, uint8_t *num_slices, uint
break;
default:
PRINT_NAS_ERROR("Unknown length in Allowed S-NSSAI list item\n");
PRINT_ERROR("Unknown length in Allowed S-NSSAI list item\n");
break;
}
}
@@ -139,7 +140,7 @@ size_t decode_registration_accept(registration_accept_msg *registration_accept,
byte_array_t ba = buffer; // local copy of buffer
if (ba.len < REGISTRATION_ACCEPT_MIN_LEN) {
PRINT_NAS_ERROR("Registration Accept decoding failed: invalid buffer length\n");
PRINT_ERROR("Registration Accept decoding failed: invalid buffer length\n");
return -1;
}
@@ -152,7 +153,7 @@ size_t decode_registration_accept(registration_accept_msg *registration_accept,
if (ba.len > 0 && ba.buf[0] == IEI_5G_GUTI) {
registration_accept->guti = calloc_or_fail(1, sizeof(*registration_accept->guti));
if ((dec = decode_5gs_mobile_identity(registration_accept->guti, IEI_5G_GUTI, ba.buf, ba.len)) < 0) {
PRINT_NAS_ERROR("Failed to decode 5GS Mobile Identity in Registration Accept\n");
PRINT_ERROR("Failed to decode 5GS Mobile Identity in Registration Accept\n");
return -1;
}
UPDATE_BYTE_ARRAY(ba, dec);
@@ -182,7 +183,7 @@ size_t decode_registration_accept(registration_accept_msg *registration_accept,
}
}
if(ba.len != 0) {
PRINT_NAS_ERROR("Failed to decode registration accept: ba.len = %ld\n", ba.len);
PRINT_ERROR("Failed to decode registration accept: ba.len = %ld\n", ba.len);
return -1;
}
return buffer.len;
@@ -209,22 +210,22 @@ int encode_registration_accept(const registration_accept_msg *registration_accep
bool eq_snssai(const nr_nas_msg_snssai_t *a, const nr_nas_msg_snssai_t *b)
{
_NAS_EQ_CHECK_INT(a->sst, b->sst);
_EQ_CHECK_INT(a->sst, b->sst);
if ((a->hplmn_sst && !b->hplmn_sst) || (!a->hplmn_sst && b->hplmn_sst))
return false;
if (a->hplmn_sst && b->hplmn_sst)
_NAS_EQ_CHECK_INT(*a->hplmn_sst, *b->hplmn_sst);
_EQ_CHECK_INT(*a->hplmn_sst, *b->hplmn_sst);
if ((a->sd && !b->sd) || (!a->sd && b->sd))
return false;
if (a->sd && b->sd)
_NAS_EQ_CHECK_INT(*a->sd, *b->sd);
_EQ_CHECK_INT(*a->sd, *b->sd);
if ((a->hplmn_sd && !b->hplmn_sd) || (!a->hplmn_sd && b->hplmn_sd))
return false;
if (a->hplmn_sd && b->hplmn_sd)
_NAS_EQ_CHECK_INT(*a->hplmn_sd, *b->hplmn_sd);
_EQ_CHECK_INT(*a->hplmn_sd, *b->hplmn_sd);
return true;
}
@@ -233,48 +234,48 @@ bool eq_snssai(const nr_nas_msg_snssai_t *a, const nr_nas_msg_snssai_t *b)
bool eq_fgmm_registration_accept(const registration_accept_msg *a, const registration_accept_msg *b)
{
if (!a || !b) {
PRINT_NAS_ERROR("Null pointer in registration_accept_msg_eq\n");
PRINT_ERROR("Null pointer in registration_accept_msg_eq\n");
return false;
}
// 5GS registration result (mandatory)
_NAS_EQ_CHECK_INT(a->result, b->result);
_NAS_EQ_CHECK_INT(a->sms_allowed, b->sms_allowed);
_EQ_CHECK_INT(a->result, b->result);
_EQ_CHECK_INT(a->sms_allowed, b->sms_allowed);
// GUTI (optional)
if (a->guti && b->guti) {
_NAS_EQ_CHECK_INT(a->guti->guti.spare, b->guti->guti.spare);
_NAS_EQ_CHECK_INT(a->guti->guti.oddeven, b->guti->guti.oddeven);
_NAS_EQ_CHECK_INT(a->guti->guti.typeofidentity, b->guti->guti.typeofidentity);
_NAS_EQ_CHECK_INT(a->guti->guti.mccdigit2, b->guti->guti.mccdigit2);
_NAS_EQ_CHECK_INT(a->guti->guti.mccdigit1, b->guti->guti.mccdigit1);
_NAS_EQ_CHECK_INT(a->guti->guti.mncdigit3, b->guti->guti.mncdigit3);
_NAS_EQ_CHECK_INT(a->guti->guti.mccdigit3, b->guti->guti.mccdigit3);
_NAS_EQ_CHECK_INT(a->guti->guti.mncdigit2, b->guti->guti.mncdigit2);
_NAS_EQ_CHECK_INT(a->guti->guti.mncdigit1, b->guti->guti.mncdigit1);
_NAS_EQ_CHECK_INT(a->guti->guti.amfregionid, b->guti->guti.amfregionid);
_NAS_EQ_CHECK_INT(a->guti->guti.amfsetid, b->guti->guti.amfsetid);
_NAS_EQ_CHECK_INT(a->guti->guti.amfpointer, b->guti->guti.amfpointer);
_NAS_EQ_CHECK_INT(a->guti->guti.tmsi, b->guti->guti.tmsi);
_EQ_CHECK_INT(a->guti->guti.spare, b->guti->guti.spare);
_EQ_CHECK_INT(a->guti->guti.oddeven, b->guti->guti.oddeven);
_EQ_CHECK_INT(a->guti->guti.typeofidentity, b->guti->guti.typeofidentity);
_EQ_CHECK_INT(a->guti->guti.mccdigit2, b->guti->guti.mccdigit2);
_EQ_CHECK_INT(a->guti->guti.mccdigit1, b->guti->guti.mccdigit1);
_EQ_CHECK_INT(a->guti->guti.mncdigit3, b->guti->guti.mncdigit3);
_EQ_CHECK_INT(a->guti->guti.mccdigit3, b->guti->guti.mccdigit3);
_EQ_CHECK_INT(a->guti->guti.mncdigit2, b->guti->guti.mncdigit2);
_EQ_CHECK_INT(a->guti->guti.mncdigit1, b->guti->guti.mncdigit1);
_EQ_CHECK_INT(a->guti->guti.amfregionid, b->guti->guti.amfregionid);
_EQ_CHECK_INT(a->guti->guti.amfsetid, b->guti->guti.amfsetid);
_EQ_CHECK_INT(a->guti->guti.amfpointer, b->guti->guti.amfpointer);
_EQ_CHECK_INT(a->guti->guti.tmsi, b->guti->guti.tmsi);
} else if ((a->guti && !b->guti) || (!a->guti && b->guti)) {
PRINT_NAS_ERROR("NAS Equality Check failure: One of the two GUTIs is NULL\n");
PRINT_ERROR("NAS Equality Check failure: One of the two GUTIs is NULL\n");
return false;
}
_NAS_EQ_CHECK_INT(a->num_allowed_slices, b->num_allowed_slices);
_NAS_EQ_CHECK_INT(a->num_configured_slices, b->num_configured_slices);
_EQ_CHECK_INT(a->num_allowed_slices, b->num_allowed_slices);
_EQ_CHECK_INT(a->num_configured_slices, b->num_configured_slices);
// Configured NSSAI (optional)
for (int i = 0; i < a->num_configured_slices; i++) {
if (!eq_snssai(&a->config_nssai[i], &b->config_nssai[i])) {
PRINT_NAS_ERROR("NAS Equality Check failure: Configured NSSAI\n");
PRINT_ERROR("NAS Equality Check failure: Configured NSSAI\n");
return false;
}
}
// Allowed NSSAI (optional)
for (int i = 0; i < a->num_allowed_slices; i++) {
if (!eq_snssai(&a->nas_allowed_nssai[i], &b->nas_allowed_nssai[i])) {
PRINT_NAS_ERROR("NAS Equality Check failure: Allowed NSSAI\n");
PRINT_ERROR("NAS Equality Check failure: Allowed NSSAI\n");
return false;
}
}
@@ -25,6 +25,7 @@
#include <stdlib.h> // For malloc and free
#include "fgmm_lib.h"
#include "common/utils/ds/byte_array.h"
#include "common/utils/eq_check.h"
#include "common/utils/utils.h"
#define MIN_AUTH_FAILURE_LEN 1
@@ -35,7 +36,7 @@
int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg)
{
if (buffer->len < MIN_AUTH_FAILURE_LEN) {
PRINT_NAS_ERROR("Missing mandatory IE in Authentication Failure");
PRINT_ERROR("Missing mandatory IE in Authentication Failure");
return -1; // missing mandatory IE
}
// 5GMM cause (Mandatory)
@@ -44,11 +45,11 @@ int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *ms
if (msg->cause == Synch_failure) {
// Authentication failure parameter shall be present with cause Synch Failure
if (msg->authentication_failure_param.len == 0) {
PRINT_NAS_ERROR("Authentication Failure Cause is synch failure but Authentication Failure Parameter is not available");
PRINT_ERROR("Authentication Failure Cause is synch failure but Authentication Failure Parameter is not available");
return -1;
}
if (buffer->len - encoded < msg->authentication_failure_param.len + 2) {
PRINT_NAS_ERROR("Invalid buffer for encoding of Authentication Failure Parameter");
PRINT_ERROR("Invalid buffer for encoding of Authentication Failure Parameter");
return -1;
}
// Encode the IEI
@@ -76,7 +77,7 @@ int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffe
if (iei == AUTH_FAIL_PARAM_IEI) {
msg->authentication_failure_param.len = ba.buf[decoded++];
if (msg->authentication_failure_param.len > AUTH_FAILURE_PARAM_LEN - 2) { // maximum length of contents is 14 octets
PRINT_NAS_ERROR("Length of Authentication Failure Parameter contents is too large");
PRINT_ERROR("Length of Authentication Failure Parameter contents is too large");
return -1;
}
msg->authentication_failure_param.buf = malloc_or_fail(msg->authentication_failure_param.len);
@@ -90,7 +91,7 @@ int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffe
bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b)
{
_NAS_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_INT(a->cause, b->cause);
eq_byte_array(&a->authentication_failure_param, &b->authentication_failure_param);
return true;
}
@@ -24,6 +24,7 @@
#include <arpa/inet.h> // For htons and ntohs
#include <stdlib.h> // For malloc and free
#include "fgmm_lib.h"
#include "common/utils/eq_check.h"
#define MIN_AUTH_REJECT_LEN 3
@@ -55,13 +56,13 @@ int decode_fgmm_auth_reject(fgmm_auth_reject_msg_t *msg, const byte_array_t *buf
if (iei == IEI_EAPMSG) {
return (decoded + decode_eap_msg_ie(&msg->eap_msg, &ba));
}
PRINT_NAS_ERROR("Expected EAP MSG but it is not present");
PRINT_ERROR("Expected EAP MSG but it is not present");
return -1;
}
bool eq_auth_reject(fgmm_auth_reject_msg_t *a, fgmm_auth_reject_msg_t *b)
{
_NAS_EQ_CHECK_LONG(a->eap_msg.len, b->eap_msg.len);
_EQ_CHECK_LONG(a->eap_msg.len, b->eap_msg.len);
if (a->eap_msg.len > 0) {
return !memcmp(a->eap_msg.buf, b->eap_msg.buf, a->eap_msg.len);
}
@@ -22,11 +22,12 @@
#include "fgmm_identity_request.h"
#include <string.h>
#include "FGSMobileIdentity.h"
#include "common/utils/eq_check.h"
int decode_fgs_identity_request(fgs_identity_request_msg_t *msg, const byte_array_t *buffer)
{
if (buffer->len < 1) {
PRINT_NAS_ERROR("Failed to decode NAS Identity Request: invalid buffer length %ld\n", buffer->len);
PRINT_ERROR("Failed to decode NAS Identity Request: invalid buffer length %ld\n", buffer->len);
return -1;
}
+12 -11
View File
@@ -24,6 +24,7 @@
#include <arpa/inet.h> // For htons and ntohs
#include <stdlib.h> // For malloc and free
#include "common/utils/ds/byte_array.h"
#include "common/utils/eq_check.h"
#define IEI_LEN 1
#define GPRS_TIMER_LENGTH 3 // octets
@@ -41,7 +42,7 @@
int encode_pdu_session_ie(byte_array_t *buffer, nas_service_IEI_t iei, const uint8_t *psi)
{
if (buffer->len < MIN_PDU_SESSION_CONTENTS_LEN + 2) {
PRINT_NAS_ERROR("%s failed: buffer is too small", __func__);
PRINT_ERROR("%s failed: buffer is too small", __func__);
return -1;
}
@@ -83,14 +84,14 @@ int decode_pdu_session_ie(uint8_t *psi, const byte_array_t *buffer)
uint8_t *buf = buffer->buf;
if (buffer->len < MIN_PDU_SESSION_CONTENTS_LEN + 2) {
PRINT_NAS_ERROR("%s failed: buffer length is too small", __func__);
PRINT_ERROR("%s failed: buffer length is too small", __func__);
return -1;
}
// start decoding from length IE (IEI is decoded in the caller)
uint8_t pdu_session_status_len = buf[decoded++];
if (pdu_session_status_len > MAX_PDU_SESSION_CONTENTS_LEN) {
PRINT_NAS_ERROR("decoded length is out of bound for PDU Session Status/Reactivation result\n");
PRINT_ERROR("decoded length is out of bound for PDU Session Status/Reactivation result\n");
return -1;
}
@@ -116,7 +117,7 @@ int decode_pdu_session_ie(uint8_t *psi, const byte_array_t *buffer)
int encode_gprs_timer_ie(byte_array_t *buffer, nas_service_IEI_t iei, const gprs_timer_t *timer)
{
if (buffer->len < GPRS_TIMER_LENGTH) {
PRINT_NAS_ERROR("Buffer length is too short to encode the GPRS Timer IE\n");
PRINT_ERROR("Buffer length is too short to encode the GPRS Timer IE\n");
return -1;
}
@@ -150,8 +151,8 @@ int decode_gprs_timer_ie(gprs_timer_t *timer, const byte_array_t *buffer)
/** @brief Equality check for GPRS Timer */
bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b)
{
_NAS_EQ_CHECK_INT(a->value, b->value);
_NAS_EQ_CHECK_INT(a->unit, b->unit);
_EQ_CHECK_INT(a->value, b->value);
_EQ_CHECK_INT(a->unit, b->unit);
return true;
}
@@ -162,13 +163,13 @@ int encode_eap_msg_ie(byte_array_t *buffer, const byte_array_t *msg)
// Sanity check on buffer length
if (buffer->len < MIN_EAP_MSG_LEN) {
PRINT_NAS_ERROR("Invalid buffer length %ld", buffer->len);
PRINT_ERROR("Invalid buffer length %ld", buffer->len);
return -1;
}
// Sanity check on input length
if (msg->len < MIN_EAP_CONTENTS_LEN || msg->len > MAX_EAP_CONTENTS_LEN) {
PRINT_NAS_ERROR("Invalid EAP message length %ld", msg->len);
PRINT_ERROR("Invalid EAP message length %ld", msg->len);
return -1;
}
@@ -196,7 +197,7 @@ int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer)
// Check buffer length validity
if (buffer->len < min_len_to_decode) {
PRINT_NAS_ERROR("Invalid buffer for decoding EAP message IE");
PRINT_ERROR("Invalid buffer for decoding EAP message IE");
return -1;
}
@@ -206,13 +207,13 @@ int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer)
// Check payload length validity
if (eap_msg->len < MIN_EAP_CONTENTS_LEN || eap_msg->len > MAX_EAP_CONTENTS_LEN) {
PRINT_NAS_ERROR("Invalid EAP message length %ld", eap_msg->len);
PRINT_ERROR("Invalid EAP message length %ld", eap_msg->len);
return -1;
}
// Check for buffer overflow
if (buffer->len < decoded + eap_msg->len) {
PRINT_NAS_ERROR("Buffer too short for EAP message: %ld < %ld", buffer->len, decoded + eap_msg->len);
PRINT_ERROR("Buffer too short for EAP message: %ld < %ld", buffer->len, decoded + eap_msg->len);
return -1;
}
@@ -32,6 +32,7 @@
#include <stdbool.h>
#include "fgs_nas_utils.h"
#include "common/utils/ds/byte_array.h"
#include "common/utils/utils.h"
/* The following defines are valide for
both PDU Session Status and PDU session Reactivation Result IEs */
@@ -25,6 +25,7 @@
#include <stdlib.h> // For malloc and free
#include "common/utils/utils.h" // For malloc_or_fail
#include "common/utils/ds/byte_array.h" // For byte_array_t
#include "common/utils/eq_check.h"
#include "fgmm_lib.h"
/** @brief Encode Service Accept (8.2.17 of 3GPP TS 24.501) */
@@ -53,7 +54,7 @@ int encode_fgs_service_accept(byte_array_t *buffer, const fgs_service_accept_msg
// encode length of PDU session reactivation result error cause
uint16_t error_len = msg->num_errors * sizeof(msg->cause[0]);
if (error_len > MAX_NUM_PDU_ERRORS) {
PRINT_NAS_ERROR("encoded length is out of bound (IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE)\n");
PRINT_ERROR("encoded length is out of bound (IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE)\n");
return -1;
}
uint16_t n_len = htons(error_len);
@@ -115,7 +116,7 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t
uint16_t error_len = ntohs(tmp);
decoded += sizeof(error_len);
if (error_len > MAX_NUM_PDU_ERRORS * sizeof(msg->cause[0])) {
PRINT_NAS_ERROR("IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE: decoded length is out of bound\n");
PRINT_ERROR("IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE: decoded length is out of bound\n");
return -1;
}
// Decode each PDU Session ID and Cause
@@ -137,7 +138,7 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t
break;
default:
PRINT_NAS_ERROR("Unkwown or invalid IEI %d\n", iei);
PRINT_ERROR("Unkwown or invalid IEI %d\n", iei);
return -1;
}
}
@@ -150,26 +151,26 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t
*/
bool eq_service_accept(const fgs_service_accept_msg_t *a, const fgs_service_accept_msg_t *b)
{
_NAS_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
if (a->has_psi_status && b->has_psi_status) {
for (int i = 0; i < MAX_NUM_PSI; i++)
_NAS_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
}
_NAS_EQ_CHECK_INT(a->has_psi_res, b->has_psi_res);
_EQ_CHECK_INT(a->has_psi_res, b->has_psi_res);
if (a->has_psi_res && b->has_psi_res) {
for (int i = 0; i < MAX_NUM_PSI; i++)
_NAS_EQ_CHECK_INT(a->psi_res[i], b->psi_res[i]);
_EQ_CHECK_INT(a->psi_res[i], b->psi_res[i]);
}
_NAS_EQ_CHECK_INT(a->num_errors, b->num_errors);
_EQ_CHECK_INT(a->num_errors, b->num_errors);
if (a->num_errors && b->num_errors) {
for (int i = 0; i < a->num_errors; i++) {
_NAS_EQ_CHECK_INT(a->cause[i].cause, b->cause[i].cause);
_NAS_EQ_CHECK_INT(a->cause[i].pdu_session_id, b->cause[i].pdu_session_id);
_EQ_CHECK_INT(a->cause[i].cause, b->cause[i].cause);
_EQ_CHECK_INT(a->cause[i].pdu_session_id, b->cause[i].pdu_session_id);
}
}
if (a->t3448 != NULL || b->t3448 != NULL) {
if (a->t3448 == NULL || b->t3448 == NULL) {
PRINT_NAS_ERROR("t3448 equality check failed\n");
PRINT_ERROR("t3448 equality check failed\n");
return false;
}
if (!eq_gprs_timer(a->t3448, b->t3448))
@@ -25,6 +25,7 @@
#include <stdlib.h> // For malloc and free
#include "common/utils/ds/byte_array.h"
#include "common/utils/utils.h"
#include "common/utils/eq_check.h"
#include "fgmm_lib.h"
#define SERVICE_REJECT_MIN_LEN 1 // 1 octet
@@ -33,7 +34,7 @@
int encode_fgs_service_reject(byte_array_t *buffer, const fgs_service_reject_msg_t *msg)
{
if (buffer->len < SERVICE_REJECT_MIN_LEN) {
PRINT_NAS_ERROR("Failed to encode Service Reject: missing Cause IE!\n");
PRINT_ERROR("Failed to encode Service Reject: missing Cause IE!\n");
return -1;
}
@@ -71,7 +72,7 @@ int encode_fgs_service_reject(byte_array_t *buffer, const fgs_service_reject_msg
int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t *buffer)
{
if (buffer->len < SERVICE_REJECT_MIN_LEN) {
PRINT_NAS_ERROR("Nothing to decode: missing Cause IE!\n");
PRINT_ERROR("Nothing to decode: missing Cause IE!\n");
return -1;
}
@@ -112,11 +113,11 @@ int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t
int cag_len = cag_list_len + 2; // encoded content + 2 octets for the length IE
decoded += cag_len;
UPDATE_BYTE_ARRAY(ba, cag_len);
PRINT_NAS_ERROR("CAG information list IE in NAS Service Reject is not handled\n");
PRINT_ERROR("CAG information list IE in NAS Service Reject is not handled\n");
} break;
default:
PRINT_NAS_ERROR("Uknown or invalid NAS Service Reject IEI %d\n", iei);
PRINT_ERROR("Uknown or invalid NAS Service Reject IEI %d\n", iei);
return -1;
}
}
@@ -127,15 +128,15 @@ int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t
/** @brief Equality check for Service Reject (enc/dec) */
bool eq_service_reject(const fgs_service_reject_msg_t *a, const fgs_service_reject_msg_t *b)
{
_NAS_EQ_CHECK_INT(a->cause, b->cause);
_NAS_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
if (a->has_psi_status && b->has_psi_status) {
for (int i = 0; i < MAX_NUM_PSI; i++)
_NAS_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
}
if (a->t3448 != NULL || b->t3448 != NULL) {
if (a->t3448 == NULL || b->t3448 == NULL) {
PRINT_NAS_ERROR("t3448 equality check failed\n");
PRINT_ERROR("t3448 equality check failed\n");
return false;
}
if (!eq_gprs_timer(a->t3448, b->t3448))
@@ -143,7 +144,7 @@ bool eq_service_reject(const fgs_service_reject_msg_t *a, const fgs_service_reje
}
if (a->t3446 != NULL || b->t3446 != NULL) {
if (a->t3446 == NULL || b->t3446 == NULL) {
PRINT_NAS_ERROR("t3448 equality check failed\n");
PRINT_ERROR("t3448 equality check failed\n");
return false;
}
if (!eq_gprs_timer(a->t3446, b->t3446))
@@ -23,6 +23,7 @@
#include <arpa/inet.h>
#include "PduSessionEstablishmentAccept.h"
#include "common/utils/LOG/log.h"
#include "common/utils/utils.h" // text_info_t, TO_ENUM, TO_TEXT
#include "fgs_nas_utils.h"
/**
@@ -205,7 +206,7 @@ int decode_pdu_session_establishment_accept_msg(pdu_session_establishment_accept
}
default:
PRINT_NAS_ERROR("Unknown IEI %d\n", psea_iei);
PRINT_ERROR("Unknown IEI %d\n", psea_iei);
curPtr = buffer + msg_length; // we force stop processing
break;
}
@@ -25,6 +25,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "fgs_nas_utils.h"
#include "common/utils/utils.h" // text_info_t, TO_ENUM, TO_TEXT
/* PDU Session Establish Accept Optional IE Identifiers - TS 24.501 Table 8.3.2.1.1 */
+7
View File
@@ -3,6 +3,9 @@ add_subdirectory(5GMM/IES)
add_subdirectory(5GSM/MSG)
if(ENABLE_TESTS)
target_compile_definitions(fgs_5gmm_lib PRIVATE ENABLE_TESTS)
target_compile_definitions(fgs_5gmm_ies_lib PRIVATE ENABLE_TESTS)
target_compile_definitions(fgs_5gsm_lib PRIVATE ENABLE_TESTS)
add_subdirectory(tests)
endif()
add_library(fgs_lib fgs_nas_lib.c)
@@ -16,3 +19,7 @@ target_link_libraries(fgs_lib PUBLIC
)
target_include_directories(fgs_lib PUBLIC . 5GMM/MSG 5GMM/IES)
if(ENABLE_TESTS)
target_compile_definitions(fgs_lib PRIVATE ENABLE_TESTS)
endif()
+7 -6
View File
@@ -22,6 +22,7 @@
#include "NR_NAS_defs.h"
#include "nas_log.h"
#include "TLVEncoder.h"
#include "common/utils/eq_check.h"
#include "fgs_nas_utils.h"
int _nas_mm_msg_encode_header(const fgmm_msg_header_t *header, uint8_t *buffer, uint32_t len)
@@ -56,7 +57,7 @@ int mm_msg_encode(const fgmm_nas_message_plain_t *p, uint8_t *buffer, uint32_t l
int enc_header = _nas_mm_msg_encode_header(&p->header, buffer, len);
if (enc_header < 0) {
PRINT_NAS_ERROR("Failed to encode 5GMM message header\n");
PRINT_ERROR("Failed to encode 5GMM message header\n");
return enc_header;
}
@@ -104,7 +105,7 @@ int mm_msg_encode(const fgmm_nas_message_plain_t *p, uint8_t *buffer, uint32_t l
}
if (enc_msg < 0) {
PRINT_NAS_ERROR("Failed to encode 5GMM message\n");
PRINT_ERROR("Failed to encode 5GMM message\n");
return enc_msg;
}
@@ -116,7 +117,7 @@ int nas_protected_security_header_encode(uint8_t *buffer, const fgs_nas_message_
int size = 0;
if (length < sizeof(fgs_nas_message_security_header_t)) {
PRINT_NAS_ERROR("Could not encode the NAS security header\n");
PRINT_ERROR("Could not encode the NAS security header\n");
return -1;
}
@@ -140,7 +141,7 @@ int nas_protected_security_header_encode(uint8_t *buffer, const fgs_nas_message_
uint8_t decode_5gmm_msg_header(fgmm_msg_header_t *mm_header, const uint8_t *buffer, uint32_t len)
{
if (len < sizeof(fgmm_msg_header_t)) {
PRINT_NAS_ERROR("Failed to decode plain 5GMM header: buffer length too short\n");
PRINT_ERROR("Failed to decode plain 5GMM header: buffer length too short\n");
return -1;
}
mm_header->ex_protocol_discriminator = *buffer++;
@@ -155,7 +156,7 @@ uint8_t decode_5gmm_msg_header(fgmm_msg_header_t *mm_header, const uint8_t *buff
uint8_t decode_5gsm_msg_header(fgsm_msg_header_t *sm_header, const uint8_t *buffer, uint32_t len)
{
if (len < sizeof(fgsm_msg_header_t)) {
PRINT_NAS_ERROR("Failed to decode plain 5GSM header: buffer length too short\n");
PRINT_ERROR("Failed to decode plain 5GSM header: buffer length too short\n");
return -1;
}
sm_header->ex_protocol_discriminator = *buffer++;
@@ -172,7 +173,7 @@ int decode_5gs_security_protected_header(fgs_nas_message_security_header_t *head
{
int decoded = 0;
if (len < sizeof(fgs_nas_message_security_header_t)) {
PRINT_NAS_ERROR("Failed to decode security protected 5GS header: buffer length too short\n");
PRINT_ERROR("Failed to decode security protected 5GS header: buffer length too short\n");
return -1;
}
header->protocol_discriminator = *buf++;
+2 -27
View File
@@ -26,33 +26,8 @@
#include <arpa/inet.h>
#include <string.h> // For memcpy
#include <stdio.h>
#define PRINT_NAS_ERROR(...) fprintf(stderr, ##__VA_ARGS__)
#define _NAS_EQ_CHECK_GENERIC(condition, fmt, ...) \
do { \
if (!(condition)) { \
PRINT_NAS_ERROR("NAS Equality Check failure: %s:%d: Condition '%s' failed: " fmt " != " fmt "\n", \
__FILE__, \
__LINE__, \
#condition, \
##__VA_ARGS__); \
return false; \
} \
} while (0)
#define _NAS_EQ_CHECK_LONG(A, B) _NAS_EQ_CHECK_GENERIC(A == B, "%ld", A, B);
#define _NAS_EQ_CHECK_INT(A, B) _NAS_EQ_CHECK_GENERIC(A == B, "%d", A, B);
#define _NAS_EQ_CHECK_STR(A, B) _NAS_EQ_CHECK_GENERIC(strcmp(A, B) == 0, "'%s'", A, B);
/* Map task id to printable name. */
typedef struct {
int id;
char text[256];
} text_info_t;
#define TO_TEXT(LabEl, nUmID) {nUmID, #LabEl},
#define TO_ENUM(LabEl, nUmID ) LabEl = nUmID,
#include "utils.h" // text_info_t, TO_ENUM, TO_TEXT
#include "common/utils/eq_check.h"
#define GET_SHORT(input, size) ({ \
uint16_t tmp16; \
+4
View File
@@ -1 +1,5 @@
add_subdirectory(MESSAGES)
if(ENABLE_TESTS)
add_subdirectory(tests)
endif()

Some files were not shown because too many files have changed in this diff Show More