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:
+6
-22
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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/*
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -48,7 +48,6 @@ RUN apt-get update && \
|
||||
procps \
|
||||
libsctp1 \
|
||||
tzdata \
|
||||
libblas3 \
|
||||
libc6 \
|
||||
libconfig9 \
|
||||
gdb \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/*
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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/*
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -36,7 +36,6 @@ RUN apt-get update && \
|
||||
pkg-config \
|
||||
libsctp1 \
|
||||
tzdata \
|
||||
libblas3 \
|
||||
libconfig9 \
|
||||
openssl \
|
||||
net-tools \
|
||||
|
||||
@@ -52,8 +52,6 @@ RUN apt-get update && \
|
||||
libboost-system1.83.0 \
|
||||
libboost-program-options1.83.0 \
|
||||
tzdata \
|
||||
liblapacke \
|
||||
libblas3 \
|
||||
libconfig9 \
|
||||
openssl \
|
||||
net-tools \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
@@ -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])
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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) */
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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(>p_tnl->transportLayerAddress, out->tl_address);
|
||||
OCTET_STRING_TO_UINT32(>p_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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(>PV1U_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
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user