mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Compare commits
22 Commits
pre-commit
...
e2ap_integ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
878b3c3857 | ||
|
|
e2de6719ee | ||
|
|
e69feb9384 | ||
|
|
65abd4b55b | ||
|
|
0583c5411a | ||
|
|
2e0a39816e | ||
|
|
d060ae2008 | ||
|
|
95ba33d955 | ||
|
|
3e5e7abaab | ||
|
|
76216713db | ||
|
|
f10ca57b77 | ||
|
|
8e8c6a7da3 | ||
|
|
155761417d | ||
|
|
1324d151ea | ||
|
|
b385f1778c | ||
|
|
d4ff3e8fb7 | ||
|
|
28010c223c | ||
|
|
b3fd97bb99 | ||
|
|
89108aa716 | ||
|
|
781f85e35d | ||
|
|
e3a96bbeef | ||
|
|
d370df812a |
@@ -302,6 +302,19 @@ if (DEBUG_ASN1C)
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
endif()
|
||||
|
||||
|
||||
#########################
|
||||
##### E2 AGENT
|
||||
#########################
|
||||
#add_boolean_option() does not work -- why?
|
||||
set(E2_AGENT "OFF" CACHE STRING "O-RAN E2 Agent")
|
||||
set_property(CACHE E2_AGENT PROPERTY STRINGS "ON" "OFF")
|
||||
|
||||
if(E2_AGENT)
|
||||
include_directories(openair2/E2AP)
|
||||
endif()
|
||||
|
||||
|
||||
##################################################
|
||||
# ASN.1 grammar C code generation & dependencies #
|
||||
##################################################
|
||||
@@ -1553,6 +1566,10 @@ add_library(L2
|
||||
)
|
||||
target_link_libraries(L2 PRIVATE x2ap s1ap lte_rrc m2ap)
|
||||
target_link_libraries(L2 PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(L2 PUBLIC e2_agent)
|
||||
target_compile_definitions(L2 PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
add_library(MAC_NR ${MAC_NR_SRC})
|
||||
target_link_libraries(MAC_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
@@ -1583,6 +1600,10 @@ add_library(e1_pdcp_if
|
||||
target_link_libraries(e1_pdcp_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap)
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(L2_NR PUBLIC e2_agent)
|
||||
target_compile_definitions(L2_NR PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
add_library(L2_LTE_NR
|
||||
${L2_RRC_SRC}
|
||||
@@ -2163,6 +2184,9 @@ target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYP
|
||||
target_link_libraries(lte-softmodem PRIVATE ${T_LIB})
|
||||
target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
if(E2_AGENT)
|
||||
target_compile_definitions(lte-softmodem PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
add_executable(oairu
|
||||
${OPENAIR_DIR}/executables/lte-ru.c
|
||||
@@ -2274,7 +2298,10 @@ endif()
|
||||
|
||||
# force the generation of ASN.1 so that we don't need to wait during the build
|
||||
target_link_libraries(nr-softmodem PRIVATE
|
||||
asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp)
|
||||
asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp)
|
||||
if(E2_AGENT)
|
||||
target_compile_definitions(nr-softmodem PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
add_executable(nr-cuup
|
||||
executables/nr-cuup.c
|
||||
@@ -2668,6 +2695,9 @@ make_driver(ue_ip ${OPENAIR2_DIR}/NETWORK_DRIVER/UE_IP ${ue_ip_src})
|
||||
|
||||
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
|
||||
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(doc)
|
||||
add_subdirectory(openair1)
|
||||
|
||||
@@ -261,3 +261,9 @@ log_config :
|
||||
rrc_log_level ="info";
|
||||
};
|
||||
|
||||
e2_agent = {
|
||||
enable = 1;
|
||||
address = "127.0.0.1";
|
||||
port = 36421;
|
||||
sm_dir = "/path/where/the/SMs/are/located/"
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ Options:
|
||||
Pass the supplied option verbatim to cmake.
|
||||
-d | --build-dir
|
||||
Sets build directory (will be <oai-root>/cmake_targets/<build-dir>/build)
|
||||
--build-e2
|
||||
Enable the the E2 Agent
|
||||
-I | --install-external-packages
|
||||
Installs required packages such as LibXML, asn1.1 compiler, ...
|
||||
This option will require root password
|
||||
@@ -197,6 +199,10 @@ function main() {
|
||||
-d | --build-dir)
|
||||
BUILD_DIR=$2
|
||||
shift 2;;
|
||||
--build-e2)
|
||||
CMAKE_CMD="$CMAKE_CMD -DE2_AGENT=ON"
|
||||
shift
|
||||
;;
|
||||
-I | --install-external-packages)
|
||||
INSTALL_EXTERNAL=1
|
||||
echo_info "Will install external packages"
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
add_subdirectory(utils)
|
||||
|
||||
add_library(ngran_types OBJECT ngran_types.c)
|
||||
|
||||
22
common/ngran_types.c
Normal file
22
common/ngran_types.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "ngran_types.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
char* get_ngran_name(ngran_node_t ran_type)
|
||||
{
|
||||
assert(ran_type >= 0);
|
||||
switch (ran_type)
|
||||
{
|
||||
case ngran_eNB: return "ngran_eNB";
|
||||
case ngran_ng_eNB: return "ngran_ng_eNB";
|
||||
case ngran_gNB: return "ngran_gNB";
|
||||
case ngran_eNB_CU: return "ngran_eNB_CU";
|
||||
case ngran_ng_eNB_CU: return "ngran_ng_eNB_CU";
|
||||
case ngran_gNB_CU: return "ngran_gNB_CU";
|
||||
case ngran_eNB_DU: return "ngran_eNB_DU";
|
||||
case ngran_gNB_DU: return "ngran_gNB_DU";
|
||||
case ngran_eNB_MBMS_STA: return "ngran_eNB_MBMS_STA";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -57,4 +57,7 @@ typedef enum { CPtype = 0, UPtype } E1_t;
|
||||
|
||||
typedef enum { non_dynamic, dynamic } fiveQI_type_t;
|
||||
#define maxSRBs 4
|
||||
|
||||
char* get_ngran_name(ngran_node_t ran_type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
add_subdirectory(alg)
|
||||
add_subdirectory(ds)
|
||||
add_boolean_option(ENABLE_TELNETSRV OFF "Whether to build telnet support in modems" OFF)
|
||||
if(ENABLE_TELNETSRV)
|
||||
|
||||
6
common/utils/alg/CMakeLists.txt
Normal file
6
common/utils/alg/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
add_library(alg OBJECT
|
||||
defer.c
|
||||
find.c
|
||||
)
|
||||
target_include_directories(alg PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(alg PUBLIC ds)
|
||||
66
common/utils/alg/alg.h
Normal file
66
common/utils/alg/alg.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ALG_MIR_H
|
||||
#define ALG_MIR_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "find.h"
|
||||
#include "defer.h"
|
||||
|
||||
|
||||
/*
|
||||
* Check at compile time that something is of a particular type.
|
||||
* Always evaluates to 1 so you may use it easily in comparisons.
|
||||
*/
|
||||
#define typecheck(type, x) \
|
||||
({ \
|
||||
type __dummy; \
|
||||
typeof(x) __dummy2; \
|
||||
(void)(&__dummy == &__dummy2); \
|
||||
1; \
|
||||
})
|
||||
|
||||
|
||||
#define swap(x,y) do \ { uint8_t swap_temp[sizeof(x) == sizeof(y) ? (signed)sizeof(x) : -1]; \
|
||||
memcpy(swap_temp,&y,sizeof(x)); \
|
||||
memcpy(&y,&x, sizeof(x)); \
|
||||
memcpy(&x,swap_temp,sizeof(x)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/*
|
||||
* Find an element in a data structure if the predicate is true
|
||||
*/
|
||||
|
||||
|
||||
#define find_if(T,U,W,X,Y) _Generic ((T), seq_arr_t*: find_if_arr, \
|
||||
assoc_rb_tree_t*: find_if_rb_tree, \
|
||||
default: find_if_arr) (T,U,W,X,Y)
|
||||
|
||||
#endif
|
||||
39
common/utils/alg/defer.c
Normal file
39
common/utils/alg/defer.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "defer.h"
|
||||
|
||||
|
||||
#if defined __clang__ // requires -fblocks (lambdas)
|
||||
void cleanup_deferred (void (^*d) (void))
|
||||
{
|
||||
(*d)();
|
||||
}
|
||||
#elif defined __GNUC__ // nested-function-in-stmt-expressionstatic
|
||||
void cleanup_deferred (void (**d) (void))
|
||||
{
|
||||
(*d)();
|
||||
}
|
||||
#endif
|
||||
|
||||
67
common/utils/alg/defer.h
Normal file
67
common/utils/alg/defer.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef DEFER_H
|
||||
#define DEFER_H
|
||||
|
||||
/*
|
||||
* Defer mechanism taken from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2542.pdf
|
||||
* It may become part of the C2X standard in <stddefer.h>
|
||||
* Basically, what is included in the defer statement, will be executed when the end of the
|
||||
* scope where it was defined happened i.e., it uses the same mechanims as the C++ destructors
|
||||
*/
|
||||
|
||||
#define CONCAT_IMPL( x, y ) x##y
|
||||
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )
|
||||
#define FUNC_DEFER4 MACRO_CONCAT(DF_, __LINE__ )
|
||||
#define FUNC_DEFER3 MACRO_CONCAT(FUNC_DEFER4, _line_ )
|
||||
#define FUNC_DEFER2 MACRO_CONCAT(FUNC_DEFER3, __COUNTER__ )
|
||||
#define FUNC_DEFER MACRO_CONCAT(FUNC_DEFER2, _counter )
|
||||
#define FUNC_DEFER_IMPL MACRO_CONCAT(FUNC_DEFER3, __impl )
|
||||
|
||||
|
||||
|
||||
#if defined __clang__ // requires -fblocks (lambdas) and -lBlocksRuntime in the linker
|
||||
|
||||
void cleanup_deferred (void (^*d) (void));
|
||||
|
||||
#define defer(...) \
|
||||
__attribute__((__cleanup__ (cleanup_deferred))) \
|
||||
__attribute__((unused)) void (^FUNC_DEFER) (void) = ^__VA_ARGS__
|
||||
|
||||
|
||||
#elif defined __GNUC__ // nested-function-in-stmt-expression
|
||||
|
||||
void cleanup_deferred (void (**d) (void));
|
||||
|
||||
#define defer(...) \
|
||||
__attribute__((__cleanup__ (cleanup_deferred))) \
|
||||
void (*FUNC_DEFER) (void) = ({ \
|
||||
void FUNC_DEFER_IMPL (void) __VA_ARGS__ \
|
||||
FUNC_DEFER_IMPL; })
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
82
common/utils/alg/find.c
Normal file
82
common/utils/alg/find.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "find.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void* find_if_arr(seq_arr_t* arr, void* start_it, void* end_it, void* value, bool (*f)(const void*, const void*))
|
||||
{
|
||||
assert(arr != NULL);
|
||||
|
||||
while (start_it != end_it) {
|
||||
if (f(value, start_it))
|
||||
return start_it;
|
||||
start_it = seq_next(arr, start_it);
|
||||
}
|
||||
return start_it;
|
||||
}
|
||||
|
||||
void* find_if_rb_tree(assoc_rb_tree_t* tree, void* start_it, void* end_it, void const* value, bool (*f)(const void*, const void*))
|
||||
{
|
||||
assert(tree != NULL);
|
||||
|
||||
while (start_it != end_it) {
|
||||
if (f(value, assoc_key(tree, start_it)))
|
||||
return start_it;
|
||||
start_it = assoc_next(tree, start_it);
|
||||
}
|
||||
|
||||
return start_it;
|
||||
}
|
||||
|
||||
bml_iter_t find_if_bi_map_left(bi_map_t* map, bml_iter_t start_it, bml_iter_t end_it, void const* value, bool (*f)(const void*, const void*))
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(start_it.it != NULL);
|
||||
|
||||
while (start_it.it != end_it.it) {
|
||||
if (f(value, assoc_key(&map->left, start_it.it)))
|
||||
return start_it;
|
||||
start_it = bi_map_next_left(map, start_it);
|
||||
}
|
||||
|
||||
return start_it;
|
||||
}
|
||||
|
||||
bmr_iter_t find_if_bi_map_right(bi_map_t* map, bmr_iter_t start_it, bmr_iter_t end_it, void const* value, bool (*f)(const void*, const void*))
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(start_it.it != NULL);
|
||||
|
||||
while (start_it.it != end_it.it) {
|
||||
if (f(value, start_it.it) == true)
|
||||
return start_it;
|
||||
|
||||
start_it = bi_map_next_right(map, start_it);
|
||||
}
|
||||
|
||||
return start_it;
|
||||
}
|
||||
57
common/utils/alg/find.h
Normal file
57
common/utils/alg/find.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FIND_ALGORITHM
|
||||
#define FIND_ALGORITHM
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "seq_container/seq_generic.h"
|
||||
#include "assoc_container/assoc_generic.h"
|
||||
#include "assoc_container/bimap.h"
|
||||
|
||||
|
||||
/*
|
||||
* It returns the first position in the data structure where the predicate i.e., param f, returns true
|
||||
* @param ds: data structure
|
||||
* @param start_it: valid iterator position within the seq_arr_t.
|
||||
* @param end_it: end iterator position. range [start_it, end). end needs to be reacheable from start_it.
|
||||
* @param value: the value to compare with.
|
||||
* @param f: the predicate. Returns true if the value and the object pointed to by the iterator match. value is
|
||||
* the first argument and the iterator the second
|
||||
* */
|
||||
|
||||
// Sequencial containers
|
||||
|
||||
void* find_if_arr(seq_arr_t* ds, void* start_it, void* end_it, void* value, bool (*f)(const void*, const void*));
|
||||
|
||||
// Associative containers
|
||||
|
||||
void* find_if_rb_tree(assoc_rb_tree_t* ds, void* start_it, void* end_it, void const* value, bool (*f)(const void*, const void*));
|
||||
|
||||
bml_iter_t find_if_bi_map_left(bi_map_t* ds, bml_iter_t start_it, bml_iter_t end_it, void const* value, bool (*f)(const void*, const void*));
|
||||
|
||||
bmr_iter_t find_if_bi_map_right(bi_map_t* ds, bmr_iter_t start_it, bmr_iter_t end_it, void const* value, bool (*f)(const void*, const void*));
|
||||
|
||||
#endif
|
||||
36
common/utils/alg/lock_guard/CMakeLists.txt
Normal file
36
common/utils/alg/lock_guard/CMakeLists.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(lock_guard)
|
||||
|
||||
set(default_build_type "Debug")
|
||||
|
||||
set(SANITIZER "ADDRESS" CACHE STRING "Sanitizers")
|
||||
set_property(CACHE SANITIZER PROPERTY STRINGS "NONE" "ADDRESS" "THREAD")
|
||||
message(STATUS "Selected SANITIZER TYPE: ${SANITIZER}")
|
||||
|
||||
if(SANITIZER STREQUAL "ADDRESS")
|
||||
add_compile_options("-fno-omit-frame-pointer;-fsanitize=address;-Wall;-Werror;-g")
|
||||
add_link_options("-fsanitize=address")
|
||||
|
||||
elseif(SANITIZER STREQUAL "THREAD" )
|
||||
|
||||
add_compile_options("-fsanitize=thread;-g;")
|
||||
add_link_options("-fsanitize=thread;")
|
||||
|
||||
endif()
|
||||
|
||||
option(CODE_COVERAGE "Code coverage" ON)
|
||||
if(CODE_COVERAGE)
|
||||
add_compile_options("-fprofile-arcs;-ftest-coverage")
|
||||
add_link_options("-lgcov;-coverage;")
|
||||
message("Code Coverage cmd: cd CMakeFiles/tc.dir && lcov --capture --directory . --output-file coverage.info && genhtml coverage.info --output-directory out && cd out && firefox index.html")
|
||||
endif()
|
||||
|
||||
option(CODE_PROFILER "Code Profiler" ON)
|
||||
if(CODE_PROFILER)
|
||||
add_compile_options("-pg")
|
||||
add_link_options("-pg")
|
||||
message("Code Profiler cmd: gprof tc gmon.out > analysis.txt && vim analysis.txt ")
|
||||
endif()
|
||||
|
||||
add_executable(test_lock_guard test.c)
|
||||
target_link_libraries(test_lock_guard PRIVATE pthread alg)
|
||||
68
common/utils/alg/lock_guard/lock_guard.h
Normal file
68
common/utils/alg/lock_guard/lock_guard.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MIR_LOCK_GUARD_H
|
||||
#define MIR_LOCK_GUARD_H
|
||||
|
||||
#include "defer.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
/*
|
||||
* Lock guard mechanism in C, similar to std::lock_guard. The lock unlocks at the end of the scope.
|
||||
* Very helpfull to avoid forgetting unlock from functions with multiple return statements.
|
||||
* Similar to the mechanism found at QEMU_LOCK_GUARD
|
||||
* @param X pthread_mutex_t* or pthread_mutex_t const*
|
||||
*/
|
||||
|
||||
void mir_dummy_lock_guard();
|
||||
void mir_dummy_lock_guard_const();
|
||||
|
||||
#define CHECK_TYPE_INLINE(val, type) (void)_Generic((val), type: mir_dummy_lock_guard, const type: mir_dummy_lock_guard_const)
|
||||
|
||||
#define lock_guard(X) \
|
||||
do{ CHECK_TYPE_INLINE(X, pthread_mutex_t*);\
|
||||
int rc = pthread_mutex_lock(X); \
|
||||
if (rc != 0){ \
|
||||
fprintf(stdout, "Error while locking, possibly the lock is already locked: %s\n", strerror(rc)); \
|
||||
fflush(stdout); \
|
||||
assert(0!=0); \
|
||||
exit(-1); \
|
||||
} \
|
||||
} while(0); \
|
||||
defer( { int rc = pthread_mutex_unlock(X); \
|
||||
if(rc != 0){ \
|
||||
fprintf(stdout, "Error while unlocking: %s\n", strerror(rc) ); \
|
||||
fflush(stdout); \
|
||||
assert(0!=0); \
|
||||
exit(-1); \
|
||||
} \
|
||||
}); \
|
||||
|
||||
#endif
|
||||
|
||||
72
common/utils/alg/lock_guard/test.c
Normal file
72
common/utils/alg/lock_guard/test.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "lock_guard.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static
|
||||
int dummy_func(pthread_mutex_t* m)
|
||||
{
|
||||
lock_guard(m);
|
||||
for(int i =0; i < 10; ++i){
|
||||
printf("Value of the function = %d \n",i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
pthread_mutex_t mtx; // = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
int rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
|
||||
assert(rc == 0);
|
||||
|
||||
rc = pthread_mutex_init(&mtx, &attr);
|
||||
assert(rc == 0);
|
||||
|
||||
|
||||
dummy_func(&mtx);
|
||||
|
||||
{
|
||||
lock_guard(&mtx);
|
||||
}
|
||||
|
||||
lock_guard(&mtx);
|
||||
|
||||
// rc = pthread_mutex_unlock(&mtx);
|
||||
// if(rc != 0){
|
||||
// fprintf(stdout, "Error while locking: %s\n", strerror(rc) );
|
||||
// exit(-1);
|
||||
// }
|
||||
|
||||
|
||||
for(int i =0; i < 10; ++i){
|
||||
printf("Value of i = %d \n",i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
add_library(ds OBJECT
|
||||
byte_array.c
|
||||
assoc_container/assoc_rb_tree.c
|
||||
assoc_container/bimap.c
|
||||
seq_container/seq_arr.c
|
||||
)
|
||||
|
||||
target_include_directories(ds PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
66
common/utils/ds/assoc_container/assoc_generic.h
Normal file
66
common/utils/ds/assoc_container/assoc_generic.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ASSOCCIATIVE_CONTAINERS_GENERIC
|
||||
#define ASSOCCIATIVE_CONTAINERS_GENERIC
|
||||
|
||||
#include "assoc_rb_tree.h"
|
||||
|
||||
// Initialization
|
||||
#define assoc_init(T, KS, C, F) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_init, \
|
||||
default: assoc_rb_tree_init) (T, KS, C, F)
|
||||
|
||||
#define assoc_free(T) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_free, \
|
||||
default: assoc_rb_tree_free)(T)
|
||||
|
||||
// Modifiers
|
||||
#define assoc_insert(T, K, KS, V) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_insert, \
|
||||
default: assoc_rb_tree_insert)(T,K,KS,V)
|
||||
|
||||
|
||||
#define assoc_extract(T, K) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_extract, \
|
||||
default: assoc_rb_tree_extract)(T,K)
|
||||
|
||||
#define assoc_key(T,U) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_key, \
|
||||
default: assoc_rb_tree_key)(T,U)
|
||||
|
||||
#define assoc_value(T,U) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_value, \
|
||||
default: assoc_rb_tree_value)(T,U)
|
||||
|
||||
|
||||
// Capacity
|
||||
#define assoc_size(T) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_size, \
|
||||
default: assoc_rb_tree_size)(T)
|
||||
|
||||
// Forward Iterator Concept
|
||||
#define assoc_front(T) _Generic ((T), assoc_rb_tree_t*: assoc_rb_tree_front, \
|
||||
default: assoc_rb_tree_front)(T)
|
||||
|
||||
#define assoc_next(T,U) _Generic((T), assoc_rb_tree_t*: assoc_rb_tree_next, \
|
||||
default: assoc_rb_tree_next)(T,U)
|
||||
|
||||
#define assoc_end(T) _Generic((T), assoc_rb_tree_t*: assoc_rb_tree_end, \
|
||||
default: assoc_rb_tree_end)(T)
|
||||
|
||||
#endif
|
||||
499
common/utils/ds/assoc_container/assoc_rb_tree.c
Normal file
499
common/utils/ds/assoc_container/assoc_rb_tree.c
Normal file
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
RB tree implemented a la CLRS by mir
|
||||
|
||||
Red-Black trees have 5 properties:
|
||||
1- Every node is Red or Black
|
||||
2- The root is black
|
||||
3- Every leaf is black
|
||||
4- If a node is red, then both its children are black
|
||||
5- For each node, all simple paths from the node to descendant leaves contain the same number of black nodes
|
||||
|
||||
Lemma 1: a red-black tree with n internal nodes has a height at most 2lg(n+1)
|
||||
*/
|
||||
|
||||
#include "assoc_rb_tree.h"
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum {
|
||||
ASSOC_BLACK,
|
||||
ASSOC_RED,
|
||||
} assoc_color_e;
|
||||
|
||||
typedef struct assoc_node_s {
|
||||
void* key;
|
||||
void* value;
|
||||
struct assoc_node_s* parent;
|
||||
struct assoc_node_s* left;
|
||||
struct assoc_node_s* right;
|
||||
assoc_color_e color;
|
||||
} assoc_node_t;
|
||||
|
||||
static assoc_node_t* init_node(void* key, void* value)
|
||||
{
|
||||
assoc_node_t* n = malloc(sizeof(assoc_node_t));
|
||||
assert(n != NULL && "Memory exhausted");
|
||||
n->key = key;
|
||||
n->value = value;
|
||||
n->parent = NULL;
|
||||
n->left = NULL;
|
||||
n->right = NULL;
|
||||
n->color = ASSOC_RED;
|
||||
return n;
|
||||
}
|
||||
|
||||
static assoc_node_t* create_node_rb_tree(assoc_rb_tree_t* tree, void* key, void* value)
|
||||
{
|
||||
assoc_node_t* x = init_node(key, value);
|
||||
x->parent = tree->dummy;
|
||||
x->left = tree->dummy;
|
||||
x->right = tree->dummy;
|
||||
return x;
|
||||
}
|
||||
|
||||
static void free_node_rb_tree(assoc_node_t* n)
|
||||
{
|
||||
assert(n != NULL);
|
||||
free(n->key);
|
||||
// free(n->value);
|
||||
free(n);
|
||||
}
|
||||
|
||||
static void depth_first_search_free(assoc_rb_tree_t* tree, assoc_node_t* node, void (*f)(void* key, void* value))
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(node != NULL);
|
||||
if (node != tree->dummy) {
|
||||
depth_first_search_free(tree, node->left, f);
|
||||
depth_first_search_free(tree, node->right, f);
|
||||
if (f != NULL)
|
||||
f(node->key, node->value);
|
||||
free_node_rb_tree(node);
|
||||
}
|
||||
}
|
||||
|
||||
void assoc_rb_tree_init(assoc_rb_tree_t* tree, size_t key_sz, int (*comp_func)(const void*, const void*), free_func_t free_func)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(key_sz > 0);
|
||||
|
||||
tree->dummy = init_node(NULL, NULL);
|
||||
tree->dummy->color = ASSOC_BLACK;
|
||||
tree->root = tree->dummy;
|
||||
tree->comp = comp_func;
|
||||
tree->size = 0;
|
||||
tree->key_sz = key_sz;
|
||||
tree->free_func = free_func;
|
||||
}
|
||||
|
||||
void assoc_rb_tree_free(assoc_rb_tree_t* tree)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
depth_first_search_free(tree, tree->root, tree->free_func);
|
||||
free(tree->dummy);
|
||||
}
|
||||
|
||||
static void left_rotate(assoc_rb_tree_t* tree, assoc_node_t* x_node)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(x_node != NULL);
|
||||
assert(x_node->right != tree->dummy);
|
||||
|
||||
assoc_node_t* y_node = x_node->right;
|
||||
x_node->right = y_node->left;
|
||||
if (y_node->left != tree->dummy)
|
||||
y_node->left->parent = x_node;
|
||||
|
||||
y_node->parent = x_node->parent;
|
||||
if (x_node->parent == tree->dummy)
|
||||
tree->root = y_node;
|
||||
else if (x_node == x_node->parent->left)
|
||||
x_node->parent->left = y_node;
|
||||
else
|
||||
x_node->parent->right = y_node;
|
||||
|
||||
y_node->left = x_node;
|
||||
x_node->parent = y_node;
|
||||
}
|
||||
|
||||
static void right_rotate(assoc_rb_tree_t* tree, assoc_node_t* x_node)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(x_node != NULL);
|
||||
assert(x_node->left != tree->dummy);
|
||||
|
||||
assoc_node_t* y_node = x_node->left;
|
||||
x_node->left = y_node->right;
|
||||
if (y_node->right != tree->dummy)
|
||||
y_node->right->parent = x_node;
|
||||
|
||||
y_node->parent = x_node->parent;
|
||||
|
||||
if (x_node->parent == tree->dummy)
|
||||
tree->root = y_node;
|
||||
else if (x_node->parent->left == x_node)
|
||||
x_node->parent->left = y_node;
|
||||
else
|
||||
x_node->parent->right = y_node;
|
||||
|
||||
y_node->right = x_node;
|
||||
x_node->parent = y_node;
|
||||
}
|
||||
|
||||
static void insert_fixup(assoc_rb_tree_t* tree, assoc_node_t* z_node)
|
||||
{
|
||||
while (z_node->parent->color == ASSOC_RED) {
|
||||
// z_node->parent.color == RED) which means:
|
||||
// 1- violating only property 4 of the red-black tree
|
||||
// 2- z_node->parent was not the root by property 2, root must be black
|
||||
// 3- z_node->parent->parent must exist and is Black, since Red-Red is illegal
|
||||
|
||||
assoc_node_t* parent = z_node->parent;
|
||||
assoc_node_t* grand_parent = z_node->parent->parent;
|
||||
if (parent == grand_parent->left) {
|
||||
assoc_node_t* uncle = grand_parent->right;
|
||||
// Case 1: uncle is Red, flip colors and continue up the tree
|
||||
if (uncle->color == ASSOC_RED) {
|
||||
parent->color = ASSOC_BLACK;
|
||||
uncle->color = ASSOC_BLACK;
|
||||
grand_parent->color = ASSOC_RED;
|
||||
z_node = grand_parent;
|
||||
} else { // uncle is BLACK
|
||||
// Case 2: z_node at right
|
||||
if (z_node == parent->right) {
|
||||
z_node = parent;
|
||||
left_rotate(tree, z_node);
|
||||
parent = z_node->parent; // the grand_parent is the same, so do not refresh
|
||||
}
|
||||
// Case 3: z_node at left
|
||||
parent->color = ASSOC_BLACK;
|
||||
grand_parent->color = ASSOC_RED;
|
||||
right_rotate(tree, grand_parent);
|
||||
}
|
||||
} else {
|
||||
assoc_node_t* uncle = grand_parent->left;
|
||||
if (uncle->color == ASSOC_RED) {
|
||||
parent->color = ASSOC_BLACK;
|
||||
uncle->color = ASSOC_BLACK;
|
||||
grand_parent->color = ASSOC_RED;
|
||||
z_node = grand_parent;
|
||||
} else { // uncle->color == BLACK
|
||||
if (z_node == parent->left) {
|
||||
z_node = parent;
|
||||
right_rotate(tree, z_node);
|
||||
parent = z_node->parent; // the grand_parent is the same, so do not refresh
|
||||
}
|
||||
parent->color = ASSOC_BLACK;
|
||||
grand_parent->color = ASSOC_RED;
|
||||
left_rotate(tree, grand_parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Assure that property 2 of the red-black tree is maintained
|
||||
tree->root->color = ASSOC_BLACK;
|
||||
}
|
||||
|
||||
void assoc_rb_tree_insert(assoc_rb_tree_t* tree, void const* key, size_t key_sz, void* value)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(tree->key_sz == key_sz && "Size mismatch");
|
||||
|
||||
void* key_dst = malloc(key_sz);
|
||||
assert(key_dst != NULL && "Memory exhausted");
|
||||
memcpy(key_dst, key, key_sz);
|
||||
|
||||
assoc_node_t* z_node = create_node_rb_tree(tree, key_dst, value);
|
||||
|
||||
assert(z_node != tree->dummy);
|
||||
|
||||
assert(z_node->parent == tree->dummy);
|
||||
assert(z_node->left == tree->dummy);
|
||||
assert(z_node->right == tree->dummy);
|
||||
assert(z_node->color == ASSOC_RED);
|
||||
|
||||
assoc_node_t* x_node = tree->root;
|
||||
assoc_node_t* y_node = tree->dummy;
|
||||
|
||||
// Find leaf to insert
|
||||
while (x_node != tree->dummy) {
|
||||
y_node = x_node;
|
||||
if (tree->comp(z_node->key, x_node->key) == 1)
|
||||
x_node = x_node->left;
|
||||
else
|
||||
x_node = x_node->right;
|
||||
}
|
||||
|
||||
z_node->parent = y_node;
|
||||
|
||||
if (y_node == tree->dummy)
|
||||
tree->root = z_node;
|
||||
else if (tree->comp(z_node->key, y_node->key) == 1)
|
||||
y_node->left = z_node;
|
||||
else
|
||||
y_node->right = z_node;
|
||||
insert_fixup(tree, z_node);
|
||||
|
||||
tree->size++;
|
||||
}
|
||||
|
||||
static void delete_fixup(assoc_rb_tree_t* tree, assoc_node_t* x_node)
|
||||
{
|
||||
while (x_node != tree->root && x_node->color == ASSOC_BLACK) {
|
||||
if (x_node == x_node->parent->left) {
|
||||
assoc_node_t* w_node = x_node->parent->right;
|
||||
// Case 1: x's sibling is RED
|
||||
if (w_node->color == ASSOC_RED) {
|
||||
w_node->color = ASSOC_BLACK;
|
||||
x_node->parent->color = ASSOC_RED;
|
||||
left_rotate(tree, x_node->parent);
|
||||
w_node = x_node->parent->right;
|
||||
}
|
||||
assert(w_node->color == ASSOC_BLACK);
|
||||
// Case 2: x's siblings nodes are both black and w itself is black
|
||||
if (w_node->left->color == ASSOC_BLACK && w_node->right->color == ASSOC_BLACK) {
|
||||
w_node->color = ASSOC_RED;
|
||||
// if we come from Case 1, this will terminate, as x_node->parent == RED
|
||||
// else, spread the problem to upper levels in the tree
|
||||
// (maybe left and right branch decompensated after removing
|
||||
// black node in the left branch).
|
||||
x_node = x_node->parent;
|
||||
} else {
|
||||
// Case 3: x's sibling w is black w->left->color == RED && w->right->color == BLACK
|
||||
if (w_node->right->color == ASSOC_BLACK) {
|
||||
assert(w_node->color == ASSOC_BLACK);
|
||||
assert(w_node->left->color == ASSOC_RED);
|
||||
w_node->left->color = ASSOC_BLACK;
|
||||
w_node->color = ASSOC_RED;
|
||||
right_rotate(tree, w_node);
|
||||
w_node = x_node->parent->right;
|
||||
}
|
||||
// Case 4: x's sibling is black and w's right child is red
|
||||
assert(w_node->color == ASSOC_BLACK);
|
||||
assert(w_node->right->color == ASSOC_RED);
|
||||
w_node->color = x_node->parent->color;
|
||||
x_node->parent->color = ASSOC_BLACK;
|
||||
// since w_node->right->color == RED we insert a new black
|
||||
// in the w_node path, changing the color
|
||||
w_node->right->color = ASSOC_BLACK;
|
||||
// the rotation adds one black in the x_node path and deletes
|
||||
// one in the w_node path. As a result after the function, the x_node path
|
||||
// gets one extra black in the w_node, and ends with the number of blacks
|
||||
// +1, -1
|
||||
left_rotate(tree, x_node->parent);
|
||||
x_node = tree->root;
|
||||
}
|
||||
} else {
|
||||
assoc_node_t* w_node = x_node->parent->left;
|
||||
// Case 1: x' sibling is red
|
||||
if (w_node->color == ASSOC_RED) {
|
||||
w_node->color = ASSOC_BLACK;
|
||||
x_node->parent->color = ASSOC_RED;
|
||||
right_rotate(tree, x_node->parent);
|
||||
w_node = x_node->parent->left;
|
||||
}
|
||||
assert(w_node->color == ASSOC_BLACK);
|
||||
// Case 2: x' siblings nodes are both black and w itself is black
|
||||
if (w_node->left->color == ASSOC_BLACK && w_node->right->color == ASSOC_BLACK) {
|
||||
w_node->color = ASSOC_RED;
|
||||
x_node = x_node->parent;
|
||||
} else {
|
||||
// Case 3: x's sibling w is black w->left == RED && w->right == BLACK
|
||||
if (w_node->left->color == ASSOC_BLACK) {
|
||||
assert(w_node->color == ASSOC_BLACK);
|
||||
assert(w_node->right->color == ASSOC_RED);
|
||||
w_node->right->color = ASSOC_BLACK;
|
||||
w_node->color = ASSOC_RED;
|
||||
left_rotate(tree, w_node);
|
||||
w_node = x_node->parent->left;
|
||||
}
|
||||
// Case 4: x's sibling is black and w's left child is red
|
||||
assert(w_node->color == ASSOC_BLACK);
|
||||
assert(w_node->left->color == ASSOC_RED);
|
||||
w_node->color = x_node->parent->color;
|
||||
x_node->parent->color = ASSOC_BLACK;
|
||||
w_node->left->color = ASSOC_BLACK;
|
||||
right_rotate(tree, x_node->parent);
|
||||
x_node = tree->root;
|
||||
}
|
||||
}
|
||||
}
|
||||
x_node->color = ASSOC_BLACK;
|
||||
}
|
||||
|
||||
static void transplant(assoc_rb_tree_t* tree, assoc_node_t* u_node, assoc_node_t* v_node)
|
||||
{
|
||||
assert(u_node != tree->dummy);
|
||||
|
||||
if (u_node->parent == tree->dummy)
|
||||
tree->root = v_node;
|
||||
else if (u_node == u_node->parent->left)
|
||||
u_node->parent->left = v_node;
|
||||
else
|
||||
u_node->parent->right = v_node;
|
||||
|
||||
v_node->parent = u_node->parent;
|
||||
}
|
||||
|
||||
static assoc_node_t* minimum(assoc_rb_tree_t const* tree, assoc_node_t* x_node)
|
||||
{
|
||||
if (x_node == tree->dummy)
|
||||
return tree->dummy;
|
||||
|
||||
while (x_node->left != tree->dummy)
|
||||
x_node = x_node->left;
|
||||
return x_node;
|
||||
}
|
||||
|
||||
static assoc_node_t* find_rb_tree(assoc_rb_tree_t* tree, assoc_node_t* node, void* key)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(node != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
while (node != tree->dummy) {
|
||||
int rc = tree->comp(key, node->key);
|
||||
if (rc == 1)
|
||||
node = node->left;
|
||||
else if (rc == -1)
|
||||
node = node->right;
|
||||
else {
|
||||
assert(rc == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
void* assoc_rb_tree_extract(assoc_rb_tree_t* tree, void* key)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
assoc_node_t* z_node = find_rb_tree(tree, tree->root, key);
|
||||
assert(z_node != tree->dummy && "Trying to extract a key not found in the tree");
|
||||
|
||||
assoc_color_e original_color = z_node->color;
|
||||
assoc_node_t* x_node = z_node;
|
||||
assoc_node_t* y_node = z_node;
|
||||
if (z_node->left == tree->dummy) {
|
||||
x_node = z_node->right;
|
||||
transplant(tree, z_node, z_node->right);
|
||||
// note that nobody points to z_node, even though z_node still points to parent and right
|
||||
} else if (z_node->right == tree->dummy) {
|
||||
x_node = z_node->left;
|
||||
transplant(tree, z_node, z_node->left);
|
||||
} else {
|
||||
y_node = minimum(tree, z_node->right);
|
||||
original_color = y_node->color;
|
||||
x_node = y_node->right;
|
||||
|
||||
if (y_node->parent == z_node) {
|
||||
x_node->parent = y_node; // necessary when x_node is the dummy node
|
||||
} else {
|
||||
transplant(tree, y_node, y_node->right);
|
||||
y_node->right = z_node->right;
|
||||
y_node->right->parent = y_node;
|
||||
}
|
||||
transplant(tree, z_node, y_node);
|
||||
y_node->left = z_node->left;
|
||||
y_node->left->parent = y_node;
|
||||
y_node->color = z_node->color;
|
||||
}
|
||||
void* value = z_node->value;
|
||||
// free(z_node->key);
|
||||
// free(z_node);
|
||||
|
||||
free_node_rb_tree(z_node);
|
||||
if (original_color == ASSOC_BLACK)
|
||||
delete_fixup(tree, x_node);
|
||||
|
||||
assert(tree->size != 0);
|
||||
tree->size--;
|
||||
return value;
|
||||
}
|
||||
|
||||
void* assoc_rb_tree_front(assoc_rb_tree_t const* tree)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
// Returns, tree's most left child node
|
||||
assoc_node_t* node = minimum(tree, tree->root);
|
||||
return node;
|
||||
}
|
||||
|
||||
void* assoc_rb_tree_next(assoc_rb_tree_t const* tree, void* it)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(it != NULL);
|
||||
assoc_node_t* node = (assoc_node_t*)it;
|
||||
|
||||
assert(node != tree->dummy && "No next node since the end reached");
|
||||
|
||||
// a) If you have right child node find it
|
||||
if (node->right != tree->dummy) {
|
||||
node = minimum(tree, node->right);
|
||||
return node;
|
||||
}
|
||||
|
||||
// b) If you come from the parent's left stop. Otherwise go up untill
|
||||
// c) you come from parent's left or
|
||||
// d) you found the end of the tree
|
||||
assoc_node_t* p = node->parent;
|
||||
while (p != tree->dummy && p->left != node) {
|
||||
node = p;
|
||||
p = node->parent;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void* assoc_rb_tree_end(assoc_rb_tree_t const* tree)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
return tree->dummy;
|
||||
}
|
||||
|
||||
void* assoc_rb_tree_key(assoc_rb_tree_t* tree, void* it)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(it != tree->dummy && "end iterator passed?");
|
||||
return ((assoc_node_t*)it)->key;
|
||||
}
|
||||
|
||||
// Get the value pointer form an iterator
|
||||
void* assoc_rb_tree_value(assoc_rb_tree_t* tree, void* it)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
assert(it != tree->dummy && "end iterator passed?");
|
||||
return ((assoc_node_t*)it)->value;
|
||||
}
|
||||
|
||||
size_t assoc_rb_tree_size(assoc_rb_tree_t* tree)
|
||||
{
|
||||
assert(tree != NULL);
|
||||
return tree->size;
|
||||
}
|
||||
155
common/utils/ds/assoc_container/assoc_rb_tree.h
Normal file
155
common/utils/ds/assoc_container/assoc_rb_tree.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ASSOCIATIVE_RB_TREE_NAIVE
|
||||
#define ASSOCIATIVE_RB_TREE_NAIVE
|
||||
|
||||
/*
|
||||
RB tree implemented a la CLRS
|
||||
|
||||
Red-Black trees have 5 properties:
|
||||
1- Every node is Red or Black
|
||||
2- The root is black
|
||||
3- Every leaf is black
|
||||
4- If a node is red, then both its children are black
|
||||
5- For each node, all simple paths from the node to descendant leaves contain the same number of black nodes
|
||||
|
||||
Lemma 1: a red-black tree with n internal nodes has a height at most 2lg(n+1)
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct assoc_node_s assoc_node_t;
|
||||
|
||||
typedef void (*free_func_t)(void* key, void* value);
|
||||
|
||||
typedef struct {
|
||||
assoc_node_t* dummy; // node
|
||||
assoc_node_t* root; // node
|
||||
int (*comp)(const void*, const void*);
|
||||
size_t size;
|
||||
// size key
|
||||
size_t key_sz;
|
||||
free_func_t free_func;
|
||||
// size value
|
||||
// size_t val_sz; // Value is always a pointer to the type
|
||||
|
||||
} assoc_rb_tree_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Init the rb ds
|
||||
* @param tree: the ds to initialize
|
||||
* @param key_sz: Size of the key i.e., sizeof(T), that the rb_tree will store.
|
||||
* @param comp: Compare function in the RB tree.
|
||||
* @param t: Free function to free the value if needed
|
||||
*/
|
||||
void assoc_rb_tree_init(assoc_rb_tree_t* tree, size_t key_sz, int (*comp)(const void*, const void*), free_func_t f);
|
||||
|
||||
/*
|
||||
* Free the rb ds
|
||||
* @param tree: the ds
|
||||
*/
|
||||
void assoc_rb_tree_free(assoc_rb_tree_t* tree);
|
||||
|
||||
// Modifiers
|
||||
// The tree is responsible for freeing the void* key and value memory later
|
||||
|
||||
/*
|
||||
* Insert key-value
|
||||
* @param tree: the ds
|
||||
* @param key a pointer to the key
|
||||
* @param key_sz sizeof(key)
|
||||
* @param value Pointer to the value. Ownership is transfere i.e., the RB tree will
|
||||
* free it. It needs to be allocated in the heap
|
||||
*/
|
||||
void assoc_rb_tree_insert(assoc_rb_tree_t* tree, void const* key, size_t key_sz, void* value);
|
||||
|
||||
/*
|
||||
* Extract value It returns the void* of value. the void* of the key is freed
|
||||
* @param tree: the ds
|
||||
* @param key a pointer to the key
|
||||
* @return value
|
||||
* @pre @p key must exist in the ds
|
||||
*/
|
||||
void* assoc_rb_tree_extract(assoc_rb_tree_t* tree, void* key);
|
||||
|
||||
|
||||
/*
|
||||
* Get the key from an iterator
|
||||
* @param tree: the ds
|
||||
* @param it a pointer to the key
|
||||
* @return key from the ds. It does not free it.
|
||||
* @pre @p it must exist in the ds
|
||||
*/
|
||||
void* assoc_rb_tree_key(assoc_rb_tree_t* tree, void* it);
|
||||
|
||||
|
||||
/*
|
||||
* Get the value pointer form an iterator
|
||||
* @param tree: the ds
|
||||
* @param it a pointer to the key
|
||||
* @return key from the ds. It does not free it.
|
||||
* @pre @p it must exist in the ds
|
||||
*/
|
||||
void* assoc_rb_tree_value(assoc_rb_tree_t* tree, void* it);
|
||||
|
||||
/*
|
||||
* Size of the current ds
|
||||
* @param tree: the ds
|
||||
* @return number of elements in the ds
|
||||
*/
|
||||
size_t assoc_rb_tree_size(assoc_rb_tree_t* tree);
|
||||
|
||||
// Forward Iterator Concept
|
||||
|
||||
/*
|
||||
* Get the iterator to the first element
|
||||
* @param tree: the ds
|
||||
* @return iterator to the first element
|
||||
*/
|
||||
void* assoc_rb_tree_front(assoc_rb_tree_t const* tree);
|
||||
|
||||
|
||||
/*
|
||||
* Get the next iterator
|
||||
* @param tree: the ds
|
||||
* @param it iterator
|
||||
* @return iterator to the next element
|
||||
* @pre iterator must be in the ds
|
||||
*/
|
||||
void* assoc_rb_tree_next(assoc_rb_tree_t const* tree, void* it);
|
||||
|
||||
|
||||
/*
|
||||
* Get the last iterator
|
||||
* @param tree: the ds
|
||||
* @return iterator to one past the last element in the ds
|
||||
*/
|
||||
void* assoc_rb_tree_end(assoc_rb_tree_t const* tree);
|
||||
|
||||
#endif
|
||||
|
||||
188
common/utils/ds/assoc_container/bimap.c
Normal file
188
common/utils/ds/assoc_container/bimap.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "bimap.h"
|
||||
#include "assoc_generic.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void bi_map_init(bi_map_t* map, size_t key_sz1, size_t key_sz2, bi_map_cmp cmp1, bi_map_cmp cmp2, free_func_t free1, free_func_t free2)
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(key_sz1 > 0);
|
||||
assert(key_sz2 > 0);
|
||||
assert(cmp1 != NULL);
|
||||
assert(cmp2 != NULL);
|
||||
|
||||
assoc_init(&map->left, key_sz1, cmp1, free1);
|
||||
assoc_init(&map->right, key_sz2, cmp2, free2);
|
||||
}
|
||||
|
||||
void bi_map_free(bi_map_t* map)
|
||||
{
|
||||
assert(map != NULL);
|
||||
|
||||
assoc_free(&map->left);
|
||||
assoc_free(&map->right);
|
||||
}
|
||||
|
||||
// Modifiers
|
||||
|
||||
void bi_map_insert(bi_map_t* map, void const* key1, size_t key_sz1, void const* key2, size_t key_sz2)
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(key1 != NULL);
|
||||
assert(key_sz1 > 0);
|
||||
assert(key2 != NULL);
|
||||
assert(key_sz2 > 0);
|
||||
|
||||
void* val1 = malloc(key_sz2);
|
||||
assert(val1 != NULL && "Memory exhausted");
|
||||
memcpy(val1, key2, key_sz2);
|
||||
|
||||
assoc_insert(&map->left, key1, key_sz1, val1);
|
||||
|
||||
void* val2 = malloc(key_sz1);
|
||||
assert(val2 != NULL && "Memory exhausted");
|
||||
memcpy(val2, key1, key_sz1);
|
||||
|
||||
assoc_insert(&map->right, key2, key_sz2, val2);
|
||||
}
|
||||
|
||||
// It returns the void* of key2. the void* of the key1 is freed
|
||||
void* bi_map_extract_left(bi_map_t* map, void* key1, size_t key1_sz)
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(key1 != NULL);
|
||||
assert(key1_sz == map->left.key_sz);
|
||||
|
||||
void* key2 = assoc_extract(&map->left, key1);
|
||||
void* key3 = assoc_extract(&map->right, key2);
|
||||
|
||||
// I do not like this trick. The memory should also be the same
|
||||
int cmp = map->left.comp(key2, key3);
|
||||
// int cmp = memcmp(key1, key3, map->right.key_sz);
|
||||
assert(cmp == 0);
|
||||
free(key3);
|
||||
|
||||
size_t sz_1 = assoc_size(&map->left);
|
||||
size_t sz_2 = assoc_size(&map->right);
|
||||
|
||||
assert(sz_1 == sz_2);
|
||||
|
||||
return key2;
|
||||
}
|
||||
|
||||
// It returns the void* of key1. the void* of the key2 is freed
|
||||
void* bi_map_extract_right(bi_map_t* map, void* key2, size_t key2_sz)
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(key2 != NULL);
|
||||
assert(key2_sz == map->right.key_sz);
|
||||
|
||||
void* key1 = assoc_extract(&map->right, key2);
|
||||
void* key3 = assoc_extract(&map->left, key1);
|
||||
|
||||
int cmp = map->right.comp(key2, key3);
|
||||
// int cmp = memcmp(key2, key3, map->right.key_sz);
|
||||
assert(cmp == 0);
|
||||
free(key3);
|
||||
|
||||
size_t sz_1 = assoc_size(&map->left);
|
||||
size_t sz_2 = assoc_size(&map->right);
|
||||
|
||||
assert(sz_1 == sz_2);
|
||||
|
||||
return key1;
|
||||
}
|
||||
|
||||
// Capacity
|
||||
size_t bi_map_size(bi_map_t* map)
|
||||
{
|
||||
assert(map != NULL);
|
||||
size_t cap = assoc_size(&map->left);
|
||||
assert(cap == assoc_size(&map->right) && "Mismatch in the ds");
|
||||
return cap;
|
||||
}
|
||||
|
||||
// Forward Iterator Concept
|
||||
|
||||
bml_iter_t bi_map_front_left(bi_map_t* map)
|
||||
{
|
||||
assert(map != NULL);
|
||||
bml_iter_t it = {.it = assoc_front(&map->left)};
|
||||
return it;
|
||||
}
|
||||
|
||||
bml_iter_t bi_map_next_left(bi_map_t* map, bml_iter_t it)
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(it.it != NULL);
|
||||
bml_iter_t it_next = {.it = assoc_next(&map->left, it.it)};
|
||||
return it_next;
|
||||
}
|
||||
|
||||
bml_iter_t bi_map_end_left(bi_map_t* map)
|
||||
{
|
||||
assert(map != NULL);
|
||||
bml_iter_t it = {.it = assoc_front(&map->left)};
|
||||
return it;
|
||||
}
|
||||
|
||||
bmr_iter_t bi_map_front_right(bi_map_t* map)
|
||||
{
|
||||
assert(map != NULL);
|
||||
bmr_iter_t it = {.it = assoc_front(&map->right)};
|
||||
return it;
|
||||
}
|
||||
|
||||
bmr_iter_t bi_map_next_right(bi_map_t* map, bmr_iter_t it)
|
||||
{
|
||||
assert(map != NULL);
|
||||
assert(it.it != NULL);
|
||||
bmr_iter_t it_next = {.it = assoc_next(&map->right, it.it)};
|
||||
return it_next;
|
||||
}
|
||||
|
||||
bmr_iter_t bi_map_end_right(bi_map_t* map)
|
||||
{
|
||||
assert(map != NULL);
|
||||
bmr_iter_t it = {.it = assoc_end(&map->right)};
|
||||
return it;
|
||||
}
|
||||
|
||||
void* bi_map_value_left(bi_map_t* map, bml_iter_t it)
|
||||
{
|
||||
assert(map != NULL);
|
||||
return assoc_value(&map->left, it.it);
|
||||
}
|
||||
|
||||
void* bi_map_value_right(bi_map_t* map, bml_iter_t it)
|
||||
{
|
||||
assert(map != NULL);
|
||||
return assoc_value(&map->right, it.it);
|
||||
}
|
||||
|
||||
178
common/utils/ds/assoc_container/bimap.h
Normal file
178
common/utils/ds/assoc_container/bimap.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Mikel Irazabal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BIDIRECTIONAL_HASH_MAP
|
||||
#define BIDIRECTIONAL_HASH_MAP
|
||||
|
||||
/*
|
||||
* Naive bidirectional map. K1->K2 and K2->K1
|
||||
* It is implemented with 2 RB trees
|
||||
* https://en.wikipedia.org/wiki/Bidirectional_map
|
||||
*/
|
||||
|
||||
#include "assoc_rb_tree.h"
|
||||
|
||||
typedef int (*bi_map_cmp)(void const*, void const*);
|
||||
|
||||
typedef void (*free_func_t)(void* key, void* value);
|
||||
|
||||
typedef struct {
|
||||
assoc_rb_tree_t left;
|
||||
assoc_rb_tree_t right;
|
||||
} bi_map_t;
|
||||
|
||||
typedef struct {
|
||||
void* it;
|
||||
} bml_iter_t;
|
||||
|
||||
typedef struct {
|
||||
void* it;
|
||||
} bmr_iter_t;
|
||||
|
||||
/*
|
||||
* Init the bimap ds
|
||||
* @param map the ds to initialize
|
||||
* @param key_sz_1: Size of the first key i.e., sizeof(T), that the rb_tree will store.
|
||||
* @param key_sz_2: Size of the second key i.e., sizeof(T), that the rb_tree will store.
|
||||
* @param comp1 Compare function in the left RB tree.
|
||||
* @param comp2 Compare function in the right RB tree.
|
||||
* @param free1: Free function to free the left key
|
||||
* @param free2: Free function to free the right key
|
||||
*/
|
||||
|
||||
void bi_map_init(bi_map_t* map, size_t key_sz_1, size_t key_sz_2, bi_map_cmp cmp1, bi_map_cmp cmp2, free_func_t free1, free_func_t free2);
|
||||
|
||||
/*
|
||||
* Free the bimap ds
|
||||
* @param map the ds
|
||||
*/
|
||||
void bi_map_free(bi_map_t* map);
|
||||
|
||||
// Modifiers
|
||||
|
||||
/*
|
||||
* Insert K1 and K2 in the bimap ds
|
||||
* @param map the ds
|
||||
* @param key_1: key1 pointer of the first key
|
||||
* @param key_2: key2 pointer of the second key
|
||||
* @param key_sz_1: Size of the first key i.e., sizeof(T)
|
||||
* @param key_sz_2: Size of the second key i.e., sizeof(T)
|
||||
*/
|
||||
void bi_map_insert(bi_map_t* map, void const* key1, size_t key_sz1, void const* key2, size_t key_sz2);
|
||||
|
||||
/*
|
||||
* It returns the void* of key2. the void* of the key1 is freed
|
||||
* @param map the ds
|
||||
* @param key_1: key1 pointer of the first key
|
||||
* @param key_sz_1: Size of the first key i.e., sizeof(T)
|
||||
* @return key2
|
||||
*/
|
||||
|
||||
void* bi_map_extract_left(bi_map_t* map, void* key1, size_t key1_sz);
|
||||
|
||||
|
||||
/*
|
||||
* It returns the void* of key1. the void* of the key2 is freed
|
||||
* @param map the ds
|
||||
* @param key_2: key2 pointer of the second key
|
||||
* @param key_sz_2: Size of the first key i.e., sizeof(T)
|
||||
* @return key1
|
||||
*/
|
||||
|
||||
void* bi_map_extract_right(bi_map_t* map, void* key2, size_t key1_sz);
|
||||
|
||||
/*
|
||||
* It returns the void* of key2. the void* of the key1 is not freed
|
||||
* @param map the ds
|
||||
* @param bml_iter_t bimap left iterator
|
||||
* @return key2
|
||||
*/
|
||||
|
||||
void* bi_map_value_left(bi_map_t* map, bml_iter_t it);
|
||||
|
||||
/*
|
||||
* It returns the void* of key1. the void* of the key2 is not freed
|
||||
* @param map the ds
|
||||
* @param bml_iter_t valid bimap iterator
|
||||
* @return key1
|
||||
*/
|
||||
void* bi_map_value_right(bi_map_t* map, bml_iter_t it);
|
||||
|
||||
// Capacity
|
||||
|
||||
/*
|
||||
* Number of elements in the ds
|
||||
* @param map the ds
|
||||
* @return number of elements in the ds
|
||||
*/
|
||||
|
||||
size_t bi_map_size(bi_map_t* map);
|
||||
|
||||
// Forward Iterator Concept
|
||||
|
||||
/*
|
||||
* Front left Iterator front of the left rb tree
|
||||
* @param map the ds
|
||||
* @return iterator to the front left rb tree
|
||||
*/
|
||||
bml_iter_t bi_map_front_left(bi_map_t* map);
|
||||
|
||||
/*
|
||||
* Next Iterator in the left rb tree
|
||||
* @param map the ds
|
||||
* @param it iterator to the next element from the left rb tree
|
||||
* @return iterator to the next iterator in the left rb tree
|
||||
*/
|
||||
bml_iter_t bi_map_next_left(bi_map_t* map, bml_iter_t it);
|
||||
|
||||
/*
|
||||
* End Iterator in the left rb tree
|
||||
* @param map the ds
|
||||
* @return iterator to the one past the end iterator in the left rb tree
|
||||
*/
|
||||
bml_iter_t bi_map_end_left(bi_map_t* map);
|
||||
|
||||
/*
|
||||
* Front right Iterator front of the right rb tree
|
||||
* @param map the ds
|
||||
* @return iterator to the front right rb tree
|
||||
*/
|
||||
bmr_iter_t bi_map_front_right(bi_map_t* map);
|
||||
|
||||
/*
|
||||
* Next Iterator in the right rb tree
|
||||
* @param map the ds
|
||||
* @param it iterator to the next element from the right rb tree
|
||||
* @return iterator to the next iterator in the right rb tree
|
||||
*/
|
||||
bmr_iter_t bi_map_next_right(bi_map_t* map, bmr_iter_t);
|
||||
|
||||
/*
|
||||
* End Iterator in the right rb tree
|
||||
* @param map the ds
|
||||
* @return iterator to the one past the end iterator in the right rb tree
|
||||
*/
|
||||
bmr_iter_t bi_map_end_right(bi_map_t* map);
|
||||
|
||||
#endif
|
||||
@@ -28,7 +28,7 @@ byte_array_t copy_byte_array(byte_array_t src)
|
||||
{
|
||||
byte_array_t dst = {0};
|
||||
dst.buf = malloc(src.len);
|
||||
DevAssert(dst.buf != NULL && "Memory exhausted");
|
||||
AssertFatal(dst.buf != NULL, "Memory exhausted\n");
|
||||
memcpy(dst.buf, src.buf, src.len);
|
||||
dst.len = src.len;
|
||||
return dst;
|
||||
|
||||
@@ -24,16 +24,42 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "common/utils/assertions.h"
|
||||
|
||||
/*
|
||||
* Simple and efficient data structure to bring together the length and the pointer
|
||||
* You can cheaply copy and return it as it only utilizes two registers in x86-64
|
||||
*/
|
||||
typedef struct {
|
||||
size_t len;
|
||||
uint8_t* buf;
|
||||
} byte_array_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t buf[32];
|
||||
} byte_array_32_t;
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// These macros need to be removed once the KPM is upgraded
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
/* create on the stack a byte_array_t named 'name' implemented as array of length 'length'*/
|
||||
#define BYTE_ARRAY_STACK(name, length) \
|
||||
uint8_t(name##_BuF)[(length)]; \
|
||||
memset((name##_BuF), 0, sizeof((name##_BuF))); \
|
||||
byte_array_t(name) = {.buf = (name##_BuF), .len = (length)}
|
||||
|
||||
/* create on the heap a new 'byte_array_t' data structure named 'ba' from OCTET_STRING_t named 'octet' pointer*/
|
||||
#define BYTE_ARRAY_HEAP_CP_FROM_OCTET_STRING_POINTERS(ba, octet) \
|
||||
ba->buf = calloc(1, octet->size); \
|
||||
AssertFatal(ba->buf != NULL, "Memory exhausted"); \
|
||||
memcpy(ba->buf, octet->buf, octet->size); \
|
||||
ba->len = octet->size;
|
||||
|
||||
#define BYTE_ARRAY_HEAP_CP_FROM_OCTET_STRING(ba, octet) \
|
||||
ba.buf = calloc(1, octet.size); \
|
||||
AssertFatalu(ba.buf != NULL, "Memory exhausted"); \
|
||||
memcpy(ba.buf, octet.buf, octet.size); \
|
||||
ba.len = octet.size;
|
||||
|
||||
byte_array_t copy_byte_array(byte_array_t src);
|
||||
void free_byte_array(byte_array_t ba);
|
||||
|
||||
176
common/utils/ds/seq_container/seq_arr.c
Normal file
176
common/utils/ds/seq_container/seq_arr.c
Normal file
@@ -0,0 +1,176 @@
|
||||
#include "seq_arr.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static
|
||||
const size_t MIN_SIZE = 8;
|
||||
|
||||
static
|
||||
void maybe_expand(seq_arr_t* arr)
|
||||
{
|
||||
if(arr->size + 1 == arr->cap){
|
||||
//void* p = reallocarray(arr->data, arr->cap*2, arr->elt_size);
|
||||
arr->data = realloc(arr->data, 2*arr->cap*arr->elt_size);
|
||||
assert(arr->data != NULL && "realloc failed to allocate memory");
|
||||
arr->cap *=2;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void maybe_shrink(seq_arr_t* arr)
|
||||
{
|
||||
const float occ = (float)arr->size / (float)arr->cap;
|
||||
//printf("Occ = %f and size = %ld \n", occ, arr->size);
|
||||
if(arr->size > MIN_SIZE && occ < 0.25){
|
||||
assert(arr->cap > MIN_SIZE);
|
||||
seq_arr_t tmp = {.data = NULL, .size = arr->size, .elt_size = arr->elt_size, .cap = arr->cap/2};
|
||||
tmp.data = calloc(tmp.cap, tmp.cap);
|
||||
assert(tmp.data != NULL && "Memory exhausted");
|
||||
assert(arr->size <= tmp.cap);
|
||||
memcpy(tmp.data, arr->data, arr->size*arr->elt_size);
|
||||
free(arr->data);
|
||||
memcpy(arr, &tmp, sizeof(seq_arr_t));
|
||||
}
|
||||
}
|
||||
|
||||
void seq_arr_init(seq_arr_t* arr, size_t elt_size) //__attribute__(malloc)
|
||||
{
|
||||
assert(arr != NULL);
|
||||
seq_arr_t tmp = {.data = NULL, .size = 0, .elt_size = elt_size, .cap = MIN_SIZE};
|
||||
memcpy(arr, &tmp, sizeof(seq_arr_t));
|
||||
arr->data = calloc(arr->cap, elt_size);
|
||||
assert(arr->data != NULL);
|
||||
}
|
||||
|
||||
void seq_arr_free(seq_arr_t* arr, void (*free_func)(void*) )
|
||||
{
|
||||
assert(arr != NULL);
|
||||
assert(arr->data != NULL);
|
||||
|
||||
if(free_func != NULL) {
|
||||
void* start_it = seq_arr_front(arr);
|
||||
void* end_it = seq_arr_end(arr);
|
||||
while(start_it != end_it){
|
||||
free_func(start_it);
|
||||
start_it = seq_arr_next(arr, start_it);
|
||||
}
|
||||
}
|
||||
|
||||
free(arr->data);
|
||||
}
|
||||
|
||||
void seq_arr_push_back(seq_arr_t* arr, void* data, size_t len)
|
||||
{
|
||||
assert(arr != NULL);
|
||||
//assert(data != NULL);
|
||||
assert(len == arr->elt_size);
|
||||
|
||||
maybe_expand(arr);
|
||||
|
||||
const size_t offset = arr->size * arr->elt_size;
|
||||
memcpy(&arr->data[offset], data, arr->elt_size);
|
||||
arr->size += 1;
|
||||
};
|
||||
|
||||
void seq_arr_erase(seq_arr_t* arr, void* start_it, void* end_it)
|
||||
{
|
||||
// start_it && end_it must be in the range of arr->data
|
||||
assert(arr != NULL);
|
||||
assert(start_it != NULL);
|
||||
assert(end_it != NULL);
|
||||
assert(end_it >= start_it);
|
||||
|
||||
if(start_it == end_it) return;
|
||||
|
||||
const int num_bytes_move = seq_arr_end(arr) - end_it;
|
||||
assert(num_bytes_move > -1);
|
||||
memmove(start_it, end_it, num_bytes_move);
|
||||
|
||||
const int num_bytes_erase = end_it - start_it;
|
||||
const int32_t num_elm_erase = num_bytes_erase/arr->elt_size;
|
||||
assert(num_elm_erase > 0);
|
||||
arr->size -= num_elm_erase;
|
||||
|
||||
memset(seq_arr_end(arr), 0, num_bytes_erase);
|
||||
|
||||
maybe_shrink(arr);
|
||||
}
|
||||
|
||||
/*
|
||||
void seq_arr_erase_free(seq_arr_t *arr, void *start_it, void *end_it,
|
||||
void (*free_func)(void *)) {
|
||||
assert(arr != NULL);
|
||||
assert(start_it != NULL);
|
||||
assert(end_it != NULL);
|
||||
assert(end_it >= start_it);
|
||||
assert(free_func != NULL && "Use seq_arr_erase instead ");
|
||||
|
||||
while (start_it != end_it) {
|
||||
free_func(start_it);
|
||||
start_it = seq_arr_next(arr, start_it);
|
||||
}
|
||||
|
||||
seq_arr_erase(arr, start_it, end_it);
|
||||
}
|
||||
*/
|
||||
|
||||
size_t seq_arr_size(seq_arr_t* arr)
|
||||
{
|
||||
assert(arr != NULL);
|
||||
return arr->size;
|
||||
}
|
||||
|
||||
void* seq_arr_front(seq_arr_t* arr)
|
||||
{
|
||||
return arr->data;
|
||||
}
|
||||
|
||||
void* seq_arr_next(seq_arr_t* arr, void* it)
|
||||
{
|
||||
assert(arr != NULL);
|
||||
assert(it != NULL);
|
||||
return (uint8_t*)it + arr->elt_size;
|
||||
}
|
||||
|
||||
void* seq_arr_end(seq_arr_t* arr)
|
||||
{
|
||||
assert(arr != NULL);
|
||||
return &arr->data[arr->size*arr->elt_size];
|
||||
}
|
||||
|
||||
void* seq_arr_at(seq_arr_t* arr, uint32_t pos)
|
||||
{
|
||||
assert(pos < arr->size);
|
||||
return arr->data + pos*arr->elt_size;
|
||||
}
|
||||
|
||||
ptrdiff_t seq_arr_dist(seq_arr_t* arr, void* first, void* last)
|
||||
{
|
||||
assert(arr != NULL);
|
||||
assert(first != NULL);
|
||||
assert(last != NULL);
|
||||
const ptrdiff_t pos = (last - first)/arr->elt_size;
|
||||
assert(pos > -1);
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool seq_arr_equal(seq_arr_t* arr, void* it_1, void* it_2)
|
||||
{
|
||||
assert(arr!= NULL);
|
||||
assert(it_1 != NULL);
|
||||
assert(it_2 != NULL);
|
||||
return it_1 == it_2;
|
||||
}
|
||||
|
||||
void* seq_arr_value(seq_arr_t* arr, void* it)
|
||||
{
|
||||
assert(arr != NULL);
|
||||
assert(it != NULL);
|
||||
|
||||
assert(0!=0 && "Not implemented!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
126
common/utils/ds/seq_container/seq_arr.h
Normal file
126
common/utils/ds/seq_container/seq_arr.h
Normal file
@@ -0,0 +1,126 @@
|
||||
#ifndef SEQ_CONTAINER_ARRAY
|
||||
#define SEQ_CONTAINER_ARRAY
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/*
|
||||
* Dynamic array data structure that shrinks and expands as needed, similar to std::vector
|
||||
*/
|
||||
|
||||
typedef struct seq_arr_s{
|
||||
uint8_t* data;
|
||||
size_t size;
|
||||
const size_t elt_size;
|
||||
size_t cap;
|
||||
} seq_arr_t;
|
||||
|
||||
typedef void (*seq_free_func)(void*);
|
||||
|
||||
/*
|
||||
* Init the seq_array ds
|
||||
* @param arr: the ds to initialize
|
||||
* @param sz: Size of the data type i.e., sizeof(T), that the seq_array_t will store.
|
||||
*/
|
||||
void seq_arr_init(seq_arr_t* arr, size_t sz);
|
||||
|
||||
/*
|
||||
* Free the seq_array ds
|
||||
* @param arr: the ds
|
||||
* @param seq_free_func: Function that every element will call before being freed e.g., usefull to free
|
||||
* "deep" objects.
|
||||
* */
|
||||
void seq_arr_free(seq_arr_t*, seq_free_func );
|
||||
|
||||
/*
|
||||
* Push back
|
||||
* @param arr: the ds
|
||||
* @param data: Pointer to the data that will ve copied. This a swallow copy i.e., memcpy
|
||||
* @param len: Lenght of the data to be stored i.e.,sizeof(T). This parameter is only used
|
||||
* to guarantee that the object copied and the underlying array initialized at
|
||||
* seq_arr_init have the same lenght
|
||||
* */
|
||||
void seq_arr_push_back(seq_arr_t* arr, void* data, size_t len);
|
||||
|
||||
|
||||
/*
|
||||
* Erase a half-open range [start_it, end_it)
|
||||
* @param arr: the ds
|
||||
* @param start_it Starting iterator of the range
|
||||
* @param end_it Ending iterator of the range
|
||||
* @pre Precondition: the range is valid and @p end_it can be reached from @p start_it
|
||||
*/
|
||||
void seq_arr_erase(seq_arr_t*, void* start_it , void* end_it);
|
||||
|
||||
/*
|
||||
* Size
|
||||
* @param arr: the ds
|
||||
* @return the number of elements in the ds s
|
||||
* */
|
||||
|
||||
size_t seq_arr_size(seq_arr_t*);
|
||||
|
||||
/*
|
||||
* Front
|
||||
* @param arr: the ds
|
||||
* @return the iterator to the first element
|
||||
* */
|
||||
|
||||
void* seq_arr_front(seq_arr_t*);
|
||||
|
||||
/*
|
||||
* Next
|
||||
* @param arr the ds
|
||||
* @param it Iterator
|
||||
* @return Iterator to the next element in the ds
|
||||
* @pre Precondition: iterator @p it, is valid and not equal to the end iterator
|
||||
* */
|
||||
|
||||
void* seq_arr_next(seq_arr_t*, void* it);
|
||||
|
||||
/*
|
||||
* End
|
||||
* @param arr: the ds
|
||||
* @return one past the last element in the ds
|
||||
* */
|
||||
|
||||
void* seq_arr_end(seq_arr_t*);
|
||||
|
||||
/*
|
||||
* End
|
||||
* @param arr: the ds
|
||||
* @param nth: Position of the element
|
||||
* @return the iterator the nth element
|
||||
* Precondition: @p nth is not greater than seq_arr_size()
|
||||
*/
|
||||
|
||||
void* seq_arr_at(seq_arr_t*, uint32_t nth);
|
||||
|
||||
/*
|
||||
* Distance
|
||||
* @param arr: the ds
|
||||
* @param it_a Iterator
|
||||
* @param it_b Iterator
|
||||
* @return the of the amount of elements between it_a and it_b
|
||||
* @pre Precondition: @p it_a and @p it_b are valid and @p it_a < @p it_b
|
||||
*/
|
||||
|
||||
ptrdiff_t seq_arr_dist(seq_arr_t* arr, void* it_a, void* it_b);
|
||||
|
||||
/*
|
||||
* Equality
|
||||
* @param arr: the ds
|
||||
* @param it_a: iterator from the seq_array ds
|
||||
* @param it_b: iterator from the seq_array ds
|
||||
* @return true if both iterators point to the same element
|
||||
* @pre Precondition: @p it_a and @p it_b are valid iterators
|
||||
*/
|
||||
|
||||
bool seq_arr_equal(seq_arr_t* arr, void* it_a ,void* it_b);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
65
common/utils/ds/seq_container/seq_generic.h
Normal file
65
common/utils/ds/seq_container/seq_generic.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef SEQUENCE_CONTAINERS_GENERIC
|
||||
#define SEQUENCE_CONTAINERS_GENERIC
|
||||
|
||||
#include "seq_arr.h"
|
||||
|
||||
/*
|
||||
*Generic sequence container file. Nomenclature from the C++ sequence containers
|
||||
*/
|
||||
|
||||
|
||||
// Initialization
|
||||
#define seq_init(T,U) _Generic ((T), seq_arr_t*: seq_arr_init, \
|
||||
default: seq_arr_init) (T,U)
|
||||
|
||||
|
||||
#define seq_free(T,U) _Generic ((T), seq_arr_t*: seq_arr_free, \
|
||||
default: seq_arr_free)(T,U)
|
||||
|
||||
|
||||
// Modifiers
|
||||
#define seq_push_back(T,U,W) _Generic ((T), seq_arr_t*: seq_arr_push_back, \
|
||||
default: seq_arr_push_back)(T,U,W)
|
||||
|
||||
#define seq_erase(T,U,W) _Generic ((T), seq_arr_t*: seq_arr_erase, \
|
||||
default: seq_arr_erase)(T,U,W)
|
||||
|
||||
#define seq_erase_free(T, U, W, X) \
|
||||
_Generic((T), seq_arr_t * \
|
||||
: seq_arr_erase_free, default \
|
||||
: seq_arr_erase_free)(T, U, W, X)
|
||||
|
||||
// Capacity
|
||||
#define seq_size(T) _Generic ((T), seq_arr_t*: seq_arr_size, \
|
||||
default: seq_arr_size)(T)
|
||||
|
||||
|
||||
// Forward Iterator Concept
|
||||
#define seq_front(T) _Generic ((T), seq_arr_t*: seq_arr_front, \
|
||||
default: seq_arr_front)(T)
|
||||
|
||||
#define seq_next(T,U) _Generic((T), seq_arr_t*: seq_arr_next, \
|
||||
default: seq_arr_next)(T,U)
|
||||
|
||||
#define seq_end(T) _Generic((T), seq_arr_t*: seq_arr_end, \
|
||||
default: seq_arr_end)(T)
|
||||
|
||||
// at position starting from zero
|
||||
#define seq_at(T,U) _Generic((T), seq_arr_t*: seq_arr_at, \
|
||||
default: seq_arr_at)(T,U)
|
||||
|
||||
//
|
||||
#define seq_distance(T,U,V) _Generic((T), seq_arr_t*: seq_arr_dist,\
|
||||
default: seq_arr_dist)(T,U,V)
|
||||
|
||||
// Equality
|
||||
|
||||
#define seq_equal(T,U,V) _Generic((T), seq_arr_t*: seq_arr_equal, \
|
||||
default: seq_arr_equal)(U,V)
|
||||
|
||||
|
||||
#define seq_value(T,U) _Generic((T), seq_arr_t*: seq_arr_value, \
|
||||
default: seq_arr_value)(U)
|
||||
|
||||
|
||||
#endif
|
||||
@@ -117,7 +117,7 @@ double time_average_get_average(time_average_t *t, uint64_t time)
|
||||
return (double)t->accumulated_value / t->r.size;
|
||||
}
|
||||
|
||||
uint64_t time_average_now(void)
|
||||
uint64_t time_now_us(void)
|
||||
{
|
||||
struct timespec t;
|
||||
uint64_t ret;
|
||||
|
||||
@@ -59,6 +59,6 @@ void time_average_add(time_average_t *t, uint64_t time, uint64_t value);
|
||||
double time_average_get_average(time_average_t *t, uint64_t time);
|
||||
|
||||
/* unit microsecond */
|
||||
uint64_t time_average_now(void);
|
||||
uint64_t time_now_us(void);
|
||||
|
||||
#endif /* _COMMON_UTIL_TIME_STAT_H_ */
|
||||
|
||||
@@ -90,6 +90,18 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
# include "sys/gmon.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
#include "openair2/E2AP/sm/agent_if/read/sm_ag_if_rd.h"
|
||||
#include "openair2/E2AP/sm/agent_if/write/sm_ag_if_wr.h"
|
||||
#include "openair2/E2AP/sm/sm_io.h"
|
||||
#include "openair2/E2AP/agent/e2_agent_api.h"
|
||||
#include <time.h>
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
@@ -440,6 +452,28 @@ static void wait_nfapi_init(char *thread_name) {
|
||||
printf( "NFAPI: got sync (%s)\n", thread_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
static
|
||||
void read_RAN(sm_ag_if_rd_t* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(false && "not implemented");
|
||||
}
|
||||
|
||||
static
|
||||
sm_ag_if_ans_t write_RAN(sm_ag_if_wr_t const* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(false && "not implemented");
|
||||
sm_ag_if_ans_t ans = {};
|
||||
return ans;
|
||||
}
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
int main ( int argc, char **argv )
|
||||
{
|
||||
int CC_id = 0;
|
||||
@@ -492,6 +526,33 @@ int main ( int argc, char **argv )
|
||||
}
|
||||
|
||||
if (RC.nb_inst > 0) {
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
//////////////////////////////////
|
||||
//////////////////////////////////
|
||||
//// Init the E2 Agent
|
||||
|
||||
e2_agent_args_t args = {0};
|
||||
if (RCconfig_E2agent(&args)) {
|
||||
sleep(1);
|
||||
const eNB_RRC_INST* rrc = RC.rrc[0];
|
||||
assert(rrc != NULL && "rrc cannot be NULL");
|
||||
|
||||
const int mcc = rrc->configuration.mcc[0];
|
||||
const int mnc = rrc->configuration.mnc[0];
|
||||
const int mnc_digit_len = rrc->configuration.mnc_digit_length[0];
|
||||
const int nb_id = rrc->configuration.cell_identity;
|
||||
// TODO: node_type = 0 // ngran_eNB
|
||||
const int cu_du_id = 0;
|
||||
sm_io_ag_t io = {.read = read_RAN, .write = write_RAN};
|
||||
printf("[E2 NODE]: mcc = %d mnc = %d mnc_digit = %d nd_id = %d \n", mcc, mnc, mnc_digit_len, nb_id);
|
||||
|
||||
init_agent_api( mcc, mnc, mnc_digit_len, nb_id, cu_du_id, 0, io, &args);
|
||||
}
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
/* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks */
|
||||
init_pdcp();
|
||||
|
||||
|
||||
@@ -82,6 +82,24 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "openair2/E1AP/e1ap_common.h"
|
||||
#include "openair2/E1AP/e1ap_api.h"
|
||||
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
#include "openair2/E2AP/sm/agent_if/read/sm_ag_if_rd.h"
|
||||
#include "openair2/E2AP/sm/sm_io.h"
|
||||
#include "openair2/E2AP/agent/e2_agent_api.h"
|
||||
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#include <time.h>
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
@@ -568,6 +586,184 @@ void init_pdcp(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
static
|
||||
void read_kpm_sm(kpm_ind_data_t* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
// Fill KPM indication header
|
||||
kpm_ind_hdr_t* hdr = &data->hdr;
|
||||
int64_t t = time_now_us();
|
||||
hdr->collectStartTime = t / 1000000; // needs to be truncated to 32 bits to arrive to a resolution of seconds
|
||||
hdr->fileFormatversion = NULL;
|
||||
hdr->senderName = NULL;
|
||||
hdr->senderType = NULL;
|
||||
hdr->vendorName = NULL;
|
||||
|
||||
// Fill KPM indication message
|
||||
kpm_ind_msg_t* msg = &data->msg;
|
||||
|
||||
// TODO: assign MeaData_len according to eventPeriod/granulPeriod from the action definition or subscription request
|
||||
msg->MeasData_len = 1;
|
||||
if (msg->MeasData_len > 0) {
|
||||
msg->MeasData = calloc(msg->MeasData_len, sizeof(adapter_MeasDataItem_t));
|
||||
assert(msg->MeasData != NULL && "Memory exhausted" );
|
||||
}
|
||||
|
||||
// get the number of connected UEs
|
||||
NR_UEs_t *UE_info = &RC.nrmac[0]->UE_info;
|
||||
size_t num_ues = 0;
|
||||
UE_iterator(UE_info->list, ue) {
|
||||
if (ue)
|
||||
num_ues += 1;
|
||||
}
|
||||
|
||||
if (num_ues > 0) {
|
||||
// get the info to calculate the resource utilization
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
|
||||
int cur_slot = RC.nrmac[0]->slot;
|
||||
// int num_dl_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
|
||||
// get total number of available resource blocks
|
||||
int n_rb_sched = 0;
|
||||
if (UE_info->list[0] != NULL) {
|
||||
/* Get bwpSize and TDA from the first UE */
|
||||
/* This is temporary and it assumes all UEs have the same BWP and TDA*/
|
||||
NR_UE_info_t *UE = UE_info->list[0];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP;
|
||||
const int tda = get_dl_tda(RC.nrmac[0], scc, cur_slot);
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = get_dl_tdalist(current_BWP, coresetid, sched_ctrl->search_space->searchSpaceType->present, NR_RNTI_C);
|
||||
AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[0]->cset0_bwp_size : current_BWP->BWPSize;
|
||||
const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[0]->cset0_bwp_start : current_BWP->BWPStart;
|
||||
const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols);
|
||||
uint16_t *vrb_map = RC.nrmac[0]->common_channels[0].vrb_map;
|
||||
uint16_t rballoc_mask[bwpSize];
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
// calculate mask: init with "NOT" vrb_map:
|
||||
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
||||
rballoc_mask[i] = (~vrb_map[i + BWPStart]) & 0x3fff; //bitwise not and 14 symbols
|
||||
// if all the pdsch symbols are free
|
||||
if ((rballoc_mask[i] & slbitmap) == slbitmap) {
|
||||
n_rb_sched++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: assign the MeasData every granulPeriod
|
||||
for (size_t i = 0; i < msg->MeasData_len; i++) {
|
||||
adapter_MeasDataItem_t* item = &msg->MeasData[i];
|
||||
|
||||
// TODO: assign measRecord_len according to
|
||||
// (1) the length of Measurements Information List IE (format1) or
|
||||
// (2) Measurements Information Condition UE List IE (format2)
|
||||
// from the action definition or subscription request
|
||||
|
||||
// TODO: only support KPM format 1, and it only can handle one UE's information
|
||||
// assume to record one data: DL resource utilization
|
||||
item->measRecord_len = 1;
|
||||
if (item->measRecord_len > 0) {
|
||||
item->measRecord = calloc(item->measRecord_len, sizeof(adapter_MeasRecord_t));
|
||||
assert(item->measRecord != NULL && "Memory exhausted");
|
||||
}
|
||||
|
||||
UE_iterator(UE_info->list, UE)
|
||||
{
|
||||
int dl_rb_usage = 0;
|
||||
if (is_xlsch_in_slot(RC.nrmac[0]->dlsch_slot_bitmap[cur_slot / 64], cur_slot))
|
||||
dl_rb_usage = UE->mac_stats.dl.current_rbs*100/n_rb_sched;
|
||||
|
||||
// TODO: go through the measRecord according to the Measurements Information (format 1) or Information Condition UE (format 2) List IE
|
||||
adapter_MeasRecord_t *record_PrbDlUsage = &item->measRecord[0];
|
||||
record_PrbDlUsage->type = MeasRecord_int;
|
||||
record_PrbDlUsage->int_val = dl_rb_usage;
|
||||
}
|
||||
|
||||
// incompleteFlag = -1, the data is reliable
|
||||
item->incompleteFlag = -1;
|
||||
}
|
||||
|
||||
// TODO: assign MeasInfo_len according to the action definition or subscription request
|
||||
msg->MeasInfo_len = 1;
|
||||
if (msg->MeasInfo_len > 0) {
|
||||
msg->MeasInfo = calloc(msg->MeasInfo_len, sizeof(MeasInfo_t));
|
||||
assert(msg->MeasInfo != NULL && "Memory exhausted" );
|
||||
|
||||
MeasInfo_t* info = &msg->MeasInfo[0];
|
||||
info->meas_type = KPM_V2_MEASUREMENT_TYPE_NAME;
|
||||
char* measName = "PrbDlUsage";
|
||||
info->measName.len = strlen(measName);
|
||||
info->measName.buf = malloc(strlen(measName));
|
||||
assert(info->measName.buf != NULL && "memory exhausted");
|
||||
memcpy(info->measName.buf, measName, msg->MeasInfo[0].measName.len);
|
||||
|
||||
// TODO: assign labelInfo_len according to the action definition (?)
|
||||
info->labelInfo_len = 1;
|
||||
info->labelInfo = calloc(info->labelInfo_len, sizeof(adapter_LabelInfoItem_t));
|
||||
assert(info->labelInfo != NULL && "memory exhausted");
|
||||
adapter_LabelInfoItem_t* label = &info->labelInfo[0];
|
||||
label->noLabel = calloc(1, sizeof(long));
|
||||
assert(label->noLabel != NULL && "memory exhausted");
|
||||
*(label->noLabel) = 0;
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < msg->MeasData_len; i++) {
|
||||
adapter_MeasDataItem_t* item = &msg->MeasData[i];
|
||||
item->measRecord_len = 1;
|
||||
if (item->measRecord_len > 0) {
|
||||
item->measRecord = calloc(item->measRecord_len, sizeof(adapter_MeasRecord_t));
|
||||
assert(item->measRecord != NULL && "Memory exhausted");
|
||||
}
|
||||
|
||||
adapter_MeasRecord_t *record_nodata = &item->measRecord[0];
|
||||
record_nodata->type = MeasRecord_int;
|
||||
record_nodata->int_val = 0;
|
||||
|
||||
// incompleteFlag = 0, the data is not reliable
|
||||
item->incompleteFlag = 0;
|
||||
}
|
||||
msg->MeasInfo_len = 0;
|
||||
msg->MeasInfo = NULL;
|
||||
}
|
||||
|
||||
msg->granulPeriod = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void read_RAN(sm_ag_if_rd_t* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(data->type == KPM_STATS_V0);
|
||||
|
||||
if(data->type == KPM_STATS_V0){
|
||||
read_kpm_sm(&data->kpm_stats);
|
||||
} else {
|
||||
assert(false && "Unknown data type!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
sm_ag_if_ans_t write_RAN(sm_ag_if_wr_t const* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(false && "Not implemented");
|
||||
sm_ag_if_ans_t ans = {.type = SM_AGENT_IF_ANS_V0_END };
|
||||
return ans;
|
||||
}
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
int ru_id, CC_id = 0;
|
||||
start_background_system();
|
||||
@@ -683,6 +879,43 @@ int main( int argc, char **argv ) {
|
||||
|
||||
config_sync_var=0;
|
||||
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
//////////////////////////////////
|
||||
//////////////////////////////////
|
||||
//// Init the E2 Agent
|
||||
|
||||
e2_agent_args_t args = {0};
|
||||
if (RCconfig_NR_E2agent(&args)) {
|
||||
sleep(1);
|
||||
const gNB_RRC_INST* rrc = RC.nrrrc[0];
|
||||
assert(rrc != NULL && "rrc cannot be NULL");
|
||||
|
||||
const int mcc = rrc->configuration.mcc[0];
|
||||
const int mnc = rrc->configuration.mnc[0];
|
||||
const int mnc_digit_len = rrc->configuration.mnc_digit_length[0];
|
||||
const ngran_node_t node_type = rrc->node_type;
|
||||
int nb_id = 0;
|
||||
int cu_du_id = 0;
|
||||
if (node_type == ngran_gNB) {
|
||||
nb_id = rrc->configuration.cell_identity;
|
||||
} else if (node_type == ngran_gNB_DU) {
|
||||
cu_du_id = rrc->configuration.cell_identity;
|
||||
} else if (node_type == ngran_gNB_CU) {
|
||||
cu_du_id = rrc->node_id;
|
||||
} else {
|
||||
LOG_E(NR_RRC, "not supported ran type detect\n");
|
||||
}
|
||||
sm_io_ag_t io = {.read = read_RAN, .write = write_RAN};
|
||||
printf("[E2 NODE]: mcc = %d mnc = %d mnc_digit = %d nd_id = %d \n", mcc, mnc, mnc_digit_len, nb_id);
|
||||
|
||||
init_agent_api( mcc, mnc, mnc_digit_len, nb_id, cu_du_id, node_type, io, &args);
|
||||
}
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
wait_nfapi_init("main?");
|
||||
}
|
||||
|
||||
@@ -3,3 +3,10 @@ add_subdirectory(F1AP)
|
||||
add_subdirectory(M2AP)
|
||||
add_subdirectory(X2AP)
|
||||
add_subdirectory(RRC)
|
||||
|
||||
if(E2_AGENT STREQUAL "ON")
|
||||
add_subdirectory(E2AP)
|
||||
message(STATUS "Building E2 Agent")
|
||||
else()
|
||||
message(STATUS "NOT building E2 Agent")
|
||||
endif()
|
||||
|
||||
33
openair2/E2AP/CMakeLists.txt
Normal file
33
openair2/E2AP/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
set(E2AP_LIBRARY "STATIC" CACHE STRING "Static or dynamic library")
|
||||
set_property(CACHE E2AP_LIBRARY PROPERTY STRINGS "STATIC" "DYNAMIC")
|
||||
message(STATUS "Selected LIBRARY TYPE: ${E2AP_LIBRARY}")
|
||||
|
||||
if(E2AP_LIBRARY STREQUAL "STATIC")
|
||||
add_compile_options("-W;-Wall;-Wextra;-g;-Wno-unused-result;")
|
||||
elseif(E2AP_LIBRARY STREQUAL "DYNAMIC")
|
||||
# -fPIC flag
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
add_compile_options("-W;-Wall;-Wextra;-g")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown building type. Either choose a static or a dynamic library")
|
||||
endif()
|
||||
|
||||
|
||||
set(E2AP_ENCODING "E2AP_ASN" CACHE STRING "The E2AP encoding to use")
|
||||
set_property(CACHE E2AP_ENCODING PROPERTY STRINGS "E2AP_ASN" "E2AP_FLATBUFFERS")
|
||||
message(STATUS "Selected E2AP_ENCODING: ${E2AP_ENCODING}")
|
||||
|
||||
#######
|
||||
## Service Models
|
||||
#######
|
||||
|
||||
# KPM service Model encoding definitions
|
||||
set(SM_ENCODING_KPM "E2SM_KPM_ASN" CACHE STRING "The KPM SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_KPM PROPERTY STRINGS "E2SM_KPM_PLAIN" "E2SM_KPM_ASN" "E2SM_KPM_FLATBUFFERS")
|
||||
message(STATUS "Selected SM_ENCODING_KPM: ${SM_ENCODING_KPM}")
|
||||
|
||||
add_subdirectory(agent)
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(sm)
|
||||
add_subdirectory(test)
|
||||
72
openair2/E2AP/agent/CMakeLists.txt
Normal file
72
openair2/E2AP/agent/CMakeLists.txt
Normal file
@@ -0,0 +1,72 @@
|
||||
if(E2AP_LIBRARY STREQUAL "STATIC")
|
||||
set(E2_AGENT_BLD_LIB "STATIC")
|
||||
elseif(E2AP_LIBRARY STREQUAL "DYNAMIC")
|
||||
set(E2_AGENT_BLD_LIB "SHARED")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown type")
|
||||
endif()
|
||||
|
||||
|
||||
set(E2_AGENT_SRC
|
||||
asio_agent.c
|
||||
e2ap_agent.c
|
||||
e2_agent.c
|
||||
e2_agent_api.c
|
||||
endpoint_agent.c
|
||||
msg_handler_agent.c
|
||||
e2_agent_api.c
|
||||
plugin_agent.c
|
||||
not_handler_agent.c
|
||||
../sm/sm_proc_data.c
|
||||
)
|
||||
|
||||
if(E2AP_ENCODING STREQUAL "E2AP_ASN")
|
||||
|
||||
add_library(e2_agent STATIC ${E2_AGENT_SRC})
|
||||
target_link_libraries(e2_agent PRIVATE asn1_e2ap)
|
||||
|
||||
elseif(E2AP_ENCODING STREQUAL "E2AP_FLATBUFFERS")
|
||||
add_library(e2_agent ${E2_AGENT_BLD_LIB} #STATIC or SHARED
|
||||
${E2_AGENT_SRC}
|
||||
)
|
||||
|
||||
#bundle_static_library(e2_agent libflatccrt_d.a)
|
||||
|
||||
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Error, while compiling the agent" )
|
||||
endif()
|
||||
|
||||
|
||||
if(INCL_WHAT_YOU_USE)
|
||||
find_program(iwyu_path NAMES include-what-you-use iwyu REQUIRED)
|
||||
set_property(TARGET e2_agent PROPERTY C_INCLUDE_WHAT_YOU_USE ${iwyu_path})
|
||||
endif()
|
||||
|
||||
if(${E2AP_LIBRARY} STREQUAL "DYNAMIC" )
|
||||
target_link_libraries(e2_agent
|
||||
PUBLIC
|
||||
-pthread
|
||||
-lsctp
|
||||
-ldl
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
target_compile_definitions(e2_agent PRIVATE ${E2AP_ENCODING})
|
||||
|
||||
target_link_libraries(e2_agent PUBLIC
|
||||
e2ap_ap_obj
|
||||
e2ap_ep_obj
|
||||
pending_events_obj
|
||||
e2ap_types_obj
|
||||
e2ap_msg_enc_obj
|
||||
e2ap_msg_dec_obj
|
||||
e2ap_msg_free_obj
|
||||
)
|
||||
target_link_libraries(e2_agent PRIVATE alg ngran_types)
|
||||
target_link_libraries(e2_agent PUBLIC ds) # for byte_array_t
|
||||
|
||||
# list of SMs for which build should be triggered
|
||||
add_dependencies(e2_agent kpm_sm)
|
||||
141
openair2/E2AP/agent/asio_agent.c
Normal file
141
openair2/E2AP/agent/asio_agent.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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 "asio_agent.h"
|
||||
#include <assert.h> // for assert
|
||||
#include <errno.h> // for errno
|
||||
#include <fcntl.h> // for fcntl, F_GETFL, F_SETFL
|
||||
#include <stdio.h> // for NULL, fprintf, stderr
|
||||
#include <string.h> // for strerror
|
||||
#include <sys/epoll.h> // for epoll_event, epoll_ctl
|
||||
#include <sys/time.h> // for CLOCK_MONOTONIC
|
||||
#include <sys/timerfd.h> // for timerfd_create, timerfd_se...
|
||||
#include <sys/types.h> // for time_t
|
||||
#include <time.h> // for timespec, itimerspec
|
||||
#include <unistd.h> // for close
|
||||
|
||||
|
||||
static
|
||||
void set_fd_non_blocking(int sfd)
|
||||
{
|
||||
int flags = fcntl (sfd, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl (sfd, F_SETFL, flags);
|
||||
}
|
||||
|
||||
static
|
||||
int init_epoll(void)
|
||||
{
|
||||
const int flags = EPOLL_CLOEXEC;
|
||||
const int efd = epoll_create1(flags);
|
||||
assert(efd != -1);
|
||||
return efd;
|
||||
}
|
||||
|
||||
void init_asio_agent(asio_agent_t* io)
|
||||
{
|
||||
assert(io != NULL);
|
||||
|
||||
io->efd = init_epoll();
|
||||
set_fd_non_blocking(io->efd);
|
||||
}
|
||||
|
||||
void add_fd_asio_agent(asio_agent_t* io, int fd)
|
||||
{
|
||||
assert(io != NULL);
|
||||
const int op = EPOLL_CTL_ADD;
|
||||
const epoll_data_t e_data = {.fd = fd};
|
||||
const int e_events = EPOLLIN | EPOLLET; // open for reading and edge triggered instead of level triggered
|
||||
struct epoll_event event = {.events = e_events, .data = e_data};
|
||||
int rc = epoll_ctl(io->efd, op, fd, &event);
|
||||
assert(rc != -1);
|
||||
}
|
||||
|
||||
void rm_fd_asio_agent(asio_agent_t* io, int fd)
|
||||
{
|
||||
assert(io != NULL);
|
||||
const int op = EPOLL_CTL_DEL;
|
||||
const epoll_data_t e_data = {.fd = fd};
|
||||
const int e_events = EPOLLIN; // open for reading
|
||||
struct epoll_event event = {.events = e_events, .data = e_data};
|
||||
int rc = epoll_ctl(io->efd, op, fd, &event);
|
||||
assert(rc != -1);
|
||||
rc = close(fd);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
int create_timer_ms_asio_agent(asio_agent_t* io, long initial_ms, long interval_ms)
|
||||
{
|
||||
assert(io != NULL);
|
||||
assert(initial_ms > -1);
|
||||
assert(interval_ms > -1);
|
||||
|
||||
// Create the timer
|
||||
const int clockid = CLOCK_MONOTONIC;
|
||||
const int flags = TFD_NONBLOCK | TFD_CLOEXEC;
|
||||
const int tfd = timerfd_create(clockid, flags);
|
||||
assert(tfd != -1);
|
||||
|
||||
const time_t initial_sec = initial_ms / 1000;
|
||||
const long initial_nsec = (initial_ms * 1000000) % 1000000000;
|
||||
/* Initial expiration */
|
||||
const struct timespec it_value = {.tv_sec = initial_sec, .tv_nsec = initial_nsec};
|
||||
|
||||
const time_t interval_sec = interval_ms / 1000;
|
||||
const long interval_nsec = (interval_ms * 1000000) % 1000000000;
|
||||
/* Interval for periodic timer */
|
||||
const struct timespec it_interval = {.tv_sec = interval_sec, .tv_nsec = interval_nsec};
|
||||
|
||||
const int flags_2 = 0;
|
||||
struct itimerspec *old_value = NULL; // not interested in how the timer was previously configured
|
||||
const struct itimerspec new_value = {.it_interval = it_interval, .it_value = it_value};
|
||||
int rc = timerfd_settime(tfd, flags_2, &new_value, old_value);
|
||||
assert(rc != -1);
|
||||
|
||||
add_fd_asio_agent(io, tfd);
|
||||
return tfd;
|
||||
}
|
||||
|
||||
int event_asio_agent(asio_agent_t const* io)
|
||||
{
|
||||
assert(io != NULL);
|
||||
|
||||
const int maxevents = 1;
|
||||
struct epoll_event events[maxevents];
|
||||
const int timeout_ms = 1000;
|
||||
|
||||
const int events_ready = epoll_wait(io->efd, events, maxevents, timeout_ms);
|
||||
if (events_ready < 0) {
|
||||
fprintf(stderr, "epoll_wait() returned -1: errno %d, %s\n", errno, strerror(errno));
|
||||
assert(0);
|
||||
}
|
||||
assert(events_ready == 0 || events_ready == 1);
|
||||
if(events_ready == 0)
|
||||
return -1;
|
||||
|
||||
// Max. one event ready
|
||||
assert((events[0].events & EPOLLERR) == 0);
|
||||
return events[0].data.fd;
|
||||
}
|
||||
|
||||
|
||||
57
openair2/E2AP/agent/asio_agent.h
Normal file
57
openair2/E2AP/agent/asio_agent.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 ASYNC_INPUT_OUTPUT_AGENT_H
|
||||
#define ASYNC_INPUT_OUTPUT_AGENT_H
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
// epoll based fd
|
||||
int efd;
|
||||
|
||||
} asio_agent_t;
|
||||
|
||||
/*
|
||||
typedef enum
|
||||
{
|
||||
NET_PKT_ASIO_EVENT,
|
||||
IND_MSG_ASIO_EVENT,
|
||||
PENDING_TIMEOUT_EVENT,
|
||||
} asio_ev_t ;
|
||||
*/
|
||||
|
||||
void init_asio_agent(asio_agent_t* io);
|
||||
|
||||
void add_fd_asio_agent(asio_agent_t* io, int fd);
|
||||
|
||||
void rm_fd_asio_agent(asio_agent_t* io, int fd);
|
||||
|
||||
int create_timer_ms_asio_agent(asio_agent_t* io, long initial_ms, long interval_ms);
|
||||
|
||||
int event_asio_agent(asio_agent_t const* io);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
520
openair2/E2AP/agent/e2_agent.c
Normal file
520
openair2/E2AP/agent/e2_agent.c
Normal file
@@ -0,0 +1,520 @@
|
||||
/*
|
||||
* 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 "asio_agent.h"
|
||||
#include "e2_agent.h"
|
||||
#include "endpoint_agent.h"
|
||||
#include "msg_handler_agent.h"
|
||||
#include "not_handler_agent.h"
|
||||
#include "lib/async_event.h"
|
||||
#include "lib/v1/ap/e2ap_ap.h"
|
||||
#include "lib/v1/ap/free/e2ap_msg_free.h"
|
||||
//#include "sm/mac_sm/mac_sm_agent.h"
|
||||
//#include "sm/rlc_sm/rlc_sm_agent.h"
|
||||
#include "alg.h"
|
||||
#include "util/compare.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static
|
||||
e2_setup_request_t generate_setup_request(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
|
||||
const size_t len_rf = assoc_size(&ag->plugin.sm_ds);
|
||||
assert(len_rf > 0 && "No RAN function/service model registered. Check if the Service Models are located at shared library paths, default location is /usr/local/flexric/");
|
||||
|
||||
ran_function_t* ran_func = calloc(len_rf, sizeof(*ran_func));
|
||||
assert(ran_func != NULL);
|
||||
|
||||
e2_setup_request_t sr = {
|
||||
.id = ag->global_e2_node_id,
|
||||
.ran_func_item = ran_func,
|
||||
.len_rf = len_rf,
|
||||
.comp_conf_update = NULL,
|
||||
.len_ccu = 0
|
||||
};
|
||||
|
||||
void* it = assoc_front(&ag->plugin.sm_ds);
|
||||
for(size_t i = 0; i < len_rf; ++i){
|
||||
sm_agent_t* sm = assoc_value( &ag->plugin.sm_ds, it);
|
||||
assert(sm->ran_func_id == *(uint16_t*)assoc_key(&ag->plugin.sm_ds, it) && "RAN function mismatch");
|
||||
|
||||
ran_func[i].id = sm->ran_func_id;
|
||||
ran_func[i].rev = 0;
|
||||
ran_func[i].oid = NULL;
|
||||
|
||||
sm_e2_setup_t def = sm->proc.on_e2_setup(sm);
|
||||
byte_array_t ba = {.len = def.len_rfd, .buf = def.ran_fun_def};
|
||||
ran_func[i].def = ba;
|
||||
|
||||
it = assoc_next(&ag->plugin.sm_ds ,it);
|
||||
}
|
||||
assert(it == assoc_end(&ag->plugin.sm_ds) && "Length mismatch");
|
||||
return sr;
|
||||
}
|
||||
|
||||
static
|
||||
ric_indication_t generate_indication(e2_agent_t* ag, sm_ind_data_t* data, ind_event_t* i_ev)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(data != NULL);
|
||||
assert(i_ev != NULL);
|
||||
|
||||
ric_indication_t ind = {
|
||||
.ric_id = i_ev->ric_id,
|
||||
.action_id = i_ev->action_id,
|
||||
.sn = NULL,
|
||||
.type = RIC_IND_REPORT };
|
||||
|
||||
ind.hdr.len = data->len_hdr;
|
||||
ind.hdr.buf = data->ind_hdr;
|
||||
ind.msg.len = data->len_msg;
|
||||
ind.msg.buf = data->ind_msg;
|
||||
if(data->call_process_id != NULL){
|
||||
ind.call_process_id = malloc(sizeof(data->len_cpid) );
|
||||
assert(ind.call_process_id != NULL && "Memory exhausted" );
|
||||
ind.call_process_id->buf = data->call_process_id;
|
||||
ind.call_process_id->len = data->len_cpid;
|
||||
}
|
||||
return ind;
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
void free_fd(void* key, void* value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(value != NULL);
|
||||
int* fd = (int*) key;
|
||||
assert(*fd > 0 );
|
||||
free(value);
|
||||
}
|
||||
|
||||
static inline
|
||||
void free_pending_ev(void* key, void* value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(value != NULL);
|
||||
pending_event_t* ev = (pending_event_t*)key;
|
||||
assert(valid_pending_event(*ev));
|
||||
free(value);
|
||||
}
|
||||
|
||||
static inline
|
||||
void free_pending_agent(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
bi_map_free(&ag->pending);
|
||||
}
|
||||
|
||||
static inline
|
||||
void free_indication_event(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
bi_map_free(&ag->ind_event);
|
||||
}
|
||||
|
||||
static inline
|
||||
void init_pending_events(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
size_t fd_sz = sizeof(int);
|
||||
size_t event_sz = sizeof( pending_event_t );
|
||||
bi_map_init(&ag->pending, fd_sz, event_sz, cmp_fd, cmp_pending_event, free_fd, free_pending_ev );
|
||||
}
|
||||
|
||||
static inline
|
||||
void free_ind_event(void* key, void* value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(value != NULL);
|
||||
|
||||
(void)key;
|
||||
|
||||
ind_event_t* ev = (ind_event_t* )value;
|
||||
free(ev);
|
||||
}
|
||||
|
||||
static inline
|
||||
void free_key(void* key, void* value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(value != NULL);
|
||||
|
||||
(void)key;
|
||||
|
||||
int* fd = (int* )value;
|
||||
free(fd);
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
void init_indication_event(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
size_t key_sz_fd = sizeof(int);
|
||||
size_t key_sz_ind = sizeof(ind_event_t);
|
||||
|
||||
bi_map_init(&ag->ind_event, key_sz_fd, key_sz_ind, cmp_fd, cmp_ind_event, free_ind_event, free_key);
|
||||
}
|
||||
|
||||
static inline
|
||||
void* ind_fd(e2_agent_t* ag, int fd)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(fd > 0);
|
||||
|
||||
void* start_it = assoc_front(&ag->ind_event.left);
|
||||
void* end_it = assoc_end(&ag->ind_event.left);
|
||||
|
||||
void* it = find_if(&ag->ind_event.left, start_it, end_it, &fd, eq_fd );
|
||||
return it;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool net_pkt(const e2_agent_t* ag, int fd)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(fd > 0);
|
||||
return fd == ag->ep.base.fd;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool ind_event(e2_agent_t* ag, int fd, ind_event_t** i_ev)
|
||||
{
|
||||
assert(*i_ev == NULL);
|
||||
void* it = ind_fd(ag, fd);
|
||||
void* end_it = assoc_end(&ag->ind_event.left); // bi_map_end_left(&ag->ind_event);
|
||||
if(it != end_it){
|
||||
*i_ev = assoc_value(&ag->ind_event.left, it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool pend_event(e2_agent_t* ag, int fd, pending_event_t** p_ev)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(fd > 0);
|
||||
assert(*p_ev == NULL);
|
||||
|
||||
assert(bi_map_size(&ag->pending) == 1 );
|
||||
|
||||
void* start_it = assoc_front(&ag->pending.left);
|
||||
void* end_it = assoc_end(&ag->pending.left);
|
||||
|
||||
void* it = find_if(&ag->pending.left,start_it, end_it, &fd, eq_fd);
|
||||
|
||||
assert(it != end_it);
|
||||
*p_ev = assoc_value(&ag->pending.left ,it);
|
||||
return *p_ev != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
static
|
||||
async_event_t find_event_type(e2_agent_t* ag, int fd)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(fd > 0);
|
||||
async_event_t e = {.type = UNKNOWN_EVENT };
|
||||
if (net_pkt(ag, fd) == true){
|
||||
e.type = NETWORK_EVENT;
|
||||
} else if (ind_event(ag, fd, &e.i_ev) == true) {
|
||||
e.type = INDICATION_EVENT;
|
||||
} else if (pend_event(ag, fd, &e.p_ev) == true){
|
||||
e.type = PENDING_EVENT;
|
||||
} else{
|
||||
assert("Unknown event happened!");
|
||||
}
|
||||
return e;
|
||||
}
|
||||
*/
|
||||
|
||||
static
|
||||
void consume_fd(int fd)
|
||||
{
|
||||
assert(fd > 0);
|
||||
uint64_t read_buf = 0;
|
||||
ssize_t const bytes = read(fd,&read_buf, sizeof(read_buf));
|
||||
assert(bytes == sizeof(read_buf));
|
||||
}
|
||||
|
||||
static
|
||||
async_event_t next_async_event_agent(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
|
||||
int const fd = event_asio_agent(&ag->io);
|
||||
|
||||
async_event_t e = {.type = UNKNOWN_EVENT,
|
||||
.fd = fd};
|
||||
|
||||
if(fd == -1){ // no event happened. Just for checking the stop_token condition
|
||||
e.type = CHECK_STOP_TOKEN_EVENT;
|
||||
} else if (net_pkt(ag, fd) == true){
|
||||
|
||||
e.msg = e2ap_recv_msg_agent(&ag->ep);
|
||||
if(e.msg.type == SCTP_MSG_NOTIFICATION){
|
||||
e.type = SCTP_CONNECTION_SHUTDOWN_EVENT;
|
||||
} else if (e.msg.type == SCTP_MSG_PAYLOAD){
|
||||
e.type = SCTP_MSG_ARRIVED_EVENT;
|
||||
} else {
|
||||
assert(0!=0 && "Unknown type");
|
||||
}
|
||||
|
||||
} else if (ind_event(ag, fd, &e.i_ev) == true) {
|
||||
e.type = INDICATION_EVENT;
|
||||
} else if (pend_event(ag, fd, &e.p_ev) == true){
|
||||
e.type = PENDING_EVENT;
|
||||
} else {
|
||||
assert(0!=0 && "Unknown event happened!");
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
static
|
||||
void e2_event_loop_agent(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
while(ag->stop_token == false){
|
||||
|
||||
async_event_t e = next_async_event_agent(ag);
|
||||
assert(e.type != UNKNOWN_EVENT && "Unknown event triggered ");
|
||||
|
||||
switch(e.type){
|
||||
case SCTP_MSG_ARRIVED_EVENT:
|
||||
{
|
||||
defer({free_sctp_msg(&e.msg);});
|
||||
|
||||
e2ap_msg_t msg = e2ap_msg_dec_ag(&ag->ap, e.msg.ba);
|
||||
defer( { e2ap_msg_free_ag(&ag->ap, &msg);} );
|
||||
|
||||
e2ap_msg_t ans = e2ap_msg_handle_agent(ag, &msg);
|
||||
defer( { e2ap_msg_free_ag(&ag->ap, &ans);} );
|
||||
|
||||
if(ans.type != NONE_E2_MSG_TYPE){
|
||||
byte_array_t ba_ans = e2ap_msg_enc_ag(&ag->ap, &ans);
|
||||
defer ({free_byte_array(ba_ans); } );
|
||||
|
||||
e2ap_send_bytes_agent(&ag->ep, ba_ans);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case INDICATION_EVENT:
|
||||
{
|
||||
sm_agent_t* sm = e.i_ev->sm;
|
||||
sm_ind_data_t data = sm->proc.on_indication(sm);
|
||||
|
||||
ric_indication_t ind = generate_indication(ag, &data, e.i_ev);
|
||||
defer({ e2ap_free_indication(&ind); } );
|
||||
|
||||
byte_array_t ba = e2ap_enc_indication_ag(&ag->ap, &ind);
|
||||
defer({ free_byte_array(ba); } );
|
||||
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
|
||||
consume_fd(e.fd);
|
||||
|
||||
break;
|
||||
}
|
||||
case PENDING_EVENT:
|
||||
{
|
||||
assert(*e.p_ev == SETUP_REQUEST_PENDING_EVENT && "Unforeseen pending event happened!" );
|
||||
|
||||
// Resend the subscription request message
|
||||
e2_setup_request_t sr = generate_setup_request(ag);
|
||||
defer({ e2ap_free_setup_request(&sr); } );
|
||||
|
||||
printf("[E2AP] Resending Setup Request after timeout\n");
|
||||
byte_array_t ba = e2ap_enc_setup_request_ag(&ag->ap, &sr);
|
||||
defer({ free_byte_array(ba); } );
|
||||
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
|
||||
consume_fd(e.fd);
|
||||
|
||||
break;
|
||||
}
|
||||
case SCTP_CONNECTION_SHUTDOWN_EVENT:
|
||||
{
|
||||
notification_handle_ag(ag, &e.msg);
|
||||
break;
|
||||
}
|
||||
case CHECK_STOP_TOKEN_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(0!=0 && "Unknown event happened");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("ag->agent_stopped = true \n");
|
||||
ag->agent_stopped = true;
|
||||
}
|
||||
|
||||
e2_agent_t* e2_init_agent(const char* addr, int port, global_e2_node_id_t ge2nid, sm_io_ag_t io, const char* libs_dir)
|
||||
{
|
||||
assert(addr != NULL);
|
||||
assert(port > 0 && port < 65535);
|
||||
|
||||
printf("[E2 AGENT]: Initializing ... \n");
|
||||
|
||||
e2_agent_t* ag = calloc(1, sizeof(*ag));
|
||||
assert(ag != NULL && "Memory exhausted");
|
||||
|
||||
e2ap_init_ep_agent(&ag->ep, addr, port);
|
||||
|
||||
init_asio_agent(&ag->io);
|
||||
|
||||
add_fd_asio_agent(&ag->io, ag->ep.base.fd);
|
||||
|
||||
init_ap(&ag->ap.base.type);
|
||||
|
||||
init_handle_msg_agent(&ag->handle_msg);
|
||||
|
||||
init_plugin_ag(&ag->plugin, libs_dir, io);
|
||||
|
||||
init_pending_events(ag);
|
||||
|
||||
init_indication_event(ag);
|
||||
|
||||
ag->global_e2_node_id = ge2nid;
|
||||
ag->stop_token = false;
|
||||
ag->agent_stopped = false;
|
||||
|
||||
return ag;
|
||||
}
|
||||
|
||||
|
||||
void e2_start_agent(e2_agent_t* ag)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
|
||||
// Resend the subscription request message
|
||||
e2_setup_request_t sr = generate_setup_request(ag);
|
||||
defer({ e2ap_free_setup_request(&sr); } );
|
||||
|
||||
printf("[E2-AGENT]: Sending setup request\n");
|
||||
byte_array_t ba = e2ap_enc_setup_request_ag(&ag->ap, &sr);
|
||||
defer({free_byte_array(ba); } );
|
||||
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
|
||||
// A pending event is created along with a timer of 3000 ms,
|
||||
// after which an event will be generated
|
||||
pending_event_t ev = SETUP_REQUEST_PENDING_EVENT;
|
||||
long const wait_ms = 3000;
|
||||
int fd_timer = create_timer_ms_asio_agent(&ag->io, wait_ms, wait_ms);
|
||||
//printf("fd_timer with value created == %d\n", fd_timer);
|
||||
|
||||
bi_map_insert(&ag->pending, &fd_timer, sizeof(fd_timer), &ev, sizeof(ev));
|
||||
|
||||
e2_event_loop_agent(ag);
|
||||
}
|
||||
|
||||
void e2_free_agent(e2_agent_t* ag)
|
||||
{
|
||||
ag->stop_token = true;
|
||||
while(ag->agent_stopped == false){
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
free_plugin_ag(&ag->plugin);
|
||||
|
||||
free_pending_agent(ag);
|
||||
|
||||
free_indication_event(ag);
|
||||
|
||||
free(ag);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
/////////////////////////////////
|
||||
|
||||
void e2_send_subscription_response(e2_agent_t* ag, const ric_subscription_response_t* sr)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(sr != NULL);
|
||||
|
||||
byte_array_t ba = e2ap_enc_subscription_response_ag(&ag->ap, sr);
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
void e2_send_subscription_failure(e2_agent_t* ag, const ric_subscription_failure_t* sf)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(sf != NULL);
|
||||
|
||||
byte_array_t ba = e2ap_enc_subscription_failure_ag(&ag->ap, sf);
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
void e2_send_indication_agent(e2_agent_t* ag, const ric_indication_t* indication)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(indication != NULL);
|
||||
|
||||
byte_array_t ba = e2ap_enc_indication_ag(&ag->ap, indication);
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
void e2_send_subscription_delete_response(e2_agent_t* ag, const ric_subscription_delete_response_t* sdr)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(sdr != NULL);
|
||||
byte_array_t ba = e2ap_enc_subscription_delete_response_ag(&ag->ap, sdr);
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
void e2_send_subscription_delete_failure(e2_agent_t* ag, const ric_subscription_delete_failure_t* sdf)
|
||||
{
|
||||
byte_array_t ba = e2ap_enc_subscription_delete_failure_ag(&ag->ap, sdf );
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
void e2_send_control_acknowledge(e2_agent_t* ag, const ric_control_acknowledge_t* ca)
|
||||
{
|
||||
byte_array_t ba = e2ap_enc_control_acknowledge_ag(&ag->ap, ca);
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
void e2_send_control_failure(e2_agent_t* ag, const ric_control_failure_t* cf)
|
||||
{
|
||||
byte_array_t ba = e2ap_enc_control_failure_ag(&ag->ap, cf);
|
||||
e2ap_send_bytes_agent(&ag->ep, ba);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
|
||||
100
openair2/E2AP/agent/e2_agent.h
Normal file
100
openair2/E2AP/agent/e2_agent.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 E2_AGENT_H
|
||||
#define E2_AGENT_H
|
||||
|
||||
#include "assoc_container/assoc_generic.h"
|
||||
#include "assoc_container/bimap.h"
|
||||
|
||||
#include "common/ngran_types.h"
|
||||
|
||||
#include "lib/v1/ap/global_consts.h"
|
||||
#include "lib/v1/ap/type_defs.h"
|
||||
|
||||
#include "asio_agent.h"
|
||||
#include "e2ap_agent.h"
|
||||
#include "endpoint_agent.h"
|
||||
#include "plugin_agent.h"
|
||||
#include "sm/sm_io.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct e2_agent_s e2_agent_t;
|
||||
|
||||
typedef e2ap_msg_t (*handle_msg_fp_agent)(struct e2_agent_s*, const e2ap_msg_t* msg) ;
|
||||
|
||||
typedef struct e2_agent_s
|
||||
{
|
||||
e2ap_ep_ag_t ep;
|
||||
e2ap_agent_t ap;
|
||||
asio_agent_t io;
|
||||
handle_msg_fp_agent handle_msg[30]; // 26 E2AP + 4 E42AP note that not all the slots will be occupied
|
||||
|
||||
// Registered SMs
|
||||
plugin_ag_t plugin;
|
||||
|
||||
// Registered Indication events
|
||||
bi_map_t ind_event; // key1:fd, key2:ind_event_t
|
||||
|
||||
// Pending events
|
||||
bi_map_t pending; // left: fd, right: pending_event_t
|
||||
|
||||
global_e2_node_id_t global_e2_node_id;
|
||||
|
||||
atomic_bool stop_token;
|
||||
atomic_bool agent_stopped;
|
||||
} e2_agent_t;
|
||||
|
||||
e2_agent_t* e2_init_agent(const char* addr, int port, global_e2_node_id_t ge2nid, sm_io_ag_t io, const char* libs_dir);
|
||||
|
||||
// Blocking call
|
||||
void e2_start_agent(e2_agent_t* ag);
|
||||
|
||||
void e2_free_agent(e2_agent_t* ag);
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// E2AP AGENT FUNCTIONAL PROCEDURES MESSAGES //
|
||||
///////////////////////////////////////////////
|
||||
|
||||
void e2_send_subscription_response(e2_agent_t* ag, const ric_subscription_response_t* sr);
|
||||
|
||||
void e2_send_subscription_failure(e2_agent_t* ag, const ric_subscription_failure_t* sf);
|
||||
|
||||
void e2_send_subscription_delete_response(e2_agent_t* ag, const ric_subscription_delete_response_t* sdr);
|
||||
|
||||
void e2_send_subscription_delete_failure(e2_agent_t* ag, const ric_subscription_delete_failure_t* sdf);
|
||||
|
||||
void e2_send_indication_agent(e2_agent_t* ag, const ric_indication_t* indication);
|
||||
|
||||
void e2_send_control_acknowledge(e2_agent_t* ag, const ric_control_acknowledge_t* ca);
|
||||
|
||||
void e2_send_control_failure(e2_agent_t* ag, const ric_control_failure_t* cf);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
91
openair2/E2AP/agent/e2_agent_api.c
Normal file
91
openair2/E2AP/agent/e2_agent_api.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 "e2_agent_api.h"
|
||||
|
||||
#include <assert.h> // for assert
|
||||
#include <pthread.h> // for pthread_cr...
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h> // for NULL
|
||||
#include "e2_agent.h" // for e2_free_agent
|
||||
#include "lib/v1/ap/e2ap_types/common/e2ap_global_node_id.h" // for global_e2_...
|
||||
#include "lib/v1/ap/e2ap_types/common/e2ap_plmn.h" // for plmn_t
|
||||
#include "common/ngran_types.h" // for ngran_gNB
|
||||
|
||||
|
||||
static
|
||||
e2_agent_t* agent = NULL;
|
||||
|
||||
static
|
||||
pthread_t thrd_agent;
|
||||
|
||||
static inline
|
||||
void* static_start_agent(void* a)
|
||||
{
|
||||
(void)a;
|
||||
// Blocking...
|
||||
e2_start_agent(agent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void init_agent_api(int mcc, int mnc, int mnc_digit_len, int nb_id, int cu_du_id, ngran_node_t ran_type, sm_io_ag_t io, e2_agent_args_t const* args)
|
||||
{
|
||||
assert(agent == NULL);
|
||||
assert(mcc > 0);
|
||||
assert(mnc > 0);
|
||||
assert(mnc_digit_len > 0);
|
||||
assert(nb_id > 0);
|
||||
assert(ran_type >= 0);
|
||||
|
||||
const plmn_t plmn = {.mcc = mcc, .mnc = mnc, .mnc_digit_len = mnc_digit_len};
|
||||
global_e2_node_id_t ge2ni = {.type = ran_type, .plmn = plmn, .nb_id = nb_id, .cu_du_id = NULL};
|
||||
|
||||
char* ran_type_str = get_ngran_name(ran_type);
|
||||
if (NODE_IS_MONOLITHIC(ran_type)) {
|
||||
printf("[E2 AGENT]: nearRT-RIC IP Address = %s, PORT = %d, RAN type = %s, nb_id = %d\n", args->ip, args->port, ran_type_str, nb_id);
|
||||
} else if (NODE_IS_CU(ran_type) || NODE_IS_DU(ran_type)) {
|
||||
assert(cu_du_id > 0);
|
||||
ge2ni.cu_du_id = calloc(1, sizeof(uint64_t));
|
||||
assert(ge2ni.cu_du_id != NULL && "memory exhausted");
|
||||
*ge2ni.cu_du_id = cu_du_id;
|
||||
printf("[E2 AGENT]: nearRT-RIC IP Address = %s, PORT = %d, RAN type = %s, nb_id = %d, cu_du_id = %ld\n", args->ip, args->port, ran_type_str, nb_id, *ge2ni.cu_du_id);
|
||||
} else {
|
||||
assert(0 != 0 && "not support RAN type\n");
|
||||
}
|
||||
|
||||
agent = e2_init_agent(args->ip, args->port, ge2ni, io, args->sm_dir);
|
||||
|
||||
// Spawn a new thread for the agent
|
||||
const int rc = pthread_create(&thrd_agent, NULL, static_start_agent, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void stop_agent_api(void)
|
||||
{
|
||||
assert(agent != NULL);
|
||||
e2_free_agent(agent);
|
||||
int const rc = pthread_join(thrd_agent,NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
|
||||
40
openair2/E2AP/agent/e2_agent_api.h
Normal file
40
openair2/E2AP/agent/e2_agent_api.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 E2_AGENT_API_MOSAIC_H
|
||||
#define E2_AGENT_API_MOSAIC_H
|
||||
|
||||
#include "sm/sm_io.h"
|
||||
#include "common/ngran_types.h"
|
||||
|
||||
typedef struct {
|
||||
const char *ip;
|
||||
uint16_t port;
|
||||
const char *sm_dir;
|
||||
} e2_agent_args_t;
|
||||
|
||||
void init_agent_api(int mcc, int mnc, int mnc_digit_len, int nb_id, int cu_du_id, ngran_node_t ran_type, sm_io_ag_t io, e2_agent_args_t const *args);
|
||||
void stop_agent_api(void);
|
||||
|
||||
#endif
|
||||
|
||||
128
openair2/E2AP/agent/e2ap_agent.c
Normal file
128
openair2/E2AP/agent/e2ap_agent.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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 "e2ap_agent.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lib/v1/ap/type_defs.h"
|
||||
#include "lib/v1/ap/enc/e2ap_msg_enc_generic.h"
|
||||
#include "lib/v1/ap/dec/e2ap_msg_dec_generic.h"
|
||||
//#include "lib/ap/free/e2ap_msg_free.h"
|
||||
|
||||
|
||||
void e2ap_msg_free_ag(e2ap_agent_t* ap, e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(msg != NULL);
|
||||
e2_msg_type_t const msg_type = msg->type;
|
||||
if(msg_type == NONE_E2_MSG_TYPE) // Nothing to free
|
||||
return;
|
||||
assert(msg_type < NONE_E2_MSG_TYPE);
|
||||
ap->base.type.free_msg[msg_type](msg);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Encoding
|
||||
//
|
||||
|
||||
|
||||
byte_array_t e2ap_msg_enc_ag(e2ap_agent_t* ap, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(msg != NULL);
|
||||
e2_msg_type_t const msg_type = msg->type ;
|
||||
assert(msg_type < NONE_E2_MSG_TYPE);
|
||||
return ap->base.type.enc_msg[msg_type](msg);
|
||||
}
|
||||
|
||||
|
||||
byte_array_t e2ap_enc_setup_request_ag(e2ap_agent_t* ap, e2_setup_request_t* sr)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(sr != NULL);
|
||||
return e2ap_enc_setup_request_gen(&ap->base.type, sr);
|
||||
}
|
||||
|
||||
byte_array_t e2ap_enc_subscription_response_ag(e2ap_agent_t* ap, const ric_subscription_response_t* sr)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(sr != NULL);
|
||||
return e2ap_enc_subscription_response_gen(&ap->base.type, sr);
|
||||
}
|
||||
|
||||
byte_array_t e2ap_enc_subscription_failure_ag(e2ap_agent_t* ap,const ric_subscription_failure_t* sf)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(sf != NULL);
|
||||
return e2ap_enc_subscription_failure_gen(&ap->base.type,sf);
|
||||
}
|
||||
|
||||
byte_array_t e2ap_enc_indication_ag(e2ap_agent_t* ap, const ric_indication_t* ind)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(ind != NULL);
|
||||
return e2ap_enc_indication_gen(&ap->base.type, ind);
|
||||
}
|
||||
|
||||
byte_array_t e2ap_enc_subscription_delete_response_ag(e2ap_agent_t* ap, const ric_subscription_delete_response_t* sdr)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(sdr != NULL);
|
||||
return e2ap_enc_subscription_delete_response_gen(&ap->base.type, sdr);
|
||||
}
|
||||
|
||||
byte_array_t e2ap_enc_subscription_delete_failure_ag(e2ap_agent_t* ap, const ric_subscription_delete_failure_t* sdf)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(sdf != NULL);
|
||||
return e2ap_enc_subscription_delete_failure_gen(&ap->base.type, sdf);
|
||||
}
|
||||
|
||||
byte_array_t e2ap_enc_control_acknowledge_ag(e2ap_agent_t* ap, const ric_control_acknowledge_t* ca)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(ca != NULL);
|
||||
return e2ap_enc_control_acknowledge_gen(&ap->base.type, ca);
|
||||
}
|
||||
|
||||
byte_array_t e2ap_enc_control_failure_ag(e2ap_agent_t* ap, const ric_control_failure_t* cf)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(cf != NULL);
|
||||
return e2ap_enc_control_failure_gen(&ap->base.type, cf);
|
||||
}
|
||||
|
||||
//
|
||||
// Decoding
|
||||
//
|
||||
|
||||
e2ap_msg_t e2ap_msg_dec_ag(e2ap_agent_t* ap, byte_array_t ba)
|
||||
{
|
||||
assert(ap != NULL);
|
||||
assert(ba.buf != NULL);
|
||||
return e2ap_msg_dec_gen(&ap->base.type, ba);
|
||||
}
|
||||
|
||||
77
openair2/E2AP/agent/e2ap_agent.h
Normal file
77
openair2/E2AP/agent/e2ap_agent.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 E2AP_AGENT_H
|
||||
#define E2AP_AGENT_H
|
||||
|
||||
#include "lib/v1/ap/e2ap_ap.h" // for e2ap...
|
||||
#include "lib/v1/ap/e2ap_types/e2_setup_request.h" // for e2_s...
|
||||
#include "lib/v1/ap/e2ap_types/ric_control_ack.h" // for ric_...
|
||||
#include "lib/v1/ap/e2ap_types/ric_control_failure.h" // for ric_...
|
||||
#include "lib/v1/ap/e2ap_types/ric_indication.h" // for ric_...
|
||||
#include "lib/v1/ap/e2ap_types/ric_subscription_delete_failure.h" // for ric_...
|
||||
#include "lib/v1/ap/e2ap_types/ric_subscription_delete_response.h" // for ric_...
|
||||
#include "lib/v1/ap/e2ap_types/ric_subscription_failure.h" // for ric_...
|
||||
#include "lib/v1/ap/e2ap_types/ric_subscription_response.h" // for ric_...
|
||||
#include "lib/v1/ap/type_defs.h" // for e2ap...
|
||||
#include "byte_array.h" // for byte...
|
||||
|
||||
typedef struct e2ap_agent_s
|
||||
{
|
||||
e2ap_ap_t base;
|
||||
|
||||
} e2ap_agent_t;
|
||||
|
||||
void e2ap_msg_free_ag(e2ap_agent_t* ag, e2ap_msg_t* msg);
|
||||
|
||||
/////////////
|
||||
// Encoding
|
||||
//////////////
|
||||
|
||||
byte_array_t e2ap_msg_enc_ag(e2ap_agent_t* ap, const e2ap_msg_t* msg);
|
||||
|
||||
byte_array_t e2ap_enc_setup_request_ag(e2ap_agent_t* ap, e2_setup_request_t* sr);
|
||||
|
||||
byte_array_t e2ap_enc_subscription_response_ag(e2ap_agent_t* ap, const ric_subscription_response_t* sr);
|
||||
|
||||
byte_array_t e2ap_enc_subscription_failure_ag(e2ap_agent_t* ap,const ric_subscription_failure_t* sf);
|
||||
|
||||
byte_array_t e2ap_enc_indication_ag(e2ap_agent_t* ap, const ric_indication_t* ind);
|
||||
|
||||
byte_array_t e2ap_enc_subscription_delete_response_ag(e2ap_agent_t* ap, const ric_subscription_delete_response_t* sdr);
|
||||
|
||||
byte_array_t e2ap_enc_subscription_delete_failure_ag(e2ap_agent_t* ap, const ric_subscription_delete_failure_t* sdf);
|
||||
|
||||
byte_array_t e2ap_enc_control_acknowledge_ag(e2ap_agent_t* ap, const ric_control_acknowledge_t* ca);
|
||||
|
||||
byte_array_t e2ap_enc_control_failure_ag(e2ap_agent_t* ap, const ric_control_failure_t* cf);
|
||||
|
||||
|
||||
//
|
||||
// Decoding
|
||||
//
|
||||
|
||||
e2ap_msg_t e2ap_msg_dec_ag(e2ap_agent_t* ap, byte_array_t ba);
|
||||
|
||||
#endif
|
||||
|
||||
121
openair2/E2AP/agent/endpoint_agent.c
Normal file
121
openair2/E2AP/agent/endpoint_agent.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "endpoint_agent.h"
|
||||
#include <arpa/inet.h> // for inet_pton
|
||||
#include <assert.h> // for assert
|
||||
#include <netinet/sctp.h>
|
||||
#include <netinet/in.h> // for sockaddr_in, IPPROTO_SCTP, htonl, htons
|
||||
#include <stdio.h> // for NULL
|
||||
#include <stdlib.h> // for malloc
|
||||
#include <string.h> // for strlen, strncpy
|
||||
#include <strings.h> // for bzero
|
||||
#include <sys/socket.h> // for setsockopt, AF_INET, socket, SOCK_SEQPACKET
|
||||
#include "lib/ep/e2ap_ep.h" // for e2ap_ep_t, e2ap_recv_bytes, e2ap_send_bytes
|
||||
|
||||
static
|
||||
void init_sctp_conn_client(e2ap_ep_ag_t* ep, const char* addr, int port)
|
||||
{
|
||||
int sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
|
||||
assert(sock_fd != -1);
|
||||
|
||||
struct sockaddr_in servaddr = { .sin_family = AF_INET,
|
||||
.sin_port = htons(port),
|
||||
.sin_addr.s_addr = htonl(INADDR_ANY)};
|
||||
|
||||
int rc = inet_pton(AF_INET, addr, &servaddr.sin_addr);
|
||||
assert(rc == 1);
|
||||
|
||||
struct sctp_event_subscribe evnts = { .sctp_data_io_event = 1,
|
||||
.sctp_shutdown_event = 1};
|
||||
|
||||
rc = setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof (evnts));
|
||||
assert(rc == 0);
|
||||
|
||||
const int close_time = 0; // No automatic close https://www.rfc-editor.org/rfc/pdfrfc/rfc6458.txt.pdf p. 65
|
||||
rc = setsockopt(sock_fd, IPPROTO_SCTP, SCTP_AUTOCLOSE, &close_time, sizeof(close_time));
|
||||
assert(rc == 0);
|
||||
|
||||
const int no_delay = 1;
|
||||
rc = setsockopt(sock_fd, IPPROTO_SCTP, SCTP_NODELAY, &no_delay, sizeof(no_delay));
|
||||
assert(rc == 0);
|
||||
|
||||
ep->to = servaddr;
|
||||
*(int*)(&ep->base.port) = port;
|
||||
*(int*)(&ep->base.fd) = sock_fd;
|
||||
strncpy((char*)(&ep->base.addr), addr, 15);
|
||||
*(char*)(&ep->base.addr[15]) = 0;
|
||||
}
|
||||
|
||||
void e2ap_init_ep_agent(e2ap_ep_ag_t* ep, const char* addr, int port)
|
||||
{
|
||||
assert(ep != NULL);
|
||||
assert(addr != NULL);
|
||||
assert(strlen(addr) < 16);
|
||||
assert(port > 0 && port < 65535);
|
||||
init_sctp_conn_client(ep, addr, port);
|
||||
}
|
||||
|
||||
/*
|
||||
static
|
||||
bool eq_sockaddr(struct sockaddr_in* m0, struct sockaddr_in* m1)
|
||||
{
|
||||
assert(m0 != NULL);
|
||||
assert(m1 != NULL);
|
||||
|
||||
if(m0->sin_addr.s_addr != m1->sin_addr.s_addr)
|
||||
return false;
|
||||
|
||||
if(m0->sin_port != m1->sin_port)
|
||||
return false;
|
||||
|
||||
if(m0->sin_family != m1->sin_family)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
sctp_msg_t e2ap_recv_msg_agent(e2ap_ep_ag_t* ep)
|
||||
{
|
||||
assert(ep != NULL);
|
||||
|
||||
sctp_msg_t rcv = e2ap_recv_sctp_msg(&ep->base);// , &ba);
|
||||
return rcv;
|
||||
}
|
||||
|
||||
void e2ap_send_bytes_agent(e2ap_ep_ag_t* ep, byte_array_t ba)
|
||||
{
|
||||
assert(ep != NULL);
|
||||
assert(ba.buf && ba.len > 0);
|
||||
|
||||
sctp_msg_t msg = { .info.addr = ep->to,
|
||||
.info.sri = ep->sri,
|
||||
.ba = ba};
|
||||
|
||||
e2ap_send_sctp_msg(&ep->base, &msg);
|
||||
}
|
||||
|
||||
void e2ap_free_ep_agent(e2ap_ep_ag_t* ep)
|
||||
{
|
||||
assert(ep != NULL);
|
||||
assert(0!=0 && "Not implemented!");
|
||||
}
|
||||
50
openair2/E2AP/agent/endpoint_agent.h
Normal file
50
openair2/E2AP/agent/endpoint_agent.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 ENDPOINT_AGENT
|
||||
#define ENDPOINT_AGENT
|
||||
|
||||
#include "lib/ep/e2ap_ep.h" // for e2ap_ep_t
|
||||
#include "byte_array.h" // for byte_array_t
|
||||
|
||||
typedef struct e2ap_ep_ag
|
||||
{
|
||||
e2ap_ep_t base;
|
||||
|
||||
// Only one connection supported
|
||||
struct sockaddr_in to;
|
||||
struct sctp_sndrcvinfo sri;
|
||||
int msg_flags;
|
||||
|
||||
} e2ap_ep_ag_t;
|
||||
|
||||
|
||||
|
||||
void e2ap_init_ep_agent(e2ap_ep_ag_t* ep, const char* addr, int port);
|
||||
|
||||
void e2ap_free_ep_agent(e2ap_ep_ag_t* ep);
|
||||
|
||||
sctp_msg_t e2ap_recv_msg_agent(e2ap_ep_ag_t* ep);
|
||||
|
||||
void e2ap_send_bytes_agent(e2ap_ep_ag_t* ep, byte_array_t ba);
|
||||
|
||||
#endif
|
||||
|
||||
379
openair2/E2AP/agent/msg_handler_agent.c
Normal file
379
openair2/E2AP/agent/msg_handler_agent.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* 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 "msg_handler_agent.h"
|
||||
#include "lib/ind_event.h"
|
||||
#include "lib/pending_events.h"
|
||||
#include "sm/sm_agent.h"
|
||||
#include "alg.h"
|
||||
#include "util/compare.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static
|
||||
bool check_valid_msg_type(e2_msg_type_t msg_type )
|
||||
{
|
||||
return msg_type == RIC_SUBSCRIPTION_REQUEST
|
||||
|| msg_type == RIC_SUBSCRIPTION_DELETE_REQUEST
|
||||
|| msg_type == RIC_CONTROL_REQUEST
|
||||
|| msg_type == E2AP_ERROR_INDICATION
|
||||
|| msg_type == E2_SETUP_RESPONSE
|
||||
|| msg_type == E2_SETUP_FAILURE
|
||||
|| msg_type == E2AP_RESET_REQUEST
|
||||
|| msg_type == E2AP_RESET_RESPONSE
|
||||
|| msg_type == RIC_SERVICE_UPDATE_ACKNOWLEDGE
|
||||
|| msg_type == RIC_SERVICE_UPDATE_FAILURE
|
||||
|| msg_type == RIC_SERVICE_QUERY
|
||||
|| msg_type == E2_NODE_CONFIGURATION_UPDATE_ACKNOWLEDGE
|
||||
|| msg_type == E2_NODE_CONFIGURATION_UPDATE_FAILURE
|
||||
|| msg_type == E2_CONNECTION_UPDATE;
|
||||
}
|
||||
|
||||
static
|
||||
void stop_ind_event(e2_agent_t* ag, ric_gen_id_t id)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
ind_event_t tmp = {.ric_id = id, .sm = NULL, .action_id =0 };
|
||||
int* fd = bi_map_extract_right(&ag->ind_event, &tmp, sizeof(tmp) );
|
||||
assert(*fd > 0);
|
||||
//printf("fd value in stopping pending event = %d \n", *fd);
|
||||
rm_fd_asio_agent(&ag->io, *fd);
|
||||
free(fd);
|
||||
}
|
||||
|
||||
void init_handle_msg_agent(handle_msg_fp_agent (*handle_msg)[30])
|
||||
{
|
||||
memset((*handle_msg), 0, sizeof(handle_msg_fp_agent)*30);
|
||||
|
||||
(*handle_msg)[RIC_SUBSCRIPTION_REQUEST] = e2ap_handle_subscription_request_agent;
|
||||
(*handle_msg)[RIC_SUBSCRIPTION_DELETE_REQUEST] = e2ap_handle_subscription_delete_request_agent;
|
||||
(*handle_msg)[RIC_CONTROL_REQUEST] = e2ap_handle_control_request_agent;
|
||||
(*handle_msg)[E2AP_ERROR_INDICATION] = e2ap_handle_error_indication_agent;
|
||||
(*handle_msg)[E2_SETUP_RESPONSE] = e2ap_handle_setup_response_agent;
|
||||
(*handle_msg)[E2_SETUP_FAILURE] = e2ap_handle_setup_failure_agent;
|
||||
(*handle_msg)[E2AP_RESET_REQUEST] = e2ap_handle_reset_request_agent;
|
||||
(*handle_msg)[E2AP_RESET_RESPONSE] = e2ap_handle_reset_response_agent;
|
||||
(*handle_msg)[RIC_SERVICE_UPDATE_ACKNOWLEDGE] = e2ap_handle_service_update_ack_agent;
|
||||
(*handle_msg)[RIC_SERVICE_UPDATE_FAILURE] = e2ap_handle_service_update_failure_agent;
|
||||
(*handle_msg)[RIC_SERVICE_QUERY] = e2ap_handle_service_query_agent;
|
||||
(*handle_msg)[E2_NODE_CONFIGURATION_UPDATE_ACKNOWLEDGE] = e2ap_handle_node_configuration_update_ack_agent;
|
||||
(*handle_msg)[E2_NODE_CONFIGURATION_UPDATE_FAILURE] = e2ap_handle_node_configuration_update_failure_agent;
|
||||
(*handle_msg)[E2_CONNECTION_UPDATE] = e2ap_handle_connection_update_agent;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_msg_handle_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(msg != NULL);
|
||||
const e2_msg_type_t msg_type = msg->type;
|
||||
assert(check_valid_msg_type(msg_type) == true);
|
||||
assert(ag->handle_msg[ msg_type ] != NULL);
|
||||
return ag->handle_msg[msg_type](ag, msg);
|
||||
}
|
||||
|
||||
static inline
|
||||
bool supported_ric_subscription_request(ric_subscription_request_t const* sr)
|
||||
{
|
||||
assert(sr != NULL);
|
||||
assert(sr->len_action == 1 && "Only one action supported" );
|
||||
assert(sr->action->type == RIC_ACT_REPORT && "Only report supported" );
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
sm_subs_data_t generate_sm_subs_data( ric_subscription_request_t const* sr )
|
||||
{
|
||||
assert(sr != NULL);
|
||||
sm_subs_data_t data = { .event_trigger = sr->event_trigger.buf,
|
||||
.len_et = sr->event_trigger.len };
|
||||
if(sr->action->definition != NULL){
|
||||
data.action_def = sr->action->definition->buf;
|
||||
data.len_ad = sr->action->definition->len;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static
|
||||
ric_subscription_response_t generate_subscription_response(ric_gen_id_t const* ric_id, uint8_t ric_act_id)
|
||||
{
|
||||
ric_subscription_response_t sr = {
|
||||
.ric_id = *ric_id,
|
||||
.not_admitted = 0,
|
||||
.len_na = 0,
|
||||
};
|
||||
sr.admitted = calloc(1, sizeof(ric_action_admitted_t));
|
||||
assert(sr.admitted != NULL && "Memory exahusted");
|
||||
sr.admitted->ric_act_id = ric_act_id;
|
||||
sr.len_admitted = 1;
|
||||
|
||||
return sr;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_subscription_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(msg->type == RIC_SUBSCRIPTION_REQUEST);
|
||||
printf("[E2-AGENT]: RIC_SUBSCRIPTION_REQUEST rx\n");
|
||||
|
||||
ric_subscription_request_t const* sr = &msg->u_msgs.ric_sub_req;
|
||||
assert(supported_ric_subscription_request(sr) == true);
|
||||
|
||||
sm_subs_data_t data = generate_sm_subs_data(sr);
|
||||
uint16_t const ran_func_id = sr->ric_id.ran_func_id;
|
||||
sm_agent_t* sm = sm_plugin_ag(&ag->plugin, ran_func_id);
|
||||
subscribe_timer_t t = sm->proc.on_subscription(sm, &data);
|
||||
int fd_timer = create_timer_ms_asio_agent(&ag->io, t.ms, t.ms);
|
||||
//printf("fd_timer for subscription value created == %d\n", fd_timer);
|
||||
|
||||
// Register the indication event
|
||||
ind_event_t ev;
|
||||
ev.action_id = sr->action[0].id;
|
||||
ev.ric_id = sr->ric_id;
|
||||
ev.sm = sm;
|
||||
bi_map_insert(&ag->ind_event, &fd_timer, sizeof(fd_timer), &ev, sizeof(ev));
|
||||
|
||||
uint8_t const ric_act_id = sr->action[0].id;
|
||||
e2ap_msg_t ans = {.type = RIC_SUBSCRIPTION_RESPONSE,
|
||||
.u_msgs.ric_sub_resp = generate_subscription_response(&sr->ric_id, ric_act_id) };
|
||||
return ans;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool eq_ind_event(const void* value, const void* key)
|
||||
{
|
||||
assert(value != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
ric_gen_id_t* ric_id = (ric_gen_id_t*)value;
|
||||
ind_event_t* ind_ev = (ind_event_t*)key;
|
||||
return eq_ric_gen_id(ric_id, &ind_ev->ric_id );
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_subscription_delete_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(msg->type == RIC_SUBSCRIPTION_DELETE_REQUEST);
|
||||
printf("[E2-AGENT]: RIC_SUBSCRIPTION_DELETE_REQUEST rx\n");
|
||||
|
||||
const ric_subscription_delete_request_t* sdr = &msg->u_msgs.ric_sub_del_req;
|
||||
|
||||
stop_ind_event(ag, sdr->ric_id);
|
||||
|
||||
ric_subscription_delete_response_t sub_del = {.ric_id = sdr->ric_id };
|
||||
|
||||
e2ap_msg_t ans = {.type = RIC_SUBSCRIPTION_DELETE_RESPONSE};
|
||||
ans.u_msgs.ric_sub_del_resp = sub_del;
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
byte_array_t* ba_from_ctrl_out(sm_ctrl_out_data_t const* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
byte_array_t* ba = NULL;
|
||||
|
||||
size_t const sz = data->len_out;
|
||||
if(sz > 0){
|
||||
ba = malloc(sizeof(byte_array_t ) ) ;
|
||||
assert(ba != NULL && "Memory exhausted!");
|
||||
|
||||
ba->len = sz;
|
||||
ba->buf = malloc(sz);
|
||||
assert(ba->buf != NULL && "Memory exhausted");
|
||||
memcpy(ba->buf, data->ctrl_out, sz);
|
||||
}
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
// The purpose of the RIC Control procedure is to initiate or resume a specific functionality in the E2 Node.
|
||||
e2ap_msg_t e2ap_handle_control_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(msg->type == RIC_CONTROL_REQUEST);
|
||||
|
||||
|
||||
ric_control_request_t const* ctrl_req = &msg->u_msgs.ric_ctrl_req;
|
||||
assert(ctrl_req->ack_req != NULL && *ctrl_req->ack_req == RIC_CONTROL_REQUEST_ACK );
|
||||
|
||||
sm_ctrl_req_data_t data = {.ctrl_hdr = ctrl_req->hdr.buf,
|
||||
.len_hdr = ctrl_req->hdr.len,
|
||||
.ctrl_msg = ctrl_req->msg.buf,
|
||||
.len_msg = ctrl_req->msg.len};
|
||||
|
||||
|
||||
uint16_t const ran_func_id = ctrl_req->ric_id.ran_func_id;
|
||||
sm_agent_t* sm = sm_plugin_ag(&ag->plugin, ran_func_id);
|
||||
|
||||
sm_ctrl_out_data_t ctrl_ans = sm->proc.on_control(sm, &data);
|
||||
defer({ free_sm_ctrl_out_data(&ctrl_ans); } );
|
||||
|
||||
|
||||
byte_array_t* ba_ctrl_ans = ba_from_ctrl_out(&ctrl_ans);
|
||||
|
||||
ric_control_acknowledge_t ric_ctrl_ack = {.ric_id = ctrl_req->ric_id,
|
||||
.call_process_id = NULL,
|
||||
.status = RIC_CONTROL_STATUS_SUCCESS,
|
||||
.control_outcome = ba_ctrl_ans } ;
|
||||
|
||||
|
||||
printf("[E2-AGENT]: CONTROL ACKNOWLEDGE sent\n");
|
||||
e2ap_msg_t ans = {.type = RIC_CONTROL_ACKNOWLEDGE};
|
||||
ans.u_msgs.ric_ctrl_ack = ric_ctrl_ack;
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_error_indication_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
void stop_pending_event(e2_agent_t* ag, pending_event_t event)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
int* fd = bi_map_extract_right(&ag->pending, &event, sizeof(event));
|
||||
assert(*fd > 0);
|
||||
printf("[E2-AGENT]: stopping pending\n");
|
||||
//event = %d \n", *fd);
|
||||
rm_fd_asio_agent(&ag->io, *fd);
|
||||
free(fd);
|
||||
}
|
||||
|
||||
|
||||
e2ap_msg_t e2ap_handle_setup_response_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(msg->type == E2_SETUP_RESPONSE);
|
||||
printf("[E2-AGENT]: SETUP-RESPONSE received\n");
|
||||
|
||||
// Stop the timer
|
||||
stop_pending_event(ag, SETUP_REQUEST_PENDING_EVENT);
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_setup_failure_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_reset_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_reset_response_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_service_update_ack_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_service_update_failure_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_service_query_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_node_configuration_update_ack_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_node_configuration_update_failure_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_handle_connection_update_agent(e2_agent_t* ag, const e2ap_msg_t* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {.type = NONE_E2_MSG_TYPE};
|
||||
return ans;
|
||||
}
|
||||
|
||||
95
openair2/E2AP/agent/msg_handler_agent.h
Normal file
95
openair2/E2AP/agent/msg_handler_agent.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 MSG_HANDLER_AGENT
|
||||
#define MSG_HANDLER_AGENT
|
||||
|
||||
#include "e2_agent.h"
|
||||
#include "lib/v1/ap/type_defs.h"
|
||||
|
||||
void init_handle_msg_agent(handle_msg_fp_agent (*handle_msg)[30]);
|
||||
|
||||
e2ap_msg_t e2ap_msg_handle_agent(e2_agent_t* agent, const e2ap_msg_t* msg);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// O-RAN E2APv01.01: Messages for Global Procedures ///////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_subscription_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
//RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_subscription_delete_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_control_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// O-RAN E2APv01.01: Messages for Global Procedures ///////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_handle_error_indication_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_setup_response_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_setup_failure_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_handle_reset_request_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_handle_reset_response_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_service_update_ack_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_service_update_failure_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_service_query_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_node_configuration_update_ack_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_node_configuration_update_failure_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_handle_connection_update_agent(e2_agent_t* ag, const e2ap_msg_t* msg);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
26
openair2/E2AP/agent/not_handler_agent.c
Normal file
26
openair2/E2AP/agent/not_handler_agent.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "not_handler_agent.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../lib/pending_events.h"
|
||||
|
||||
void notification_handle_ag(e2_agent_t* ag, sctp_msg_t const* msg)
|
||||
{
|
||||
assert(ag != NULL);
|
||||
assert(msg != NULL && msg->type == SCTP_MSG_NOTIFICATION);
|
||||
|
||||
// A pending event is created along with a timer of 3000 ms,
|
||||
// after which an event will be generated
|
||||
pending_event_t ev = SETUP_REQUEST_PENDING_EVENT;
|
||||
long const wait_ms = 3000;
|
||||
int fd_timer = create_timer_ms_asio_agent(&ag->io, wait_ms, wait_ms);
|
||||
|
||||
bi_map_insert(&ag->pending, &fd_timer, sizeof(fd_timer), &ev, sizeof(ev));
|
||||
|
||||
|
||||
puts("E2 AGENT: Communication with the nearRT-RIC lost\n" );
|
||||
|
||||
}
|
||||
|
||||
9
openair2/E2AP/agent/not_handler_agent.h
Normal file
9
openair2/E2AP/agent/not_handler_agent.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef NOTIFICATION_HANDLER_AGENT_H
|
||||
#define NOTIFICATION_HANDLER_AGENT_H
|
||||
|
||||
#include "e2_agent.h"
|
||||
|
||||
void notification_handle_ag(e2_agent_t* ag, sctp_msg_t const* msg);
|
||||
|
||||
#endif
|
||||
|
||||
260
openair2/E2AP/agent/plugin_agent.c
Normal file
260
openair2/E2AP/agent/plugin_agent.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* 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 "plugin_agent.h"
|
||||
|
||||
#include "alg.h"
|
||||
#include "lock_guard/lock_guard.h"
|
||||
#include "util/compare.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <dlfcn.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static inline
|
||||
void free_sm_agent(void* key, void* value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(value != NULL);
|
||||
|
||||
sm_agent_t* sm = (sm_agent_t*)value;
|
||||
|
||||
void* handle = sm->handle;
|
||||
sm->free_sm(sm);
|
||||
|
||||
if(handle != NULL)
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
static inline
|
||||
void check_dl_error(void)
|
||||
{
|
||||
const char* error = dlerror();
|
||||
if (error != NULL) {
|
||||
printf("Error from dlerror = %s \n", error);
|
||||
fflush(stdout);
|
||||
assert(0 != 0 && "error loading the init of the shared object");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int is_regular_file(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
stat(path, &path_stat);
|
||||
return S_ISREG(path_stat.st_mode);
|
||||
}
|
||||
|
||||
static
|
||||
bool file_ends_on(const char *path, size_t plen, const char *end, size_t elen)
|
||||
{
|
||||
size_t end_start = plen - elen;
|
||||
/* check including the terminating null byte */
|
||||
return strncmp(&path[end_start], end, elen + 1) == 0;
|
||||
}
|
||||
|
||||
static
|
||||
void load_all_pugin_ag(plugin_ag_t* p, const char* dir_path)
|
||||
{
|
||||
/* Scanning the in directory */
|
||||
printf("[E2 AGENT] loading plugins from directory %s\n", dir_path);
|
||||
DIR* fd = opendir(dir_path);
|
||||
assert(fd != NULL && "Error opening the input directory");
|
||||
|
||||
struct dirent* in_file = readdir(fd);
|
||||
while (in_file != NULL) {
|
||||
// We don't want current and parent directories
|
||||
if (!strncmp(in_file->d_name, ".", 2)) {
|
||||
in_file = readdir(fd);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(in_file->d_name, "..", 3)) {
|
||||
in_file = readdir(fd);
|
||||
continue;
|
||||
}
|
||||
// We don't want anything that does not end on .so
|
||||
const size_t len = strlen(in_file->d_name);
|
||||
if (!file_ends_on(in_file->d_name, len, ".so", 3)) {
|
||||
in_file = readdir(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
char file_path[FILENAME_MAX] = {0};
|
||||
strncat(file_path, dir_path, FILENAME_MAX - 1);
|
||||
const size_t fp_len = strlen(file_path);
|
||||
strncat(file_path + fp_len, in_file->d_name, FILENAME_MAX - fp_len - 1);
|
||||
|
||||
if (is_regular_file(file_path))
|
||||
load_plugin_ag(p, file_path);
|
||||
|
||||
in_file = readdir(fd);
|
||||
}
|
||||
|
||||
closedir(fd);
|
||||
}
|
||||
|
||||
void unload_all_pugin_ag(plugin_ag_t* p, const char* path)
|
||||
{
|
||||
assert(p != NULL);
|
||||
assert(path != NULL);
|
||||
assert(0!=0 && "Not implemented!");
|
||||
}
|
||||
|
||||
void init_plugin_ag(plugin_ag_t* p, const char* dir_path, sm_io_ag_t io)
|
||||
{
|
||||
assert(p != NULL);
|
||||
assert(dir_path != NULL);
|
||||
|
||||
p->dir_path = (char*)dir_path;
|
||||
p->io = io;
|
||||
p->flag_shutdown = false;
|
||||
|
||||
pthread_mutexattr_t attr= {0};
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
|
||||
|
||||
int rc = pthread_mutex_init(&p->sm_ds_mtx, &attr);
|
||||
assert(rc == 0);
|
||||
|
||||
const size_t ran_func_size = sizeof(uint16_t);
|
||||
assoc_init(&p->sm_ds, ran_func_size, cmp_ran_func_id, free_sm_agent );
|
||||
|
||||
load_all_pugin_ag(p, dir_path);
|
||||
}
|
||||
|
||||
void free_plugin_ag(plugin_ag_t* p)
|
||||
{
|
||||
assert(p != NULL);
|
||||
|
||||
assoc_free(&p->sm_ds);
|
||||
|
||||
pthread_mutex_destroy(&p->sm_ds_mtx);
|
||||
|
||||
// Thread management
|
||||
p->flag_shutdown = true;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool absolute_path(const char* path)
|
||||
{
|
||||
return path != NULL ? true : false;
|
||||
}
|
||||
|
||||
void load_plugin_ag(plugin_ag_t* p, const char* path)
|
||||
{
|
||||
//ToDo: Looks code from a sophomore. DO IT PROPERLY
|
||||
assert(p != NULL);
|
||||
assert(path != NULL);
|
||||
|
||||
printf("[E2 AGENT]: Opening plugin from path = %s \n", path );
|
||||
|
||||
void* handle = dlopen(path, RTLD_NOW);
|
||||
if(handle == NULL){
|
||||
printf("Error while opening the shared object = %s \n", dlerror());
|
||||
return;
|
||||
}
|
||||
assert(handle != NULL && "Could not open the file path");
|
||||
dlerror();
|
||||
|
||||
char* so_name = strrchr(path, '/');
|
||||
char* ptr_so_name = NULL;
|
||||
if(absolute_path(so_name) == true){
|
||||
ptr_so_name = so_name + strlen("/lib");
|
||||
assert(so_name != NULL);
|
||||
} else {
|
||||
ptr_so_name = (char*)path + strlen("lib");
|
||||
}
|
||||
|
||||
char symbol_so[256] = {'m','a','k','e','_'};
|
||||
char* needle = "_sm.so";
|
||||
|
||||
char* match = strstr( ptr_so_name, needle);
|
||||
assert(match != NULL && "Could not find the string _sm.so in the so\n");
|
||||
|
||||
char* ptr = &symbol_so[5];
|
||||
assert(match > ptr_so_name);
|
||||
strncat(ptr, ptr_so_name , match - ptr_so_name);
|
||||
ptr += match - ptr_so_name;
|
||||
const char* suffix = "_sm_agent";
|
||||
strncat(ptr,suffix, strlen(suffix));
|
||||
|
||||
sm_agent_t* (*fp)(sm_io_ag_t);
|
||||
fp = dlsym(handle, symbol_so);
|
||||
check_dl_error();
|
||||
sm_agent_t* sm = fp(p->io);
|
||||
|
||||
sm->handle = handle;
|
||||
assert(sm != NULL);
|
||||
const uint16_t ran_func_id = sm->ran_func_id;
|
||||
|
||||
{
|
||||
lock_guard(&p->sm_ds_mtx);
|
||||
assoc_insert(&p->sm_ds, &ran_func_id, sizeof(ran_func_id), sm);
|
||||
}
|
||||
|
||||
// printf("AGENT: Accepting SM ID = %d with def = %s \n", sm->ran_func_id, sm->ran_func_name);
|
||||
}
|
||||
|
||||
void unload_plugin_ag(plugin_ag_t* p, uint16_t key)
|
||||
{
|
||||
assert(p != NULL);
|
||||
assert(key != 0);
|
||||
assert(0!=0 && "Not implemented!");
|
||||
}
|
||||
|
||||
sm_agent_t* sm_plugin_ag(plugin_ag_t* p, uint16_t key)
|
||||
{
|
||||
assert(p != NULL);
|
||||
assert(key > 0 && "Reserved value");
|
||||
|
||||
lock_guard(&p->sm_ds_mtx);
|
||||
|
||||
void* start_it = assoc_front(&p->sm_ds);
|
||||
void* end_it = assoc_end(&p->sm_ds);
|
||||
void* it = find_if(&p->sm_ds, start_it, end_it, &key, eq_ran_func_id);
|
||||
assert(it != end_it && "RAN function ID not found in the RAN");
|
||||
|
||||
sm_agent_t* sm = assoc_value(&p->sm_ds, it);
|
||||
|
||||
assert(sm->ran_func_id == key);
|
||||
return sm;
|
||||
}
|
||||
|
||||
size_t size_plugin_ag(plugin_ag_t* p)
|
||||
{
|
||||
assert(p != NULL);
|
||||
|
||||
lock_guard(&p->sm_ds_mtx);
|
||||
|
||||
size_t s = assoc_size(&p->sm_ds);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
68
openair2/E2AP/agent/plugin_agent.h
Normal file
68
openair2/E2AP/agent/plugin_agent.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef E2_PLUGIN_AGENT_H
|
||||
#define E2_PLUGIN_AGENT_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdatomic.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "assoc_container/assoc_generic.h"
|
||||
|
||||
#include "sm/sm_agent.h"
|
||||
#include "sm/sm_io.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sm_io_ag_t io;
|
||||
const char* dir_path;
|
||||
|
||||
// Registered SMs
|
||||
assoc_rb_tree_t sm_ds; // key: ran_func_id, value: sm_agent_t*
|
||||
pthread_mutex_t sm_ds_mtx;
|
||||
|
||||
int sockfd;
|
||||
pthread_t thread_rx;
|
||||
|
||||
atomic_bool flag_shutdown;
|
||||
} plugin_ag_t;
|
||||
|
||||
|
||||
void init_plugin_ag(plugin_ag_t* p, const char* path, sm_io_ag_t io);
|
||||
|
||||
void free_plugin_ag(plugin_ag_t* p);
|
||||
|
||||
void load_plugin_ag(plugin_ag_t* p, const char* path);
|
||||
|
||||
void unload_plugin_ag(plugin_ag_t* p, uint16_t key);
|
||||
|
||||
sm_agent_t* sm_plugin_ag(plugin_ag_t* p, uint16_t key);
|
||||
|
||||
size_t size_plugin_ag(plugin_ag_t* p);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
11
openair2/E2AP/lib/CMakeLists.txt
Normal file
11
openair2/E2AP/lib/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
add_subdirectory(v1)
|
||||
add_subdirectory(ep)
|
||||
add_subdirectory(msg_hand)
|
||||
|
||||
add_library(pending_events_obj OBJECT
|
||||
pending_events.c
|
||||
pending_event_ric.c
|
||||
ind_event.c
|
||||
)
|
||||
target_link_libraries(pending_events_obj PRIVATE e2ap_types_obj e2ap_ap_obj ds)
|
||||
52
openair2/E2AP/lib/async_event.h
Normal file
52
openair2/E2AP/lib/async_event.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 ASYNC_EVENT_H
|
||||
#define ASYNC_EVENT_H
|
||||
|
||||
#include "ind_event.h"
|
||||
#include "pending_events.h"
|
||||
#include "ep/sctp_msg.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHECK_STOP_TOKEN_EVENT,
|
||||
SCTP_CONNECTION_SHUTDOWN_EVENT,
|
||||
SCTP_MSG_ARRIVED_EVENT,
|
||||
INDICATION_EVENT,
|
||||
PENDING_EVENT,
|
||||
|
||||
UNKNOWN_EVENT,
|
||||
} async_event_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
async_event_e type;
|
||||
int fd;
|
||||
union{
|
||||
pending_event_t* p_ev;
|
||||
ind_event_t* i_ev;
|
||||
sctp_msg_t msg;
|
||||
};
|
||||
} async_event_t;
|
||||
|
||||
#endif
|
||||
|
||||
3
openair2/E2AP/lib/ep/CMakeLists.txt
Normal file
3
openair2/E2AP/lib/ep/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
add_library(e2ap_ep_obj OBJECT e2ap_ep.c sctp_msg.c )
|
||||
target_link_libraries(e2ap_ep_obj PRIVATE sctp alg)
|
||||
target_link_libraries(e2ap_ep_obj PUBLIC ds)
|
||||
190
openair2/E2AP/lib/ep/e2ap_ep.c
Normal file
190
openair2/E2AP/lib/ep/e2ap_ep.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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 "e2ap_ep.h"
|
||||
#include "lock_guard/lock_guard.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
void e2ap_ep_init(e2ap_ep_t* ep)
|
||||
{
|
||||
int rc = pthread_mutex_init(&ep->mtx, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void e2ap_ep_free(e2ap_ep_t* ep)
|
||||
{
|
||||
assert(ep != NULL);
|
||||
int rc = pthread_mutex_destroy(&ep->mtx);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void e2ap_send_sctp_msg(const e2ap_ep_t* ep, sctp_msg_t* msg)
|
||||
{
|
||||
assert(ep != NULL);
|
||||
assert(msg->ba.buf && msg->ba.len > 0);
|
||||
|
||||
struct sockaddr_in const* addr = &msg->info.addr;
|
||||
struct sctp_sndrcvinfo const* sri = &msg->info.sri;
|
||||
byte_array_t const ba = msg->ba;
|
||||
|
||||
lock_guard(&((e2ap_ep_t*)ep)->mtx);
|
||||
|
||||
const int rc = sctp_sendmsg(ep->fd, (void*)ba.buf, ba.len, (struct sockaddr *)addr, sizeof(*addr), sri->sinfo_ppid, sri->sinfo_flags, sri->sinfo_stream, 0, 0) ;
|
||||
assert(rc != 0);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
struct sctp_shutdown_event cp_sn_shutdown_event(struct sctp_shutdown_event const* src)
|
||||
{
|
||||
struct sctp_shutdown_event dst = { .sse_type = src->sse_type,
|
||||
.sse_flags = src->sse_flags,
|
||||
.sse_length = src->sse_length,
|
||||
.sse_assoc_id = src->sse_assoc_id };
|
||||
return dst;
|
||||
}
|
||||
|
||||
static
|
||||
struct sctp_assoc_change cp_sn_assoc_change( struct sctp_assoc_change const* src)
|
||||
{
|
||||
struct sctp_assoc_change dst = {.sac_state = src->sac_state};
|
||||
|
||||
switch(src->sac_state) {
|
||||
case SCTP_COMM_UP:
|
||||
assert(0 !=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_COMM_LOST:
|
||||
assert(0 !=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_RESTART:
|
||||
assert(0 !=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_SHUTDOWN_COMP:
|
||||
assert(0 !=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_CANT_STR_ASSOC:
|
||||
assert(0 !=0 && "Not implemented");
|
||||
break;
|
||||
default:
|
||||
assert(0!=0 && "Impossible data path. enum sctp_sac_state only has 5 states" );
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
union sctp_notification cp_sctp_notification(union sctp_notification const* src, size_t len)
|
||||
{
|
||||
assert(src != NULL);
|
||||
assert(sizeof(((union sctp_notification*)NULL)->sn_header) <= len);
|
||||
|
||||
union sctp_notification dst = {.sn_header.sn_type = src-> sn_header.sn_type};
|
||||
|
||||
switch(src->sn_header.sn_type) {
|
||||
case SCTP_ASSOC_CHANGE: //This tag indicates that an association has either been opened or closed. Refer to Section 6.1.1 for details.
|
||||
assert(sizeof(struct sctp_assoc_change) >= len && "Error notification msg size is smaller than struct sctp_assoc_change size\n");
|
||||
dst.sn_assoc_change = cp_sn_assoc_change(&src->sn_assoc_change);
|
||||
break;
|
||||
|
||||
case SCTP_PEER_ADDR_CHANGE: //This tag indicates that an address that is part of an existing association has experienced a change of state (e.g., a failure or return to service of the reachability of an endpoint via a specific transport address). Please see Section 6.1.2 for data structure details.
|
||||
assert(0!=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_REMOTE_ERROR: // The attached error message is an Operation Error message received from the remote peer. It includes the complete TLV sent by the remote endpoint. See Section 6.1.3 for the detailed format.
|
||||
assert(0!=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_SEND_FAILED: //The attached datagram could not be sent to the remote endpoint. This structure includes the original SCTP_SNDINFO that was used in sending this message; i.e., this structure uses the sctp_sndinfo per Section 6.1.11.
|
||||
assert(0!=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_SHUTDOWN_EVENT: // The peer has sent a SHUTDOWN. No further data should be sent on this socket.
|
||||
assert( sizeof(struct sctp_shutdown_event) >= len);
|
||||
dst.sn_shutdown_event = cp_sn_shutdown_event(&src->sn_shutdown_event);
|
||||
break;
|
||||
|
||||
case SCTP_ADAPTATION_INDICATION: //This notification holds the peer’s indicated adaptation layer. Please see Section 6.1.6.
|
||||
assert(0!=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
case SCTP_PARTIAL_DELIVERY_EVENT: //This notification is used to tell a receiver that the partial delivery has been aborted. This may indicate that the association is about to be aborted. Please see Section 6.1.7.
|
||||
assert(0!=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
//case SCTP_AUTHENTICATION_EVENT: //This notification is used to tell a receiver that either an error occurred on authentication, or a new key was made active. See Section 6.1.8.
|
||||
// assert(0!=0 && "Not implemented");
|
||||
// break;
|
||||
|
||||
case SCTP_SENDER_DRY_EVENT:
|
||||
assert(0!=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0!=0 && "Not implemented");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
sctp_msg_t e2ap_recv_sctp_msg(e2ap_ep_t* ep)
|
||||
{
|
||||
assert(ep != NULL);
|
||||
|
||||
sctp_msg_t from = {0};
|
||||
|
||||
from.ba.len = 16384;
|
||||
from.ba.buf = malloc(16384);
|
||||
|
||||
assert(from.ba.buf != NULL && "Memory exhausted");
|
||||
|
||||
socklen_t len = sizeof(from.info.addr);
|
||||
int msg_flags = 0;
|
||||
|
||||
lock_guard(&((e2ap_ep_t*)ep)->mtx);
|
||||
int const rc = sctp_recvmsg(ep->fd, from.ba.buf, from.ba.len, (struct sockaddr*)&from.info.addr, &len, &from.info.sri, &msg_flags);
|
||||
assert(rc > -1 && rc != 0 && rc < (int)from.ba.len);
|
||||
|
||||
if(msg_flags & MSG_NOTIFICATION){
|
||||
assert((msg_flags & MSG_EOR) && "Notification received but the buffer is not large enough");
|
||||
uint8_t buf[2048] = {0};
|
||||
memcpy(buf, from.ba.buf, 2048);
|
||||
free(from.ba.buf);
|
||||
|
||||
from.type = SCTP_MSG_NOTIFICATION;
|
||||
from.notif = cp_sctp_notification((union sctp_notification*) buf, rc);
|
||||
} else {
|
||||
from.type = SCTP_MSG_PAYLOAD;
|
||||
from.ba.len = rc; // set actually received number of bytes
|
||||
}
|
||||
|
||||
return from;
|
||||
}
|
||||
|
||||
55
openair2/E2AP/lib/ep/e2ap_ep.h
Normal file
55
openair2/E2AP/lib/ep/e2ap_ep.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 E2AP_EP
|
||||
#define E2AP_EP
|
||||
|
||||
#include <assert.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sctp_msg.h"
|
||||
|
||||
|
||||
typedef struct{
|
||||
const char addr[16]; // only ipv4 supported
|
||||
const int port;
|
||||
const int fd;
|
||||
pthread_mutex_t mtx;
|
||||
} e2ap_ep_t;
|
||||
|
||||
void e2ap_ep_init(e2ap_ep_t* ep);
|
||||
|
||||
void e2ap_ep_free(e2ap_ep_t* ep);
|
||||
|
||||
void e2ap_send_sctp_msg(const e2ap_ep_t* ep, sctp_msg_t* msg);
|
||||
|
||||
sctp_msg_t e2ap_recv_sctp_msg(e2ap_ep_t* ep);
|
||||
|
||||
#endif
|
||||
|
||||
107
openair2/E2AP/lib/ep/sctp_msg.c
Normal file
107
openair2/E2AP/lib/ep/sctp_msg.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 "sctp_msg.h"
|
||||
|
||||
void free_sctp_msg(sctp_msg_t* rcv)
|
||||
{
|
||||
assert(rcv != NULL);
|
||||
|
||||
if(rcv->type == SCTP_MSG_PAYLOAD)
|
||||
free_byte_array(rcv->ba);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int cmp_sockaddr_in(struct sockaddr_in const* m0, struct sockaddr_in const* m1)
|
||||
{
|
||||
assert(m0 != NULL);
|
||||
assert(m1 != NULL);
|
||||
|
||||
if(m0->sin_port < m1->sin_port)
|
||||
return 1;
|
||||
|
||||
if(m0->sin_port > m1->sin_port)
|
||||
return -1;
|
||||
|
||||
if(m0->sin_addr.s_addr < m1->sin_addr.s_addr)
|
||||
return 1;
|
||||
|
||||
if(m0->sin_addr.s_addr > m1->sin_addr.s_addr)
|
||||
return -1;
|
||||
|
||||
if(m0->sin_family < m1->sin_family)
|
||||
return 1;
|
||||
|
||||
if(m0->sin_family > m1->sin_family)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int cmp_sctp_sndrcvinfo(struct sctp_sndrcvinfo* m0, struct sctp_sndrcvinfo* m1)
|
||||
{
|
||||
assert(m0 != NULL && m1 != NULL);
|
||||
|
||||
/*
|
||||
struct sctp_sndrcvinfo {
|
||||
uint16_t sinfo_stream;
|
||||
uint16_t sinfo_ssn;
|
||||
uint16_t sinfo_flags;
|
||||
uint32_t sinfo_ppid;
|
||||
uint32_t sinfo_context;
|
||||
uint32_t sinfo_timetolive;
|
||||
uint32_t sinfo_tsn;
|
||||
uint32_t sinfo_cumtsn;
|
||||
sctp_assoc_t sinfo_assoc_id;
|
||||
};
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmp_sctp_info_wrapper(void const* m0_v, void const* m1_v)
|
||||
{
|
||||
if(m0_v == NULL && m1_v == NULL)
|
||||
return 0;
|
||||
|
||||
if(m0_v == NULL)
|
||||
return 1;
|
||||
|
||||
if(m1_v == NULL)
|
||||
return -1;
|
||||
|
||||
sctp_info_t* m0 = (sctp_info_t*)m0_v;
|
||||
sctp_info_t* m1 = (sctp_info_t*)m1_v;
|
||||
|
||||
int cmp = cmp_sockaddr_in(&m0->addr, &m1->addr);
|
||||
|
||||
if(cmp != 0) return cmp;
|
||||
|
||||
return cmp_sctp_sndrcvinfo(&m0->sri, &m1->sri);
|
||||
}
|
||||
|
||||
bool eq_sctp_info_wrapper(void const* m0, void const* m1)
|
||||
{
|
||||
return cmp_sctp_info_wrapper(m0,m1) == 0;
|
||||
}
|
||||
|
||||
65
openair2/E2AP/lib/ep/sctp_msg.h
Normal file
65
openair2/E2AP/lib/ep/sctp_msg.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 SCTP_MSG_H
|
||||
#define SCTP_MSG_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "byte_array.h"
|
||||
|
||||
typedef enum {
|
||||
SCTP_MSG_PAYLOAD,
|
||||
SCTP_MSG_NOTIFICATION
|
||||
} sctp_msg_type_t;
|
||||
|
||||
typedef struct{
|
||||
struct sockaddr_in addr;
|
||||
struct sctp_sndrcvinfo sri;
|
||||
} sctp_info_t ;
|
||||
|
||||
int cmp_sctp_info_wrapper(void const* m0, void const* m1);
|
||||
|
||||
bool eq_sctp_info_wrapper(void const* m0, void const* m1);
|
||||
|
||||
typedef struct{
|
||||
sctp_msg_type_t type;
|
||||
sctp_info_t info;
|
||||
union{
|
||||
byte_array_t ba;
|
||||
union sctp_notification notif;
|
||||
};
|
||||
} sctp_msg_t;
|
||||
|
||||
void free_sctp_msg(sctp_msg_t* rcv);
|
||||
|
||||
#endif
|
||||
|
||||
38
openair2/E2AP/lib/ind_event.c
Normal file
38
openair2/E2AP/lib/ind_event.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 "ind_event.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int cmp_ind_event(void const* m0_v, void const* m1_v)
|
||||
{
|
||||
assert(m0_v != NULL);
|
||||
assert(m1_v != NULL);
|
||||
ind_event_t* m0 = (ind_event_t*)m0_v;
|
||||
ind_event_t* m1 = (ind_event_t*)m1_v;
|
||||
|
||||
int cmp = cmp_ric_gen_id(&m0->ric_id, &m1->ric_id);
|
||||
return cmp;
|
||||
}
|
||||
41
openair2/E2AP/lib/ind_event.h
Normal file
41
openair2/E2AP/lib/ind_event.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 INDICATION_EVENT_H
|
||||
#define INDICATION_EVENT_H
|
||||
|
||||
#include <stdint.h> // for uint8_t
|
||||
#include "v1/ap/e2ap_types/common/ric_gen_id.h" // for ric_gen_id_t
|
||||
#include "../sm/sm_agent.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ric_gen_id_t ric_id;
|
||||
sm_agent_t* sm;
|
||||
uint8_t action_id;
|
||||
} ind_event_t;
|
||||
|
||||
int cmp_ind_event(void const* m0_v, void const* m1_v);
|
||||
|
||||
#endif
|
||||
|
||||
6
openair2/E2AP/lib/msg_hand/CMakeLists.txt
Normal file
6
openair2/E2AP/lib/msg_hand/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
add_library(msg_hand_obj OBJECT
|
||||
reg_e2_nodes.c
|
||||
e2_node_arr.c
|
||||
)
|
||||
|
||||
46
openair2/E2AP/lib/msg_hand/e2_node_arr.c
Normal file
46
openair2/E2AP/lib/msg_hand/e2_node_arr.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 "e2_node_arr.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void free_e2_node_arr(e2_node_arr_t* xapp)
|
||||
{
|
||||
assert(xapp != NULL);
|
||||
|
||||
for(size_t i = 0; i < xapp->len; ++i){
|
||||
for(size_t j = 0; j < xapp->n[i].len_rf; ++j){
|
||||
free_ran_function(&xapp->n[i].ack_rf[j]);
|
||||
}
|
||||
if( xapp->n[i].len_rf > 0)
|
||||
free(xapp->n[i].ack_rf);
|
||||
|
||||
free_global_e2_node_id(&xapp->n[i].id);
|
||||
}
|
||||
|
||||
if(xapp->len > 0){
|
||||
free(xapp->n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
46
openair2/E2AP/lib/msg_hand/e2_node_arr.h
Normal file
46
openair2/E2AP/lib/msg_hand/e2_node_arr.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 E2_NODE_ARR_H
|
||||
#define E2_NODE_ARR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../ap/e2ap_types/e2_node_connected.h"
|
||||
|
||||
typedef struct{
|
||||
uint8_t len;
|
||||
e2_node_connected_t* n;
|
||||
} e2_node_arr_t;
|
||||
|
||||
void free_e2_node_arr(e2_node_arr_t*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
298
openair2/E2AP/lib/msg_hand/reg_e2_nodes.c
Normal file
298
openair2/E2AP/lib/msg_hand/reg_e2_nodes.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* 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 "reg_e2_nodes.h"
|
||||
#include "lock_guard/lock_guard.h"
|
||||
#include "find.h"
|
||||
#include "alg.h"
|
||||
|
||||
#include "../../lib/ap/e2ap_types/common/e2ap_global_node_id.h"
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static
|
||||
void free_ran_function_pointer(void* rf_p)
|
||||
{
|
||||
assert(rf_p != NULL);
|
||||
ran_function_t* rf = *(ran_function_t**)rf_p;
|
||||
free_ran_function_wrapper(rf);
|
||||
free(rf);
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
void free_e2_nodes(void* key, void* value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(value != NULL);
|
||||
|
||||
(void)key;
|
||||
seq_arr_t* arr_node = (seq_arr_t*)value;
|
||||
//assert(seq_size(arr_node) == 2);
|
||||
seq_free_func f = free_ran_function_pointer;
|
||||
seq_arr_free(arr_node, f);
|
||||
free(arr_node);
|
||||
|
||||
global_e2_node_id_t* e2node = (global_e2_node_id_t*) key;
|
||||
free_global_e2_node_id(e2node);
|
||||
}
|
||||
|
||||
|
||||
void init_reg_e2_node(reg_e2_nodes_t* i)
|
||||
{
|
||||
assert(i != NULL);
|
||||
|
||||
assoc_init(&i->node_to_rf, sizeof(global_e2_node_id_t), cmp_global_e2_node_id_wrapper, free_e2_nodes);
|
||||
|
||||
pthread_mutexattr_t* attr = NULL;
|
||||
#ifdef DEBUG
|
||||
*attr = PTHREAD_MUTEX_ERRORCHECK;
|
||||
#endif
|
||||
|
||||
int const rc = pthread_mutex_init(&i->mtx, attr);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void free_reg_e2_node(reg_e2_nodes_t* i)
|
||||
{
|
||||
assert(i != NULL);
|
||||
assoc_free(&i->node_to_rf);
|
||||
// assoc_free(&i->rf_to_node);
|
||||
|
||||
int const rc = pthread_mutex_destroy(&i->mtx);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void add_reg_e2_node(reg_e2_nodes_t* i, global_e2_node_id_t const* id, size_t len, ran_function_t const ran_func[len])
|
||||
{
|
||||
assert(i != NULL);
|
||||
assert(id != NULL);
|
||||
assert(len > 0);
|
||||
assert(ran_func != NULL);
|
||||
|
||||
seq_arr_t* arr = calloc(1, sizeof(seq_arr_t));
|
||||
assert(arr != NULL && "Memory exhausted");
|
||||
|
||||
seq_init(arr, sizeof(ran_function_t*));
|
||||
|
||||
for(size_t i = 0; i < len; ++i){
|
||||
ran_function_t* tmp = calloc(1, sizeof(ran_function_t) );
|
||||
assert(tmp != NULL && "Memory exhausted");
|
||||
|
||||
*tmp = cp_ran_function(&ran_func[i]);
|
||||
seq_push_back(arr, &tmp, sizeof(ran_function_t*) );
|
||||
}
|
||||
|
||||
lock_guard(&i->mtx);
|
||||
|
||||
if(assoc_size(&i->node_to_rf) > 0){
|
||||
void* it_node = assoc_front(&i->node_to_rf);
|
||||
void* end_node = assoc_end(&i->node_to_rf);
|
||||
|
||||
it_node = find_if(&i->node_to_rf, it_node, end_node, id, eq_global_e2_node_id_wrapper );
|
||||
assert(it_node == end_node && "Trying to add an already existing E2 Node");
|
||||
}
|
||||
|
||||
// if(it_node != end_node) {
|
||||
// seq_arr_t* old_arr = assoc_extract(&i->node_to_rf,(global_e2_node_id_t*)id);
|
||||
// seq_free(old_arr, free_ran_function_wrapper);
|
||||
// free(old_arr);
|
||||
// }
|
||||
|
||||
assoc_insert(&i->node_to_rf, id, sizeof(global_e2_node_id_t), arr);
|
||||
|
||||
// void* it_n = assoc_front(&i->node_to_rf);
|
||||
// seq_arr_t* arr_tmp = assoc_value(&i->node_to_rf, it_n);
|
||||
// assert(seq_size(arr_tmp) == 2 && "Only for current test valid");
|
||||
}
|
||||
|
||||
static inline
|
||||
assoc_rb_tree_t available_e2node(reg_e2_nodes_t* n, size_t len, ran_function_t rf[len])
|
||||
{
|
||||
assert(n != NULL);
|
||||
assert(len > 0);
|
||||
assert(rf != NULL);
|
||||
|
||||
assoc_rb_tree_t ret = {0};
|
||||
assoc_init(&ret, sizeof(global_e2_node_id_t), cmp_global_e2_node_id_wrapper, free_e2_nodes);
|
||||
|
||||
|
||||
lock_guard(&n->mtx);
|
||||
|
||||
void* it = assoc_front(&n->node_to_rf);
|
||||
void* end = assoc_end(&n->node_to_rf);
|
||||
|
||||
while(it != end){ // per E2 Node
|
||||
seq_arr_t* arr_v = assoc_value(&n->node_to_rf, it);
|
||||
const size_t sz = seq_size(arr_v);
|
||||
for(size_t i = 0; i < len; ++i){
|
||||
for(size_t j = 0; j < sz ; ++j){
|
||||
ran_function_t* r = *(ran_function_t**)seq_at(arr_v, j);
|
||||
// Add the RAN functions that have permission
|
||||
if(eq_ran_function(r,&rf[i]) == true){
|
||||
global_e2_node_id_t* id = assoc_key(&ret, it);
|
||||
|
||||
void* it_ret = assoc_front(&ret);
|
||||
void* end_ret = assoc_end(&ret);
|
||||
|
||||
it_ret = find_if(&ret, it_ret, end_ret, id, eq_global_e2_node_id_wrapper);
|
||||
seq_arr_t* arr = NULL;
|
||||
if(it_ret == end_ret){
|
||||
arr = calloc(1, sizeof(seq_arr_t));
|
||||
assert(arr != NULL && "memory exhasuted");
|
||||
|
||||
seq_init(arr,sizeof(ran_function_t*));
|
||||
assoc_insert(&ret, id, sizeof(global_e2_node_id_t), arr);
|
||||
} else{
|
||||
arr = assoc_value(&ret, it_ret);
|
||||
}
|
||||
ran_function_t* tmp = calloc(1, sizeof(ran_function_t));
|
||||
assert(tmp != NULL && "Memory exhausted");
|
||||
|
||||
*tmp = cp_ran_function(r);
|
||||
seq_push_back(arr, tmp, sizeof(ran_function_t*));
|
||||
}
|
||||
}
|
||||
}
|
||||
it = assoc_next(&n->node_to_rf, it);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t sz_reg_e2_node(reg_e2_nodes_t* n)
|
||||
{
|
||||
assert(n != NULL);
|
||||
|
||||
lock_guard(&n->mtx);
|
||||
return assoc_size(&n->node_to_rf);
|
||||
}
|
||||
|
||||
|
||||
assoc_rb_tree_t cp_reg_e2_node(reg_e2_nodes_t* n)
|
||||
{
|
||||
assert(n != 0);
|
||||
|
||||
// key:global_e2_node_id_t | value: seq_arr_t* of ran_function_t
|
||||
assoc_rb_tree_t ans = {0};
|
||||
assoc_init(&ans, sizeof(global_e2_node_id_t), cmp_global_e2_node_id_wrapper, free_e2_nodes);
|
||||
|
||||
lock_guard(&n->mtx);
|
||||
|
||||
void* it = assoc_front(&n->node_to_rf);
|
||||
void* end = assoc_end(&n->node_to_rf);
|
||||
|
||||
while(it != end){
|
||||
global_e2_node_id_t* tmp = assoc_key(&n->node_to_rf, it );
|
||||
global_e2_node_id_t cp_tmp = cp_global_e2_node_id(tmp);
|
||||
|
||||
seq_arr_t* arr = assoc_value(&n->node_to_rf, it);
|
||||
seq_arr_t* new_arr = calloc(1, sizeof(seq_arr_t));
|
||||
assert(new_arr != NULL);
|
||||
seq_init(new_arr, sizeof(ran_function_t*));
|
||||
void* it_arr = seq_front(arr);
|
||||
void* end_arr = seq_end(arr);
|
||||
while(it_arr != end_arr){
|
||||
ran_function_t* r = *(ran_function_t**)it_arr;
|
||||
ran_function_t* tmp_r = calloc(1, sizeof(ran_function_t));
|
||||
assert(tmp_r != NULL);
|
||||
*tmp_r = cp_ran_function(r);
|
||||
seq_push_back(new_arr, &tmp_r, sizeof(ran_function_t*));
|
||||
|
||||
it_arr = seq_next(arr, it_arr);
|
||||
}
|
||||
assoc_insert(&ans,&cp_tmp, sizeof(global_e2_node_id_t), new_arr);
|
||||
|
||||
it = assoc_next(&n->node_to_rf, it);
|
||||
}
|
||||
|
||||
assert(assoc_size(&ans) == assoc_size(&n->node_to_rf) );
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
e2_node_arr_t generate_e2_node_arr(reg_e2_nodes_t* n)
|
||||
{
|
||||
assoc_rb_tree_t t = cp_reg_e2_node(n);
|
||||
defer({ assoc_free(&t); }; );
|
||||
|
||||
e2_node_arr_t ans = {0};
|
||||
ans.len = assoc_size(&t);
|
||||
|
||||
if(ans.len > 0){
|
||||
ans.n = calloc(ans.len, sizeof(e2_node_connected_t) );
|
||||
assert(ans.n != NULL && "Memory exhausted" );
|
||||
}
|
||||
|
||||
uint32_t i = 0;
|
||||
void* it = assoc_front(&t);
|
||||
void* end = assoc_end(&t);
|
||||
while(it != end){
|
||||
global_e2_node_id_t* tmp_id = assoc_key(&t, it);
|
||||
ans.n[i].id = cp_global_e2_node_id(tmp_id);
|
||||
|
||||
seq_arr_t* tmp_arr = assoc_value(&t, it);
|
||||
assert(tmp_arr->elt_size == sizeof(ran_function_t*));
|
||||
|
||||
const size_t sz = seq_size(tmp_arr);
|
||||
|
||||
ans.n[i].len_rf = sz;
|
||||
if(sz > 0){
|
||||
ans.n[i].ack_rf = calloc(sz, sizeof(ran_function_t));
|
||||
assert(ans.n[i].ack_rf != NULL && "memory exhausted");
|
||||
}
|
||||
|
||||
for(size_t j = 0; j < sz; ++j){
|
||||
ran_function_t* r = *(ran_function_t**)seq_at(tmp_arr, j);
|
||||
ans.n[i].ack_rf[j] = cp_ran_function(r);
|
||||
}
|
||||
|
||||
i += 1;
|
||||
it = assoc_next(&t, it);
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
void rm_reg_e2_node(reg_e2_nodes_t* n, global_e2_node_id_t const* id)
|
||||
{
|
||||
assert(n != NULL);
|
||||
assert(id != NULL);
|
||||
|
||||
printf("[NEAR-RIC]: Removing E2 Node MCC %d MNC %d NB_ID %u \n", id->plmn.mcc, id->plmn.mnc, id->nb_id);
|
||||
|
||||
{
|
||||
lock_guard(&n->mtx);
|
||||
|
||||
void* it = assoc_front(&n->node_to_rf);
|
||||
void* end = assoc_end(&n->node_to_rf);
|
||||
it = find_if(&n->node_to_rf, it, end, id, eq_global_e2_node_id_wrapper );
|
||||
assert(it != end && "Not registed e2 Node passed");
|
||||
|
||||
seq_arr_t* arr = assoc_extract(&n->node_to_rf, (global_e2_node_id_t*)id);;
|
||||
|
||||
free_e2_nodes((void*)id , arr);
|
||||
}
|
||||
}
|
||||
|
||||
56
openair2/E2AP/lib/msg_hand/reg_e2_nodes.h
Normal file
56
openair2/E2AP/lib/msg_hand/reg_e2_nodes.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 REGISTERED_E2_NODES_H
|
||||
#define REGISTERED_E2_NODES_H
|
||||
|
||||
#include "assoc_container/assoc_generic.h"
|
||||
#include "../ap/e2ap_types/e2_node_connected.h"
|
||||
|
||||
#include "e2_node_arr.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef struct{
|
||||
// key:global_e2_node_id_t | value: seq_arr_t* of ran_function_t
|
||||
assoc_rb_tree_t node_to_rf;
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
} reg_e2_nodes_t;
|
||||
|
||||
void init_reg_e2_node(reg_e2_nodes_t* n);
|
||||
|
||||
void free_reg_e2_node(reg_e2_nodes_t* n);
|
||||
|
||||
void add_reg_e2_node(reg_e2_nodes_t* n, global_e2_node_id_t const* id, size_t len, ran_function_t const ran_func[len]);
|
||||
|
||||
void rm_reg_e2_node(reg_e2_nodes_t* n, global_e2_node_id_t const* id);
|
||||
|
||||
size_t sz_reg_e2_node(reg_e2_nodes_t* n);
|
||||
|
||||
assoc_rb_tree_t cp_reg_e2_node(reg_e2_nodes_t* n);
|
||||
|
||||
e2_node_arr_t generate_e2_node_arr(reg_e2_nodes_t* n);
|
||||
|
||||
#endif
|
||||
|
||||
44
openair2/E2AP/lib/pending_event_ric.c
Normal file
44
openair2/E2AP/lib/pending_event_ric.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 "pending_event_ric.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int cmp_pending_event_ric(void const* p_v1, void const* p_v2)
|
||||
{
|
||||
assert(p_v1 != NULL);
|
||||
assert(p_v2 != NULL);
|
||||
|
||||
pending_event_ric_t* p1 = (pending_event_ric_t*)p_v1;
|
||||
pending_event_ric_t* p2 = (pending_event_ric_t*)p_v2;
|
||||
int cmp_ev = cmp_pending_event(p1, p2);
|
||||
if(cmp_ev != 0)
|
||||
return cmp_ev;
|
||||
|
||||
return cmp_ric_gen_id(&p1->id, &p2->id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
40
openair2/E2AP/lib/pending_event_ric.h
Normal file
40
openair2/E2AP/lib/pending_event_ric.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 PENDING_EVENT_RIC_H
|
||||
#define PENDING_EVENT_RIC_H
|
||||
|
||||
#include "lib/pending_events.h"
|
||||
#include "lib/v1/ap/e2ap_types/common/ric_gen_id.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pending_event_t ev;
|
||||
ric_gen_id_t id;
|
||||
} pending_event_ric_t;
|
||||
|
||||
int cmp_pending_event_ric(void const* p_v1, void const* p_v2);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
51
openair2/E2AP/lib/pending_events.c
Normal file
51
openair2/E2AP/lib/pending_events.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 "pending_events.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int cmp_pending_event(void const* pend_v1, void const* pend_v2)
|
||||
{
|
||||
assert(pend_v1 != NULL);
|
||||
assert(pend_v2 != NULL);
|
||||
|
||||
pending_event_t* ev1 = (pending_event_t*)pend_v1;
|
||||
pending_event_t* ev2 = (pending_event_t*)pend_v2;
|
||||
|
||||
if(*ev1 < *ev2) return 1;
|
||||
if(*ev1 == *ev2) return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool valid_pending_event(pending_event_t ev)
|
||||
{
|
||||
assert(ev == SETUP_REQUEST_PENDING_EVENT
|
||||
|| ev == SUBSCRIPTION_REQUEST_PENDING_EVENT
|
||||
|| ev == SUBSCRIPTION_DELETE_REQUEST_PENDING_EVENT
|
||||
|| ev == E42_SETUP_REQUEST_PENDING_EVENT
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
54
openair2/E2AP/lib/pending_events.h
Normal file
54
openair2/E2AP/lib/pending_events.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 PENDING_EVENTS_H
|
||||
#define PENDING_EVENTS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum pending_event_e
|
||||
{
|
||||
// AGENT
|
||||
SETUP_REQUEST_PENDING_EVENT,
|
||||
|
||||
// RIC
|
||||
SUBSCRIPTION_REQUEST_PENDING_EVENT,
|
||||
SUBSCRIPTION_DELETE_REQUEST_PENDING_EVENT,
|
||||
CONTROL_REQUEST_PENDING_EVENT,
|
||||
|
||||
// xApp
|
||||
E42_SETUP_REQUEST_PENDING_EVENT,
|
||||
E42_RIC_SUBSCRIPTION_REQUEST_PENDING_EVENT,
|
||||
RIC_SUBSCRIPTION_DELETE_REQUEST_PENDING_EVENT,
|
||||
E42_RIC_SUBSCRIPTION_DELETE_REQUEST_PENDING_EVENT,
|
||||
E42_RIC_CONTROL_REQUEST_PENDING_EVENT,
|
||||
|
||||
} pending_event_t;
|
||||
|
||||
|
||||
int cmp_pending_event(void const* pend_v1, void const* pend_v2);
|
||||
|
||||
bool valid_pending_event(pending_event_t ev);
|
||||
|
||||
#endif
|
||||
|
||||
2
openair2/E2AP/lib/v1/CMakeLists.txt
Normal file
2
openair2/E2AP/lib/v1/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
add_subdirectory(ap)
|
||||
24
openair2/E2AP/lib/v1/ap/CMakeLists.txt
Normal file
24
openair2/E2AP/lib/v1/ap/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
add_subdirectory(e2ap_types)
|
||||
add_subdirectory(ie)
|
||||
add_subdirectory(enc)
|
||||
add_subdirectory(dec)
|
||||
add_subdirectory(free)
|
||||
|
||||
|
||||
if(E2AP_ENCODING STREQUAL "E2AP_ASN")
|
||||
add_library(e2ap_ap_obj OBJECT e2ap_ap_asn.c)
|
||||
|
||||
elseif(E2AP_ENCODING STREQUAL "E2AP_FLATBUFFERS")
|
||||
add_library(e2ap_ap_obj OBJECT e2ap_ap_fb.c)
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown E2AP encoding type")
|
||||
endif()
|
||||
|
||||
# Set the MACRO variable that will be used by the compiler to select the encoding/decoding
|
||||
target_compile_definitions(e2ap_ap_obj PRIVATE ${E2AP_ENCODING})
|
||||
target_link_libraries(e2ap_ap_obj PUBLIC
|
||||
e2ap_types_obj
|
||||
e2ap_msg_enc_obj
|
||||
e2ap_msg_dec_obj
|
||||
e2ap_msg_free_obj)
|
||||
16
openair2/E2AP/lib/v1/ap/dec/CMakeLists.txt
Normal file
16
openair2/E2AP/lib/v1/ap/dec/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
if(E2AP_ENCODING STREQUAL "E2AP_ASN")
|
||||
add_library(e2ap_msg_dec_obj OBJECT e2ap_msg_dec_asn.c)
|
||||
target_link_libraries(e2ap_msg_dec_obj PRIVATE asn1_e2ap)
|
||||
target_compile_options(e2ap_msg_dec_obj PRIVATE -DASN_DISABLE_OER_SUPPORT)
|
||||
|
||||
elseif(E2AP_ENCODING STREQUAL "E2AP_FLATBUFFERS")
|
||||
add_library(e2ap_msg_dec_obj OBJECT e2ap_msg_dec_fb.c)
|
||||
|
||||
target_link_libraries(e2ap_msg_dec_obj PRIVATE e2ap_fb_obj)
|
||||
else()
|
||||
message(FATAL_ERROR "no E2AP encoding scheme selected")
|
||||
endif()
|
||||
|
||||
add_compile_definitions(PRIVATE ${E2AP_ENCODING})
|
||||
|
||||
target_link_libraries(e2ap_msg_dec_obj PRIVATE e2ap_types_obj)
|
||||
2413
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_asn.c
Normal file
2413
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_asn.c
Normal file
File diff suppressed because it is too large
Load Diff
138
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_asn.h
Normal file
138
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_asn.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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 E2AP_MSG_DEC_ASN_H
|
||||
#define E2AP_MSG_DEC_ASN_H
|
||||
|
||||
#include "lib/v1/ap/type_defs.h"
|
||||
|
||||
struct E2AP_E2AP_PDU;
|
||||
typedef struct e2ap_asn e2ap_asn_t;
|
||||
|
||||
e2ap_msg_t e2ap_msg_dec_asn(e2ap_asn_t* asn, byte_array_t ba);
|
||||
|
||||
void e2ap_msg_free_asn(struct e2ap_asn* enc, e2ap_msg_t* msg);
|
||||
|
||||
void init_ap_asn(struct e2ap_asn*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// O-RAN E2APv01.01: Messages for Global Procedures ///////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_subscription_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_response(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
//E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_failure(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
//RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_response(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
//E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_failure(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_indication(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_control_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_control_ack(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_control_failure(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// O-RAN E2APv01.01: Messages for Global Procedures ///////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_error_indication(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_setup_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_setup_response(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_setup_failure(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_reset_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_reset_response(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_service_update(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_update_ack(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_update_failure(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_query(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_ack(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_failure(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_connection_update(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_connection_update_ack(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_connection_update_failure(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// xApp -> iApp
|
||||
e2ap_msg_t e2ap_dec_e42_setup_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// iApp -> xApp
|
||||
e2ap_msg_t e2ap_dec_e42_setup_response(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// xApp -> iApp
|
||||
e2ap_msg_t e2ap_dec_e42_subscription_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// xApp -> iApp
|
||||
e2ap_msg_t e2ap_dec_e42_subscription_delete_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
// xApp -> iApp
|
||||
e2ap_msg_t e2ap_dec_e42_control_request(const struct E2AP_E2AP_PDU* pdu);
|
||||
|
||||
#endif
|
||||
|
||||
945
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_fb.c
Normal file
945
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_fb.c
Normal file
@@ -0,0 +1,945 @@
|
||||
/*
|
||||
* 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 "e2ap_msg_dec_fb.h"
|
||||
|
||||
#include "../free/e2ap_msg_free.h"
|
||||
#include "../e2ap_ap.h"
|
||||
#include "../ie/fb/e2ap_reader.h"
|
||||
#include "../global_consts.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static inline
|
||||
cause_t copy_cause(e2ap_Cause_union_t cause)
|
||||
{
|
||||
assert(e2ap_Cause_is_known_type(cause.type));
|
||||
cause_t ret;
|
||||
switch (cause.type) {
|
||||
case e2ap_Cause_ricRequest:
|
||||
assert(e2ap_RicRequest_ricRequestCause(cause.value) < 11);
|
||||
ret.ricRequest = e2ap_RicRequest_ricRequestCause(cause.value);
|
||||
ret.present = CAUSE_RICREQUEST;
|
||||
break;
|
||||
case e2ap_Cause_ricService:
|
||||
assert(e2ap_RicService_ricServiceCause(cause.value) < 3);
|
||||
ret.ricService = e2ap_RicService_ricServiceCause(cause.value);
|
||||
ret.present = CAUSE_RICSERVICE;
|
||||
break;
|
||||
case e2ap_Cause_transportLayer:
|
||||
assert(e2ap_TransportLayer_transportLayerCause(cause.value) < 2);
|
||||
ret.transport = e2ap_TransportLayer_transportLayerCause(cause.value);
|
||||
ret.present = CAUSE_TRANSPORT;
|
||||
break;
|
||||
case e2ap_Cause_protocol:
|
||||
assert(e2ap_Protocol_protocolCause(cause.value) < 7);
|
||||
ret.protocol = e2ap_Protocol_protocolCause(cause.value);
|
||||
ret.present = CAUSE_PROTOCOL;
|
||||
break;
|
||||
case e2ap_Cause_misc:
|
||||
assert(e2ap_Misc_miscellaneousCause(cause.value) < 4);
|
||||
ret.misc = e2ap_Misc_miscellaneousCause(cause.value);
|
||||
ret.present = CAUSE_MISC;
|
||||
break;
|
||||
case e2ap_Cause_NONE:
|
||||
assert(0 && "not implemented");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32_t get_time_to_wait(uint32_t ttw)
|
||||
{
|
||||
/* the ASN.1 encoding treats the time_to_wait_ms type as an enum, although it
|
||||
* is a uint32_t (in ms). For the time being, we will do the same, but
|
||||
* convert it from the ms value of the flatbuffers */
|
||||
if (ttw == 0)
|
||||
return 0;
|
||||
else if (ttw == 1)
|
||||
return 1;
|
||||
else if (ttw == 2)
|
||||
return 2;
|
||||
else if (ttw <= 5)
|
||||
return 3;
|
||||
else if (ttw <= 10)
|
||||
return 4;
|
||||
else if (ttw <= 20)
|
||||
return 5;
|
||||
else if (ttw <= 30)
|
||||
return 6;
|
||||
else if (ttw <= 40)
|
||||
return 7;
|
||||
else if (ttw <= 50)
|
||||
return 8;
|
||||
else if (ttw <= 100)
|
||||
return 9;
|
||||
else if (ttw <= 200)
|
||||
return 10;
|
||||
else if (ttw <= 500)
|
||||
return 11;
|
||||
else if (ttw <= 1000)
|
||||
return 12;
|
||||
else if (ttw <= 2000)
|
||||
return 13;
|
||||
else if (ttw <= 5000)
|
||||
return 14;
|
||||
else if (ttw <= 10000)
|
||||
return 15;
|
||||
else if (ttw <= 20000)
|
||||
return 16;
|
||||
else if (ttw <= 60000)
|
||||
return 17;
|
||||
else
|
||||
assert("illegal value for time to wait, cannot map to enum");
|
||||
assert(0 && "illegal code path");
|
||||
}
|
||||
|
||||
static inline
|
||||
byte_array_t copy_vec_uint8_to_ba(const uint8_t *b, size_t l)
|
||||
{
|
||||
uint8_t* buf = malloc(l);
|
||||
assert(buf);
|
||||
memcpy(buf, b, l);
|
||||
return (byte_array_t) { .buf = buf, .len = l};
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_subscription_request_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_subscriptionRequest);
|
||||
|
||||
e2ap_RicSubscriptionRequest_table_t fb_rsr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_SUBSCRIPTION_REQUEST};
|
||||
ric_subscription_request_t* sr = &ret.u_msgs.ric_sub_req;
|
||||
|
||||
assert(e2ap_RicSubscriptionRequest_requestId_is_present(fb_rsr));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicSubscriptionRequest_requestId(fb_rsr);
|
||||
sr->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
sr->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicSubscriptionRequest_ranFunctionId_is_present(fb_rsr));
|
||||
sr->ric_id.ran_func_id = e2ap_RicSubscriptionRequest_ranFunctionId(fb_rsr);
|
||||
|
||||
const uint8_t* event = e2ap_RicSubscriptionRequest_eventTriggerDefinition(fb_rsr);
|
||||
const size_t event_len = flatbuffers_uint8_vec_len(event);
|
||||
assert(event && event_len > 0);
|
||||
sr->event_trigger.buf = malloc(event_len);
|
||||
assert(sr->event_trigger.buf);
|
||||
memcpy(sr->event_trigger.buf, event, event_len);
|
||||
sr->event_trigger.len = event_len;
|
||||
|
||||
e2ap_Action_vec_t actions = e2ap_RicSubscriptionRequest_actions(fb_rsr);
|
||||
const int len_ra = e2ap_Action_vec_len(actions);
|
||||
assert(len_ra > 0 && len_ra <= MAX_NUM_ACTION_DEF );
|
||||
sr->len_action = len_ra;
|
||||
sr->action = calloc(len_ra, sizeof(ric_action_t));
|
||||
assert(sr->action);
|
||||
|
||||
for (int i = 0; i < len_ra; ++i) {
|
||||
e2ap_Action_table_t action = e2ap_Action_vec_at(actions, i);
|
||||
ric_action_t * dst = &sr->action[i];
|
||||
|
||||
dst->id = e2ap_Action_id(action);
|
||||
dst->type = e2ap_Action_type(action); /* maps one-to-one */
|
||||
|
||||
const uint8_t* definition = e2ap_Action_definition(action);
|
||||
const size_t definition_len = flatbuffers_uint8_vec_len(definition);
|
||||
if (definition && definition_len > 0) {
|
||||
dst->definition = malloc(sizeof(byte_array_t));
|
||||
assert(dst->definition);
|
||||
dst->definition->buf = malloc(definition_len);
|
||||
assert(dst->definition->buf);
|
||||
memcpy(dst->definition->buf, definition, definition_len);
|
||||
dst->definition->len = definition_len;
|
||||
}
|
||||
|
||||
e2ap_RicSubsequentAction_table_t rsa = e2ap_Action_subsequentAction(action);
|
||||
if (rsa) {
|
||||
dst->subseq_action = calloc(1, sizeof(ric_subsequent_action_t));
|
||||
assert(dst->subseq_action);
|
||||
e2ap_RicSubsequentActionType_enum_t rsat = e2ap_RicSubsequentAction_type(rsa);
|
||||
assert(rsat);
|
||||
dst->subseq_action->type = rsat;
|
||||
if (e2ap_RicSubsequentAction_timeToWait(rsa) != 0) {
|
||||
dst->subseq_action->time_to_wait_ms = malloc(sizeof(uint32_t));
|
||||
assert(dst->subseq_action->time_to_wait_ms);
|
||||
*dst->subseq_action->time_to_wait_ms = get_time_to_wait(e2ap_RicSubsequentAction_timeToWait(rsa));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_subscription_response_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_subscriptionResponse);
|
||||
|
||||
e2ap_RicSubscriptionResponse_table_t fb_rsr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_SUBSCRIPTION_RESPONSE};
|
||||
ric_subscription_response_t* sr = &ret.u_msgs.ric_sub_resp;
|
||||
|
||||
assert(e2ap_RicSubscriptionResponse_requestId_is_present(fb_rsr));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicSubscriptionResponse_requestId(fb_rsr);
|
||||
sr->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
sr->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicSubscriptionResponse_ranFunctionId_is_present(fb_rsr));
|
||||
sr->ric_id.ran_func_id = e2ap_RicSubscriptionResponse_ranFunctionId(fb_rsr);
|
||||
|
||||
e2ap_RicActionAdmitted_vec_t al = e2ap_RicSubscriptionResponse_admittedActions(fb_rsr);
|
||||
sr->len_admitted = e2ap_RicActionAdmitted_vec_len(al);
|
||||
assert(sr->len_admitted > 0);
|
||||
sr->admitted = calloc(sr->len_admitted, sizeof(*sr->admitted));
|
||||
assert(sr->admitted);
|
||||
for (size_t i = 0; i < sr->len_admitted; ++i) {
|
||||
e2ap_RicActionAdmitted_table_t admitted = e2ap_RicActionAdmitted_vec_at(al, i);
|
||||
ric_action_admitted_t* dst = &sr->admitted[i];
|
||||
dst->ric_act_id = e2ap_RicActionAdmitted_id(admitted);
|
||||
}
|
||||
|
||||
e2ap_RicActionNotAdmitted_vec_t nal = e2ap_RicSubscriptionResponse_notAdmittedActions(fb_rsr);
|
||||
sr->len_na = e2ap_RicActionNotAdmitted_vec_len(nal);
|
||||
if (sr->len_na > 0) {
|
||||
sr->not_admitted = calloc(sr->len_na, sizeof(ric_action_not_admitted_t));
|
||||
assert(sr->not_admitted);
|
||||
for (size_t i = 0; i < sr->len_na; ++i) {
|
||||
e2ap_RicActionNotAdmitted_table_t not_admitted = e2ap_RicActionNotAdmitted_vec_at(nal, i);
|
||||
ric_action_not_admitted_t* dst = &sr->not_admitted[i];
|
||||
dst->ric_act_id = e2ap_RicActionNotAdmitted_id(not_admitted);
|
||||
dst->cause = copy_cause(e2ap_RicActionNotAdmitted_cause_union(not_admitted));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_subscription_failure_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_subscriptionFailure);
|
||||
|
||||
e2ap_RicSubscriptionFailure_table_t fb_rsf = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_SUBSCRIPTION_FAILURE};
|
||||
ric_subscription_failure_t* sf = &ret.u_msgs.ric_sub_fail;
|
||||
|
||||
assert(e2ap_RicSubscriptionFailure_requestId_is_present(fb_rsf));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicSubscriptionFailure_requestId(fb_rsf);
|
||||
sf->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
sf->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicSubscriptionFailure_ranFunctionId_is_present(fb_rsf));
|
||||
sf->ric_id.ran_func_id = e2ap_RicSubscriptionFailure_ranFunctionId(fb_rsf);
|
||||
|
||||
e2ap_RicActionNotAdmitted_vec_t naa = e2ap_RicSubscriptionFailure_notAdmittedActions(fb_rsf);
|
||||
sf->len_na = e2ap_RicActionNotAdmitted_vec_len(naa);
|
||||
if (sf->len_na > 0) {
|
||||
sf->not_admitted = calloc(sf->len_na, sizeof(ric_action_not_admitted_t));
|
||||
assert(sf->not_admitted);
|
||||
for (size_t i = 0; i < sf->len_na; ++i) {
|
||||
e2ap_RicActionNotAdmitted_table_t not_admitted = e2ap_RicActionNotAdmitted_vec_at(naa, i);
|
||||
ric_action_not_admitted_t* dst = &sf->not_admitted[i];
|
||||
dst->ric_act_id = e2ap_RicActionNotAdmitted_id(not_admitted);
|
||||
dst->cause = copy_cause(e2ap_RicActionNotAdmitted_cause_union(not_admitted));
|
||||
}
|
||||
}
|
||||
|
||||
assert(!e2ap_RicSubscriptionFailure_criticalityDiagnostics_is_present(fb_rsf) && "decoding of criticality diagnostics is not implemented");
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_request_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_subscriptionDeleteRequest);
|
||||
|
||||
e2ap_RicSubscriptionDeleteRequest_table_t fb_sdr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_SUBSCRIPTION_DELETE_REQUEST};
|
||||
ric_subscription_delete_request_t* dr = &ret.u_msgs.ric_sub_del_req;
|
||||
|
||||
assert(e2ap_RicSubscriptionDeleteRequest_requestId_is_present(fb_sdr));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicSubscriptionDeleteRequest_requestId(fb_sdr);
|
||||
dr->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
dr->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicSubscriptionDeleteRequest_ranFunctionId_is_present(fb_sdr));
|
||||
dr->ric_id.ran_func_id = e2ap_RicSubscriptionDeleteRequest_ranFunctionId(fb_sdr);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_response_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_subscriptionDeleteResponse);
|
||||
|
||||
e2ap_RicSubscriptionDeleteResponse_table_t fb_sdr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_SUBSCRIPTION_DELETE_RESPONSE};
|
||||
ric_subscription_delete_response_t* dr = &ret.u_msgs.ric_sub_del_resp;
|
||||
|
||||
assert(e2ap_RicSubscriptionDeleteResponse_requestId_is_present(fb_sdr));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicSubscriptionDeleteResponse_requestId(fb_sdr);
|
||||
dr->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
dr->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicSubscriptionDeleteResponse_ranFunctionId_is_present(fb_sdr));
|
||||
dr->ric_id.ran_func_id = e2ap_RicSubscriptionDeleteResponse_ranFunctionId(fb_sdr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_failure_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_subscriptionDeleteFailure);
|
||||
|
||||
e2ap_RicSubscriptionDeleteFailure_table_t fb_sdf = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_SUBSCRIPTION_DELETE_FAILURE};
|
||||
ric_subscription_delete_failure_t* df = &ret.u_msgs.ric_sub_del_fail;
|
||||
|
||||
assert(e2ap_RicSubscriptionDeleteFailure_requestId_is_present(fb_sdf));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicSubscriptionDeleteFailure_requestId(fb_sdf);
|
||||
df->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
df->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicSubscriptionDeleteFailure_ranFunctionId_is_present(fb_sdf));
|
||||
df->ric_id.ran_func_id = e2ap_RicSubscriptionDeleteFailure_ranFunctionId(fb_sdf);
|
||||
|
||||
assert(e2ap_RicSubscriptionDeleteFailure_cause_is_present(fb_sdf));
|
||||
df->cause = copy_cause(e2ap_RicSubscriptionDeleteFailure_cause_union(fb_sdf));
|
||||
|
||||
assert(!e2ap_RicSubscriptionDeleteFailure_criticalityDiagnostics_is_present(fb_sdf) && "decoding of criticality diagnostics is not implemented");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_indication_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_indication);
|
||||
|
||||
e2ap_RicIndication_table_t fb_sdr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_INDICATION};
|
||||
ric_indication_t* ind = &ret.u_msgs.ric_ind;
|
||||
|
||||
assert(e2ap_RicIndication_requestId_is_present(fb_sdr));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicIndication_requestId(fb_sdr);
|
||||
ind->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
ind->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicIndication_ranFunctionId_is_present(fb_sdr));
|
||||
ind->ric_id.ran_func_id = e2ap_RicIndication_ranFunctionId(fb_sdr);
|
||||
|
||||
assert(e2ap_RicIndication_actionId_is_present(fb_sdr));
|
||||
ind->action_id = e2ap_RicIndication_actionId(fb_sdr);
|
||||
|
||||
if (e2ap_RicIndication_sn_is_present(fb_sdr)) {
|
||||
ind->sn = malloc(sizeof(*ind->sn));
|
||||
assert(ind->sn);
|
||||
*ind->sn = e2ap_RicIndication_sn(fb_sdr);
|
||||
}
|
||||
|
||||
assert(e2ap_RicIndication_indicationType_is_present(fb_sdr));
|
||||
ind->type = e2ap_RicIndication_indicationType(fb_sdr);
|
||||
|
||||
assert(e2ap_RicIndication_header_is_present(fb_sdr));
|
||||
const uint8_t* hdr = e2ap_RicIndication_header(fb_sdr);
|
||||
const size_t hdr_len = flatbuffers_uint8_vec_len(hdr);
|
||||
ind->hdr.buf = malloc(hdr_len);
|
||||
assert(ind->hdr.buf);
|
||||
memcpy(ind->hdr.buf, hdr, hdr_len);
|
||||
ind->hdr.len = hdr_len;
|
||||
|
||||
assert(e2ap_RicIndication_message_is_present(fb_sdr));
|
||||
const uint8_t* msg = e2ap_RicIndication_message(fb_sdr);
|
||||
const size_t msg_len = flatbuffers_uint8_vec_len(msg);
|
||||
ind->msg.buf = malloc(msg_len);
|
||||
assert(ind->msg.buf);
|
||||
memcpy(ind->msg.buf, msg, msg_len);
|
||||
ind->msg.len = msg_len;
|
||||
|
||||
if (e2ap_RicIndication_callProcessId_is_present(fb_sdr)) {
|
||||
const uint8_t* cpi = e2ap_RicIndication_callProcessId(fb_sdr);
|
||||
const size_t cpi_len = flatbuffers_uint8_vec_len(cpi);
|
||||
ind->call_process_id = malloc(cpi_len);
|
||||
assert(ind->call_process_id);
|
||||
memcpy(ind->call_process_id->buf, cpi, cpi_len);
|
||||
ind->call_process_id->len = cpi_len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_control_request_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_controlRequest);
|
||||
|
||||
e2ap_RicControlRequest_table_t fb_cr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_CONTROL_REQUEST };
|
||||
ric_control_request_t* ctrl = &ret.u_msgs.ric_ctrl_req;
|
||||
|
||||
assert(e2ap_RicControlRequest_requestId_is_present(fb_cr));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicControlRequest_requestId(fb_cr);
|
||||
ctrl->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
ctrl->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
/* the ran Function ID is not written in enc() when it is the default (0), so
|
||||
* do not assert on its presence */
|
||||
//assert(e2ap_RicControlRequest_ranFunctionId_is_present(fb_cr));
|
||||
ctrl->ric_id.ran_func_id = e2ap_RicControlRequest_ranFunctionId(fb_cr);
|
||||
|
||||
if (e2ap_RicControlRequest_callProcessId_is_present(fb_cr)) {
|
||||
const uint8_t* cpi = e2ap_RicControlRequest_callProcessId(fb_cr);
|
||||
const size_t cpi_len = flatbuffers_uint8_vec_len(cpi);
|
||||
ctrl->call_process_id = malloc(cpi_len);
|
||||
assert(ctrl->call_process_id);
|
||||
*ctrl->call_process_id = copy_vec_uint8_to_ba(cpi, cpi_len);
|
||||
}
|
||||
|
||||
assert(e2ap_RicControlRequest_header_is_present(fb_cr));
|
||||
const uint8_t* hdr = e2ap_RicControlRequest_header(fb_cr);
|
||||
const size_t hdr_len = flatbuffers_uint8_vec_len(hdr);
|
||||
ctrl->hdr = copy_vec_uint8_to_ba(hdr, hdr_len);
|
||||
|
||||
assert(e2ap_RicControlRequest_message_is_present(fb_cr));
|
||||
const uint8_t* msg = e2ap_RicControlRequest_message(fb_cr);
|
||||
const size_t msg_len = flatbuffers_uint8_vec_len(msg);
|
||||
ctrl->msg = copy_vec_uint8_to_ba(msg, msg_len);
|
||||
|
||||
if (e2ap_RicControlRequest_ackRequest_is_present(fb_cr)) {
|
||||
ctrl->ack_req = malloc(sizeof(*ctrl->ack_req));
|
||||
assert(ctrl->ack_req);
|
||||
*ctrl->ack_req = e2ap_RicControlRequest_ackRequest(fb_cr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_control_ack_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_controlAcknowledge);
|
||||
|
||||
e2ap_RicControlAcknowledge_table_t fb_ca = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_CONTROL_ACKNOWLEDGE};
|
||||
ric_control_acknowledge_t* ca = &ret.u_msgs.ric_ctrl_ack;
|
||||
|
||||
assert(e2ap_RicControlAcknowledge_requestId_is_present(fb_ca));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicControlAcknowledge_requestId(fb_ca);
|
||||
ca->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
ca->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicControlAcknowledge_ranFunctionId_is_present(fb_ca));
|
||||
ca->ric_id.ran_func_id = e2ap_RicControlAcknowledge_ranFunctionId(fb_ca);
|
||||
|
||||
if (e2ap_RicControlAcknowledge_callProcessId_is_present(fb_ca)) {
|
||||
const uint8_t* cpi = e2ap_RicControlAcknowledge_callProcessId(fb_ca);
|
||||
const size_t cpi_len = flatbuffers_uint8_vec_len(cpi);
|
||||
ca->call_process_id = malloc(cpi_len);
|
||||
assert(ca->call_process_id);
|
||||
*ca->call_process_id = copy_vec_uint8_to_ba(cpi, cpi_len);
|
||||
}
|
||||
|
||||
/* the outcome is not written in enc() when it is the default (0), so
|
||||
* do not assert on its presence */
|
||||
//assert(e2ap_RicControlAcknowledge_outcome_is_present(fb_ca));
|
||||
ca->status = e2ap_RicControlAcknowledge_status(fb_ca);
|
||||
|
||||
if (e2ap_RicControlAcknowledge_outcome_is_present(fb_ca)) {
|
||||
const uint8_t* oc = e2ap_RicControlAcknowledge_outcome(fb_ca);
|
||||
const size_t oc_len = flatbuffers_uint8_vec_len(oc);
|
||||
ca->control_outcome = malloc(oc_len);
|
||||
assert(ca->control_outcome);
|
||||
*ca->control_outcome = copy_vec_uint8_to_ba(oc, oc_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_control_failure_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_controlFailure);
|
||||
|
||||
e2ap_RicControlFailure_table_t fb_cf = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = RIC_CONTROL_FAILURE};
|
||||
ric_control_failure_t* cf = &ret.u_msgs.ric_ctrl_fail;
|
||||
|
||||
assert(e2ap_RicControlFailure_requestId_is_present(fb_cf));
|
||||
e2ap_RicRequestId_struct_t ricreq = e2ap_RicControlFailure_requestId(fb_cf);
|
||||
cf->ric_id.ric_req_id = ricreq->ricRequestorId;
|
||||
cf->ric_id.ric_inst_id = ricreq->ricInstanceId;
|
||||
|
||||
assert(e2ap_RicControlFailure_ranFunctionId_is_present(fb_cf));
|
||||
cf->ric_id.ran_func_id = e2ap_RicControlFailure_ranFunctionId(fb_cf);
|
||||
|
||||
if (e2ap_RicControlFailure_callProcessId_is_present(fb_cf)) {
|
||||
const uint8_t* cpi = e2ap_RicControlFailure_callProcessId(fb_cf);
|
||||
const size_t cpi_len = flatbuffers_uint8_vec_len(cpi);
|
||||
cf->call_process_id = malloc(cpi_len);
|
||||
assert(cf->call_process_id);
|
||||
*cf->call_process_id = copy_vec_uint8_to_ba(cpi, cpi_len);
|
||||
}
|
||||
|
||||
assert(e2ap_RicControlFailure_cause_is_present(fb_cf));
|
||||
cf->cause = copy_cause(e2ap_RicControlFailure_cause_union(fb_cf));
|
||||
|
||||
if (e2ap_RicControlFailure_outcome_is_present(fb_cf)) {
|
||||
const uint8_t* oc = e2ap_RicControlFailure_outcome(fb_cf);
|
||||
const size_t oc_len = flatbuffers_uint8_vec_len(oc);
|
||||
cf->control_outcome = malloc(oc_len);
|
||||
assert(cf->control_outcome);
|
||||
*cf->control_outcome = copy_vec_uint8_to_ba(oc, oc_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
e2ap_msg_t e2ap_dec_error_indication_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
(void) e2mt;
|
||||
|
||||
e2ap_msg_t ret = {.type = E2AP_ERROR_INDICATION};
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_setup_request_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_setupRequest);
|
||||
|
||||
e2ap_E2SetupRequest_table_t fb_sr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = E2_SETUP_REQUEST};
|
||||
e2_setup_request_t* sr = &ret.u_msgs.e2_stp_req;
|
||||
|
||||
e2ap_GlobalE2NodeId_union_t id = e2ap_E2SetupRequest_id_union(fb_sr);
|
||||
switch (id.type) {
|
||||
case e2ap_GlobalE2NodeId_gNB:
|
||||
sr->id.type = ngran_gNB;
|
||||
sr->id.plmn.mcc = e2ap_GNB_plmn(id.value)->mcc;
|
||||
sr->id.plmn.mnc = e2ap_GNB_plmn(id.value)->mnc;
|
||||
sr->id.plmn.mnc_digit_len = e2ap_GNB_plmn(id.value)->mnc_digit_length;
|
||||
sr->id.nb_id = e2ap_GNB_id(id.value);
|
||||
//if (e2ap_GNB_cu_up_id_is_present(id.value)) e2ap_GNB_cu_up_id(id.value)
|
||||
//if (e2ap_GNB_du_id_is_present(id.value)) e2ap_GNB_du_id(id.value)
|
||||
break;
|
||||
case e2ap_GlobalE2NodeId_engNB:
|
||||
//sr->id.type = ngran_ng_eNB_CU??;
|
||||
//e2ap_EngNB_plmn(id.value)->mcc, e2ap_EngNB_plmn(id.value)->mnc_digit_length,
|
||||
//e2ap_EngNB_plmn(id.value)->mnc, e2ap_EngNB_id(id.value)
|
||||
assert(0 && "en-gNB not implemented");
|
||||
break;
|
||||
case e2ap_GlobalE2NodeId_ngeNB:
|
||||
sr->id.type = ngran_ng_eNB;
|
||||
sr->id.plmn.mcc = e2ap_NgeNB_plmn(id.value)->mcc;
|
||||
sr->id.plmn.mnc = e2ap_NgeNB_plmn(id.value)->mnc;
|
||||
sr->id.plmn.mnc_digit_len = e2ap_NgeNB_plmn(id.value)->mnc_digit_length;
|
||||
sr->id.nb_id = e2ap_NgeNB_id(id.value);
|
||||
break;
|
||||
case e2ap_GlobalE2NodeId_eNB:
|
||||
sr->id.type = ngran_eNB;
|
||||
sr->id.plmn.mcc = e2ap_ENB_plmn(id.value)->mcc;
|
||||
sr->id.plmn.mnc = e2ap_ENB_plmn(id.value)->mnc;
|
||||
sr->id.plmn.mnc_digit_len = e2ap_ENB_plmn(id.value)->mnc_digit_length;
|
||||
sr->id.nb_id = e2ap_ENB_id(id.value);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "no ID present\n");
|
||||
break;
|
||||
}
|
||||
|
||||
e2ap_RanFunction_vec_t ranFunctions = e2ap_E2SetupRequest_ranFunctions(fb_sr);
|
||||
const size_t len_rf = e2ap_RanFunction_vec_len(ranFunctions);
|
||||
sr->len_rf = len_rf;
|
||||
if (sr->len_rf > 0) {
|
||||
sr->ran_func_item = calloc(len_rf, sizeof(*sr->ran_func_item));
|
||||
assert(sr->ran_func_item);
|
||||
for (size_t i = 0; i < len_rf; ++i) {
|
||||
e2ap_RanFunction_table_t rf = e2ap_RanFunction_vec_at(ranFunctions, i);
|
||||
ran_function_t* dst = &sr->ran_func_item[i];
|
||||
|
||||
assert(e2ap_RanFunction_id(rf) <= MAX_RAN_FUNC_ID);
|
||||
dst->id = e2ap_RanFunction_id(rf);
|
||||
|
||||
assert(e2ap_RanFunction_revision(rf) > -1 && e2ap_RanFunction_revision(rf) <= MAX_RAN_FUNC_REV);
|
||||
dst->rev = e2ap_RanFunction_revision(rf);
|
||||
|
||||
const uint8_t* definition = e2ap_RanFunction_definition(rf);
|
||||
const size_t definition_len = flatbuffers_uint8_vec_len(definition);
|
||||
assert(definition && definition_len > 0);
|
||||
dst->def = copy_vec_uint8_to_ba(definition, definition_len);
|
||||
|
||||
if (e2ap_RanFunction_oid_is_present(rf)) {
|
||||
dst->oid = malloc(sizeof(*dst->oid));
|
||||
assert(dst->oid);
|
||||
const char* oid = e2ap_RanFunction_oid(rf);
|
||||
const size_t oid_len = flatbuffers_string_len(oid);
|
||||
*dst->oid = copy_vec_uint8_to_ba((uint8_t*) oid, oid_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e2ap_E2NodeCompConfUpdateItem_vec_t e2nccuis = e2ap_E2SetupRequest_e2NodeComponentConfigurationUpdateList(fb_sr);
|
||||
const size_t len_ccu = e2ap_RanFunction_vec_len(e2nccuis);
|
||||
sr->len_ccu = len_ccu;
|
||||
if (sr->len_ccu > 0) {
|
||||
sr->comp_conf_update = calloc(len_ccu, sizeof(*sr->ran_func_item));
|
||||
assert(sr->comp_conf_update);
|
||||
for (size_t i = 0; i < len_ccu; ++i) {
|
||||
e2ap_E2NodeCompConfUpdateItem_table_t e2nccui = e2ap_E2NodeCompConfUpdateItem_vec_at(e2nccuis, i);
|
||||
e2_node_component_config_update_t* dst = &sr->comp_conf_update[i];
|
||||
|
||||
dst->e2_node_component_type = e2ap_E2NodeCompConfUpdateItem_type(e2nccui);
|
||||
|
||||
if (e2ap_E2NodeCompConfUpdateItem_id_is_present(e2nccui)) {
|
||||
dst->id_present = malloc(sizeof(*dst->id_present));
|
||||
assert(dst->id_present);
|
||||
e2ap_E2NodeCompId_union_t id = e2ap_E2NodeCompConfUpdateItem_id_union(e2nccui);
|
||||
switch (id.type) {
|
||||
case e2ap_E2NodeCompId_gnb_cu_up:
|
||||
*dst->id_present = E2_NODE_COMPONENT_ID_E2_NODE_COMPONENT_TYPE_GNB_CU_UP;
|
||||
dst->gnb_cu_up_id = e2ap_E2NCId_id(id.value);
|
||||
break;
|
||||
case e2ap_E2NodeCompId_gnb_du:
|
||||
*dst->id_present = E2_NODE_COMPONENT_ID_E2_NODE_COMPONENT_TYPE_GNB_DU;
|
||||
dst->gnb_du_id = e2ap_E2NCId_id(id.value);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "unhandled E2NodeCompId type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
e2ap_E2NodeCompConfUpdate_union_t ccu = e2ap_E2NodeCompConfUpdateItem_update_union(e2nccui);
|
||||
switch (ccu.type) {
|
||||
case e2ap_E2NodeCompConfUpdate_gnb:
|
||||
assert(0 && "not implemented yet");
|
||||
break;
|
||||
case e2ap_E2NodeCompConfUpdate_en_gnb:
|
||||
dst->update_present = E2_NODE_COMPONENT_CONFIG_UPDATE_EN_GNB_CONFIG_UPDATE;
|
||||
const uint8_t* x2ap_en_gnb = e2ap_en_gnbE2NodeCompConfUpdate_x2ap_en_gnb(ccu.value);
|
||||
const size_t x2ap_en_gnb_len = flatbuffers_uint8_vec_len(x2ap_en_gnb);
|
||||
if (x2ap_en_gnb && x2ap_en_gnb_len > 0) {
|
||||
dst->en_gnb.x2ap_en_gnb = malloc(sizeof(byte_array_t) );
|
||||
assert(dst->en_gnb.x2ap_en_gnb);
|
||||
*dst->en_gnb.x2ap_en_gnb = copy_vec_uint8_to_ba(x2ap_en_gnb, x2ap_en_gnb_len);
|
||||
}
|
||||
break;
|
||||
case e2ap_E2NodeCompConfUpdate_ng_enb:
|
||||
assert(0 && "not implemented yet");
|
||||
break;
|
||||
case e2ap_E2NodeCompConfUpdate_enb:
|
||||
assert(0 && "not implemented yet");
|
||||
break;
|
||||
default:
|
||||
assert(0 && "unhandled E2NodeCompConfUpdate");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_dec_setup_response_fb(e2ap_E2Message_table_t e2mt)
|
||||
{
|
||||
assert(e2mt);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2mt);
|
||||
assert(fb_msg.type == e2ap_Message_setupResponse);
|
||||
|
||||
e2ap_E2SetupResponse_table_t fb_sr = fb_msg.value;
|
||||
|
||||
e2ap_msg_t ret = {.type = E2_SETUP_RESPONSE };
|
||||
e2_setup_response_t* sr = &ret.u_msgs.e2_stp_resp;
|
||||
|
||||
assert(e2ap_E2SetupResponse_globalRicId_is_present(fb_sr));
|
||||
e2ap_GlobalRicId_table_t id = e2ap_E2SetupResponse_globalRicId(fb_sr);
|
||||
sr->id.plmn.mcc = e2ap_GlobalRicId_plmn(id)->mcc;
|
||||
sr->id.plmn.mnc = e2ap_GlobalRicId_plmn(id)->mnc;
|
||||
sr->id.plmn.mnc_digit_len = e2ap_GlobalRicId_plmn(id)->mnc_digit_length;
|
||||
sr->id.near_ric_id.double_word = e2ap_GlobalRicId_nearRtRicId(id);
|
||||
|
||||
flatbuffers_uint16_vec_t accepted = e2ap_E2SetupResponse_acceptedRanFunctions(fb_sr);
|
||||
const size_t len_acc = flatbuffers_uint16_vec_len(accepted);
|
||||
sr->len_acc = len_acc;
|
||||
if (len_acc > 0) {
|
||||
sr->accepted = malloc(sr->len_acc * sizeof(*sr->accepted));
|
||||
assert(sr->accepted);
|
||||
for (size_t i = 0; i < sr->len_acc; ++i)
|
||||
sr->accepted[i] = flatbuffers_uint16_vec_at(accepted, i);
|
||||
}
|
||||
|
||||
e2ap_RejectedRanFunction_vec_t rejected = e2ap_E2SetupResponse_rejectedRanFunctions(fb_sr);
|
||||
const size_t len_rej = e2ap_RejectedRanFunction_vec_len(rejected);
|
||||
sr->len_rej = len_rej;
|
||||
if (len_rej > 0) {
|
||||
sr->rejected = malloc(sr->len_rej * sizeof(*sr->rejected));
|
||||
assert(sr->rejected);
|
||||
for (size_t i = 0; i < sr->len_rej; ++i) {
|
||||
e2ap_RejectedRanFunction_table_t rej = e2ap_RejectedRanFunction_vec_at(rejected, i);
|
||||
rejected_ran_function_t* dst = &sr->rejected[i];
|
||||
dst->id = e2ap_RejectedRanFunction_ranFunctionId(rej);
|
||||
dst->cause = copy_cause(e2ap_RejectedRanFunction_cause_union(rej));
|
||||
}
|
||||
}
|
||||
|
||||
e2ap_E2NodeCompConfUpdateAckItem_vec_t updateAcks = e2ap_E2SetupResponse_updateAck(fb_sr);
|
||||
const size_t len_ccual = e2ap_E2NodeCompConfUpdateAckItem_vec_len(updateAcks);
|
||||
sr->len_ccual = len_ccual;
|
||||
if (len_ccual > 0) {
|
||||
sr->comp_conf_update_ack_list = malloc(sr->len_ccual * sizeof(*sr->comp_conf_update_ack_list));
|
||||
assert(sr->comp_conf_update_ack_list);
|
||||
for (size_t i = 0; i < sr->len_ccual; ++i) {
|
||||
e2ap_E2NodeCompConfUpdateAckItem_table_t ua = e2ap_E2NodeCompConfUpdateAckItem_vec_at(updateAcks, i);
|
||||
assert(0 && "not implemented");
|
||||
/*
|
||||
printf(" [%d] acked Update Item type %s",
|
||||
i, e2ap_E2NodeCompType_name(e2ap_E2NodeCompConfUpdateAckItem_type(ua)));
|
||||
if (e2ap_E2NodeCompConfUpdateAckItem_id_is_present(ua)) {
|
||||
e2ap_E2NodeCompId_union_t id = e2ap_E2NodeCompConfUpdateAckItem_id_union(ua);
|
||||
switch (id.type) {
|
||||
case e2ap_E2NodeCompId_gnb_cu_up:
|
||||
printf(" ID gNB CU-UP %ld", ((e2ap_E2NCId_t *)id.value)->id);
|
||||
break;
|
||||
case e2ap_E2NodeCompId_gnb_du:
|
||||
printf(" ID gNB DU %ld", ((e2ap_E2NCId_t *)id.value)->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
e2ap_E2NodeCompConfUpdateAck_table_t ack = e2ap_E2NodeCompConfUpdateAckItem_updateAck(ua);
|
||||
if (e2ap_E2NodeCompConfUpdateAck_outcome(ack) == e2ap_E2NodeCompConfUpdateAckOutcome_Success)
|
||||
printf(" outcome SUCCESS\n");
|
||||
else
|
||||
printf(" outcome Failure Cause %s\n", get_e2ap_Cause_name(e2ap_E2NodeCompConfUpdateAck_cause_union(ack)));
|
||||
*/
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_setup_failure_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_reset_request_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_reset_response_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_service_update_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_update_ack_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_update_failure_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_query_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_ack_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_failure_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_connection_update_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_connection_update_ack_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_connection_update_failure_fb(e2ap_E2Message_table_t t)
|
||||
{
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
e2ap_msg_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
e2_msg_type_t e2ap_get_msg_type(e2ap_Message_union_type_t e2mut)
|
||||
{
|
||||
switch (e2mut) {
|
||||
case e2ap_Message_setupRequest: return E2_SETUP_REQUEST;
|
||||
case e2ap_Message_setupResponse: return E2_SETUP_RESPONSE;
|
||||
//case e2ap_Message_setupFailure: return E2_SETUP_FAILURE;
|
||||
//case e2ap_Message_errorIndication: return E2AP_ERROR_INDICATION;
|
||||
//case e2ap_Message_resetRequest: return E2AP_RESET_REQUEST;
|
||||
//case e2ap_Message_resetResponse: return E2AP_RESET_RESPONSE;
|
||||
case e2ap_Message_controlRequest: return RIC_CONTROL_REQUEST;
|
||||
case e2ap_Message_controlAcknowledge: return RIC_CONTROL_ACKNOWLEDGE;
|
||||
case e2ap_Message_controlFailure: return RIC_CONTROL_FAILURE;
|
||||
case e2ap_Message_indication: return RIC_INDICATION;
|
||||
//case e2ap_Message_serviceQuery: return RIC_SERVICE_QUERY;
|
||||
//case e2ap_Message_serviceUpdate: return RIC_SERVICE_UPDATE;
|
||||
//case e2ap_Message_serviceUpdateAcknowledge: return RIC_SERVICE_UPDATE_ACKNOWLEDGE;
|
||||
//case e2ap_Message_serviceUpdateFailure: return RIC_SERVICE_UPDATE_FAILURE;
|
||||
case e2ap_Message_subscriptionRequest: return RIC_SUBSCRIPTION_REQUEST;
|
||||
case e2ap_Message_subscriptionResponse: return RIC_SUBSCRIPTION_RESPONSE;
|
||||
case e2ap_Message_subscriptionFailure: return RIC_SUBSCRIPTION_FAILURE;
|
||||
case e2ap_Message_subscriptionDeleteRequest: return RIC_SUBSCRIPTION_DELETE_REQUEST;
|
||||
case e2ap_Message_subscriptionDeleteResponse: return RIC_SUBSCRIPTION_DELETE_RESPONSE;
|
||||
case e2ap_Message_subscriptionDeleteFailure: return RIC_SUBSCRIPTION_DELETE_FAILURE;
|
||||
//case e2ap_Message_nodeConfigurationUpdate: return E2_NODE_CONFIGURATION_UPDATE;
|
||||
//case e2ap_Message_nodeConfigurationUpdateAcknowledge: return E2_NODE_CONFIGURATION_UPDATE_ACKNOWLEDGE;
|
||||
//case e2ap_Message_nodeConfigurationUpdateFailure: return E2_NODE_CONFIGURATION_UPDATE_FAILURE;
|
||||
//case e2ap_Message_connectionUpdate: return E2_CONNECTION_UPDATE;
|
||||
//case e2ap_Message_connectionUpdateAcknowledge: return E2_CONNECTION_UPDATE_ACKNOWLEDGE;
|
||||
//case e2ap_Message_connectionUpdateFailure: return E2_CONNECTION_UPDATE_FAILURE;
|
||||
default: assert(0 && "unhandled message");
|
||||
}
|
||||
assert(0 && "invalid path");
|
||||
}
|
||||
|
||||
e2ap_msg_t e2ap_msg_dec_fb(e2ap_fb_t* fb, byte_array_t ba)
|
||||
{
|
||||
assert(ba.buf != NULL && ba.len > 0);
|
||||
e2ap_E2Message_table_t e2m = e2ap_E2Message_as_root(ba.buf);
|
||||
assert(e2m);
|
||||
e2ap_Message_union_t fb_msg = e2ap_E2Message_msg_union(e2m);
|
||||
const e2_msg_type_t msg_type = e2ap_get_msg_type(fb_msg.type);
|
||||
|
||||
assert(fb->dec_msg[msg_type] && "unhandled message");
|
||||
e2ap_msg_t msg = fb->dec_msg[msg_type](e2m);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
143
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_fb.h
Normal file
143
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_fb.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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 E2AP_MSG_DEC_FB_H
|
||||
#define E2AP_MSG_DEC_FB_H
|
||||
|
||||
#include "lib/v1/ap/type_defs.h"
|
||||
|
||||
typedef const struct e2ap_E2Message_table *e2ap_E2Message_table_t;
|
||||
struct e2ap_fb;
|
||||
|
||||
e2ap_msg_t e2ap_msg_dec_fb(struct e2ap_fb* enc, byte_array_t ba);
|
||||
|
||||
void init_ap_fb(struct e2ap_fb*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// O-RAN E2APv01.01: Messages for Global Procedures ///////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_subscription_request_fb(e2ap_E2Message_table_t);
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_response_fb(e2ap_E2Message_table_t);
|
||||
|
||||
//E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_failure_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
//RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_request_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_response_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
//E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_subscription_delete_failure_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_indication_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_control_request_fb( e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_control_ack_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_control_failure_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// O-RAN E2APv01.01: Messages for Global Procedures ///////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_error_indication_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_setup_request_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_setup_response_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_setup_failure_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_reset_request_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC <-> E2
|
||||
e2ap_msg_t e2ap_dec_reset_response_fb(e2ap_E2Message_table_t );
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_service_update_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_update_ack_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_update_failure_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_service_query_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_ack_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_node_configuration_update_failure_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// RIC -> E2
|
||||
e2ap_msg_t e2ap_dec_connection_update_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_connection_update_ack_fb(e2ap_E2Message_table_t);
|
||||
|
||||
|
||||
// E2 -> RIC
|
||||
e2ap_msg_t e2ap_dec_connection_update_failure_fb(e2ap_E2Message_table_t);
|
||||
|
||||
#endif
|
||||
40
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_generic.h
Normal file
40
openair2/E2AP/lib/v1/ap/dec/e2ap_msg_dec_generic.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 E2AP_MSG_DEC_GENERIC_H
|
||||
#define E2AP_MSG_DEC_GENERIC_H
|
||||
|
||||
#include "e2ap_msg_dec_asn.h"
|
||||
#include "e2ap_msg_dec_fb.h"
|
||||
|
||||
|
||||
#define e2ap_msg_dec_gen(T,U) _Generic ((T), e2ap_asn_t*: e2ap_msg_dec_asn, \
|
||||
e2ap_fb_t*: e2ap_msg_dec_fb, \
|
||||
default: e2ap_msg_dec_asn) (T,U)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
75
openair2/E2AP/lib/v1/ap/e2ap_ap.h
Normal file
75
openair2/E2AP/lib/v1/ap/e2ap_ap.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 E2AP_APPLICATION_PROTOCOL
|
||||
#define E2AP_APPLICATION_PROTOCOL
|
||||
|
||||
#include <assert.h>
|
||||
#include "lib/v1/ap/type_defs.h"
|
||||
|
||||
#include "e2ap_ap_asn.h"
|
||||
#include "e2ap_ap_fb.h"
|
||||
|
||||
struct E2AP_E2AP_PDU;
|
||||
typedef e2ap_msg_t (*e2ap_gen_dec_asn_fp)(const struct E2AP_E2AP_PDU*);
|
||||
typedef byte_array_t (*e2ap_gen_enc_asn_fp)(const e2ap_msg_t*);
|
||||
|
||||
struct e2ap_E2Message_table;
|
||||
typedef e2ap_msg_t (*e2ap_gen_dec_fb_fp)(const struct e2ap_E2Message_table*);
|
||||
typedef byte_array_t (*e2ap_gen_enc_fb_fp)(const e2ap_msg_t*);
|
||||
|
||||
|
||||
typedef void (*e2ap_free_fp)(e2ap_msg_t*);
|
||||
|
||||
typedef struct e2ap_asn{
|
||||
e2ap_gen_enc_asn_fp enc_msg[31];
|
||||
e2ap_gen_dec_asn_fp dec_msg[31];
|
||||
e2ap_free_fp free_msg[31];
|
||||
} e2ap_asn_t;
|
||||
|
||||
typedef struct e2ap_fb{
|
||||
e2ap_gen_enc_fb_fp enc_msg[31];
|
||||
e2ap_gen_dec_fb_fp dec_msg[31];
|
||||
e2ap_free_fp free_msg[31];
|
||||
} e2ap_fb_t;
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
#ifdef E2AP_ASN
|
||||
e2ap_asn_t type;
|
||||
#elif E2AP_FLATBUFFERS
|
||||
e2ap_fb_t type;
|
||||
#else
|
||||
static_assert(0!=0, "Error. No encoding scheme selected");
|
||||
#endif
|
||||
|
||||
} e2ap_ap_t;
|
||||
|
||||
|
||||
#define init_ap(T) _Generic ((T), e2ap_asn_t*: init_ap_asn, \
|
||||
e2ap_fb_t*: init_ap_fb, \
|
||||
default: init_ap_asn) (T)
|
||||
|
||||
#endif
|
||||
|
||||
139
openair2/E2AP/lib/v1/ap/e2ap_ap_asn.c
Normal file
139
openair2/E2AP/lib/v1/ap/e2ap_ap_asn.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 "e2ap_ap_asn.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lib/v1/ap/dec/e2ap_msg_dec_generic.h"
|
||||
#include "lib/v1/ap/enc/e2ap_msg_enc_generic.h"
|
||||
#include "lib/v1/ap/free/e2ap_msg_free.h"
|
||||
|
||||
void init_ap_asn(e2ap_asn_t* asn)
|
||||
{
|
||||
assert(asn != NULL);
|
||||
|
||||
// Encoding functions
|
||||
asn->enc_msg[0] = e2ap_enc_subscription_request_asn_msg;
|
||||
asn->enc_msg[1] = e2ap_enc_subscription_response_asn_msg;
|
||||
asn->enc_msg[2] = e2ap_enc_subscription_failure_asn_msg;
|
||||
asn->enc_msg[3] = e2ap_enc_subscription_delete_request_asn_msg;
|
||||
asn->enc_msg[4] = e2ap_enc_subscription_delete_response_asn_msg;
|
||||
asn->enc_msg[5] = e2ap_enc_subscription_delete_failure_asn_msg;
|
||||
asn->enc_msg[6] = e2ap_enc_indication_asn_msg;
|
||||
asn->enc_msg[7] = e2ap_enc_control_request_asn_msg;
|
||||
asn->enc_msg[8] = e2ap_enc_control_ack_asn_msg;
|
||||
asn->enc_msg[9] = e2ap_enc_control_failure_asn_msg;
|
||||
asn->enc_msg[10] = e2ap_enc_error_indication_asn_msg;
|
||||
asn->enc_msg[11] = e2ap_enc_setup_request_asn_msg;
|
||||
asn->enc_msg[12] = e2ap_enc_setup_response_asn_msg;
|
||||
asn->enc_msg[13] = e2ap_enc_setup_failure_asn_msg;
|
||||
asn->enc_msg[14] = e2ap_enc_reset_request_asn_msg;
|
||||
asn->enc_msg[15] = e2ap_enc_reset_response_asn_msg;
|
||||
asn->enc_msg[16] = e2ap_enc_service_update_asn_msg;
|
||||
asn->enc_msg[17] = e2ap_enc_service_update_ack_asn_msg;
|
||||
asn->enc_msg[18] = e2ap_enc_service_update_failure_asn_msg;
|
||||
asn->enc_msg[19] = e2ap_enc_service_query_asn_msg;
|
||||
asn->enc_msg[20] = e2ap_enc_node_configuration_update_asn_msg;
|
||||
asn->enc_msg[21] = e2ap_enc_node_configuration_update_ack_asn_msg;
|
||||
asn->enc_msg[22] = e2ap_enc_node_configuration_update_failure_asn_msg;
|
||||
asn->enc_msg[23] = e2ap_enc_node_connection_update_asn_msg;
|
||||
asn->enc_msg[24] = e2ap_enc_node_connection_update_ack_asn_msg;
|
||||
asn->enc_msg[25] = e2ap_enc_node_connection_update_failure_asn_msg;
|
||||
asn->enc_msg[26] = e2ap_enc_e42_setup_request_asn_msg;
|
||||
asn->enc_msg[27] = e2ap_enc_e42_setup_response_asn_msg;
|
||||
|
||||
asn->enc_msg[28] = e2ap_enc_e42_subscription_request_asn_msg;
|
||||
asn->enc_msg[29] = e2ap_enc_e42_subscription_delete_request_asn_msg;
|
||||
|
||||
asn->enc_msg[30] = e2ap_enc_e42_control_request_asn_msg;
|
||||
|
||||
// Decoding Functions
|
||||
asn->dec_msg[0] = e2ap_dec_subscription_request;
|
||||
asn->dec_msg[1] = e2ap_dec_subscription_response;
|
||||
asn->dec_msg[2] = e2ap_dec_subscription_failure;
|
||||
asn->dec_msg[3] = e2ap_dec_subscription_delete_request;
|
||||
asn->dec_msg[4] = e2ap_dec_subscription_delete_response;
|
||||
asn->dec_msg[5] = e2ap_dec_subscription_delete_failure;
|
||||
asn->dec_msg[6] = e2ap_dec_indication;
|
||||
asn->dec_msg[7] = e2ap_dec_control_request;
|
||||
asn->dec_msg[8] = e2ap_dec_control_ack;
|
||||
asn->dec_msg[9] = e2ap_dec_control_failure;
|
||||
asn->dec_msg[10] = e2ap_dec_error_indication;
|
||||
asn->dec_msg[11] = e2ap_dec_setup_request;
|
||||
asn->dec_msg[12] = e2ap_dec_setup_response;
|
||||
asn->dec_msg[13] = e2ap_dec_setup_failure;
|
||||
asn->dec_msg[14] = e2ap_dec_reset_request;
|
||||
asn->dec_msg[15] = e2ap_dec_reset_response;
|
||||
asn->dec_msg[16] = e2ap_dec_service_update;
|
||||
asn->dec_msg[17] = e2ap_dec_service_update_ack;
|
||||
asn->dec_msg[18] = e2ap_dec_service_update_failure;
|
||||
asn->dec_msg[19] = e2ap_dec_service_query;
|
||||
asn->dec_msg[20] = e2ap_dec_node_configuration_update;
|
||||
asn->dec_msg[21] = e2ap_dec_node_configuration_update_ack;
|
||||
asn->dec_msg[22] = e2ap_dec_node_configuration_update_failure;
|
||||
asn->dec_msg[23] = e2ap_dec_connection_update;
|
||||
asn->dec_msg[24] = e2ap_dec_connection_update_ack;
|
||||
asn->dec_msg[25] = e2ap_dec_connection_update_failure;
|
||||
asn->dec_msg[26] = e2ap_dec_e42_setup_request;
|
||||
asn->dec_msg[27] = e2ap_dec_e42_setup_response;
|
||||
asn->dec_msg[28] = e2ap_dec_e42_subscription_request;
|
||||
asn->dec_msg[29] = e2ap_dec_e42_subscription_delete_request;
|
||||
asn->dec_msg[30] = e2ap_dec_e42_control_request;
|
||||
|
||||
// Free Functions
|
||||
asn->free_msg[0] = e2ap_free_subscription_request_msg;
|
||||
asn->free_msg[1] = e2ap_free_subscription_response_msg;
|
||||
asn->free_msg[2] = e2ap_free_subscription_failure_msg;
|
||||
asn->free_msg[3] = e2ap_free_subscription_delete_request_msg;
|
||||
asn->free_msg[4] = e2ap_free_subscription_delete_response_msg;
|
||||
asn->free_msg[5] = e2ap_free_subscription_delete_failure_msg;
|
||||
asn->free_msg[6] = e2ap_free_indication_msg;
|
||||
asn->free_msg[7] = e2ap_free_control_request_msg;
|
||||
asn->free_msg[8] = e2ap_free_control_ack_msg;
|
||||
asn->free_msg[9] = e2ap_free_control_failure_msg;
|
||||
asn->free_msg[10] = e2ap_free_error_indication_msg;
|
||||
asn->free_msg[11] = e2ap_free_setup_request_msg;
|
||||
asn->free_msg[12] = e2ap_free_setup_response_msg;
|
||||
asn->free_msg[13] = e2ap_free_setup_failure_msg;
|
||||
asn->free_msg[14] = e2ap_free_reset_request_msg;
|
||||
asn->free_msg[15] = e2ap_free_reset_response_msg;
|
||||
asn->free_msg[16] = e2ap_free_service_update_msg;
|
||||
asn->free_msg[17] = e2ap_free_service_update_ack_msg;
|
||||
asn->free_msg[18] = e2ap_free_service_update_failure_msg;
|
||||
asn->free_msg[19] = e2ap_free_service_query_msg;
|
||||
asn->free_msg[20] = e2ap_free_node_configuration_update_msg;
|
||||
asn->free_msg[21] = e2ap_free_node_configuration_update_ack_msg;
|
||||
asn->free_msg[22] = e2ap_free_node_configuration_update_failure_msg;
|
||||
asn->free_msg[23] = e2ap_free_node_connection_update_msg;
|
||||
asn->free_msg[24] = e2ap_free_node_connection_update_ack_msg;
|
||||
asn->free_msg[25] = e2ap_free_node_connection_update_failure_msg;
|
||||
asn->free_msg[26] = e2ap_free_e42_setup_request_msg;
|
||||
asn->free_msg[27] = e2ap_free_e42_setup_response_msg;
|
||||
asn->free_msg[28] = e2ap_free_e42_ric_subscription_request_msg;
|
||||
asn->free_msg[29] = e2ap_free_e42_ric_subscription_delete_request_msg;
|
||||
asn->free_msg[30] = e2ap_free_e42_ric_control_request_msg;
|
||||
|
||||
}
|
||||
|
||||
35
openair2/E2AP/lib/v1/ap/e2ap_ap_asn.h
Normal file
35
openair2/E2AP/lib/v1/ap/e2ap_ap_asn.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 E2AP_APPLICATION_PROTOCOL_ASN
|
||||
#define E2AP_APPLICATION_PROTOCOL_ASN
|
||||
|
||||
#include "e2ap_ap.h"
|
||||
|
||||
typedef struct e2ap_asn e2ap_asn_t;
|
||||
|
||||
void init_ap_asn(e2ap_asn_t* asn);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
121
openair2/E2AP/lib/v1/ap/e2ap_ap_fb.c
Normal file
121
openair2/E2AP/lib/v1/ap/e2ap_ap_fb.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "e2ap_ap_fb.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dec/e2ap_msg_dec_generic.h"
|
||||
#include "enc/e2ap_msg_enc_generic.h"
|
||||
#include "free/e2ap_msg_free.h"
|
||||
|
||||
void init_ap_fb(e2ap_fb_t* fb)
|
||||
{
|
||||
assert(fb != NULL);
|
||||
|
||||
// Encoding Fucntions
|
||||
fb->enc_msg[0] = e2ap_enc_subscription_request_fb_msg;
|
||||
fb->enc_msg[1] = e2ap_enc_subscription_response_fb_msg;
|
||||
fb->enc_msg[2] = e2ap_enc_subscription_failure_fb_msg;
|
||||
fb->enc_msg[3] = e2ap_enc_subscription_delete_request_fb_msg;
|
||||
fb->enc_msg[4] = e2ap_enc_subscription_delete_response_fb_msg;
|
||||
fb->enc_msg[5] = e2ap_enc_subscription_delete_failure_fb_msg;
|
||||
fb->enc_msg[6] = e2ap_enc_indication_fb_msg;
|
||||
fb->enc_msg[7] = e2ap_enc_control_request_fb_msg;
|
||||
fb->enc_msg[8] = e2ap_enc_control_ack_fb_msg;
|
||||
fb->enc_msg[9] = e2ap_enc_control_failure_fb_msg;
|
||||
fb->enc_msg[10] = NULL;//e2ap_dec_error_indication;
|
||||
fb->enc_msg[11] = e2ap_enc_setup_request_fb_msg;
|
||||
fb->enc_msg[12] = e2ap_enc_setup_response_fb_msg;
|
||||
fb->enc_msg[13] = NULL;//e2ap_dec_setup_failure;
|
||||
fb->enc_msg[14] = NULL;//e2ap_dec_reset_request;
|
||||
fb->enc_msg[15] = NULL;//e2ap_dec_reset_response;
|
||||
fb->enc_msg[16] = NULL;//e2ap_dec_service_update;
|
||||
fb->enc_msg[17] = NULL;//e2ap_dec_service_update_ack;
|
||||
fb->enc_msg[18] = NULL;//e2ap_dec_service_update_failure;
|
||||
fb->enc_msg[19] = NULL;//e2ap_dec_service_query;
|
||||
fb->enc_msg[20] = NULL;//e2ap_dec_node_configuration_update;
|
||||
fb->enc_msg[21] = NULL;//e2ap_dec_node_configuration_update_ack;
|
||||
fb->enc_msg[22] = NULL;//e2ap_dec_node_configuration_update_failure;
|
||||
fb->enc_msg[23] = NULL;//e2ap_dec_connection_update;
|
||||
fb->enc_msg[24] = NULL;//e2ap_dec_connection_update_ack;
|
||||
fb->enc_msg[25] = NULL;//e2ap_dec_connection_update_failure;
|
||||
|
||||
// Decoding Functions
|
||||
fb->dec_msg[0] = e2ap_dec_subscription_request_fb;
|
||||
fb->dec_msg[1] = e2ap_dec_subscription_response_fb;
|
||||
fb->dec_msg[2] = e2ap_dec_subscription_failure_fb;
|
||||
fb->dec_msg[3] = e2ap_dec_subscription_delete_request_fb;
|
||||
fb->dec_msg[4] = e2ap_dec_subscription_delete_response_fb;
|
||||
fb->dec_msg[5] = e2ap_dec_subscription_delete_failure_fb;
|
||||
fb->dec_msg[6] = e2ap_dec_indication_fb;
|
||||
fb->dec_msg[7] = e2ap_dec_control_request_fb;
|
||||
fb->dec_msg[8] = e2ap_dec_control_ack_fb;
|
||||
fb->dec_msg[9] = e2ap_dec_control_failure_fb;
|
||||
fb->dec_msg[10] = NULL;//e2ap_dec_error_indication;
|
||||
fb->dec_msg[11] = e2ap_dec_setup_request_fb;
|
||||
fb->dec_msg[12] = e2ap_dec_setup_response_fb;
|
||||
fb->dec_msg[13] = NULL;//e2ap_dec_setup_failure;
|
||||
fb->dec_msg[14] = NULL;//e2ap_dec_reset_request;
|
||||
fb->dec_msg[15] = NULL;//e2ap_dec_reset_response;
|
||||
fb->dec_msg[16] = NULL;//e2ap_dec_service_update;
|
||||
fb->dec_msg[17] = NULL;//e2ap_dec_service_update_ack;
|
||||
fb->dec_msg[18] = NULL;//e2ap_dec_service_update_failure;
|
||||
fb->dec_msg[19] = NULL;//e2ap_dec_service_query;
|
||||
fb->dec_msg[20] = NULL;//e2ap_dec_node_configuration_update;
|
||||
fb->dec_msg[21] = NULL;//e2ap_dec_node_configuration_update_ack;
|
||||
fb->dec_msg[22] = NULL;//e2ap_dec_node_configuration_update_failure;
|
||||
fb->dec_msg[23] = NULL;//e2ap_dec_connection_update;
|
||||
fb->dec_msg[24] = NULL;//e2ap_dec_connection_update_ack;
|
||||
fb->dec_msg[25] = NULL;//e2ap_dec_connection_update_failure;
|
||||
|
||||
// Free Functions
|
||||
fb->free_msg[0] = e2ap_free_subscription_request_msg;
|
||||
fb->free_msg[1] = e2ap_free_subscription_response_msg;
|
||||
fb->free_msg[2] = e2ap_free_subscription_failure_msg;
|
||||
fb->free_msg[3] = e2ap_free_subscription_delete_request_msg;
|
||||
fb->free_msg[4] = e2ap_free_subscription_delete_response_msg;
|
||||
fb->free_msg[5] = e2ap_free_subscription_delete_failure_msg;
|
||||
fb->free_msg[6] = e2ap_free_indication_msg;
|
||||
fb->free_msg[7] = e2ap_free_control_request_msg;
|
||||
fb->free_msg[8] = e2ap_free_control_ack_msg;
|
||||
fb->free_msg[9] = e2ap_free_control_failure_msg;
|
||||
fb->free_msg[10] = e2ap_free_error_indication_msg;
|
||||
fb->free_msg[11] = e2ap_free_setup_request_msg;
|
||||
fb->free_msg[12] = e2ap_free_setup_response_msg;
|
||||
fb->free_msg[13] = e2ap_free_setup_failure_msg;
|
||||
fb->free_msg[14] = e2ap_free_reset_request_msg;
|
||||
fb->free_msg[15] = e2ap_free_reset_response_msg;
|
||||
fb->free_msg[16] = e2ap_free_service_update_msg;
|
||||
fb->free_msg[17] = e2ap_free_service_update_ack_msg;
|
||||
fb->free_msg[18] = e2ap_free_service_update_failure_msg;
|
||||
fb->free_msg[19] = e2ap_free_service_query_msg;
|
||||
fb->free_msg[20] = e2ap_free_node_configuration_update_msg;
|
||||
fb->free_msg[21] = e2ap_free_node_configuration_update_ack_msg;
|
||||
fb->free_msg[22] = e2ap_free_node_configuration_update_failure_msg;
|
||||
fb->free_msg[23] = e2ap_free_node_connection_update_msg;
|
||||
fb->free_msg[24] = e2ap_free_node_connection_update_ack_msg;
|
||||
fb->free_msg[25] = e2ap_free_node_connection_update_failure_msg;
|
||||
}
|
||||
|
||||
35
openair2/E2AP/lib/v1/ap/e2ap_ap_fb.h
Normal file
35
openair2/E2AP/lib/v1/ap/e2ap_ap_fb.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 E2AP_APPLICATION_PROTOCOL_FB
|
||||
#define E2AP_APPLICATION_PROTOCOL_FB
|
||||
|
||||
#include "e2ap_ap.h"
|
||||
|
||||
typedef struct e2ap_fb e2ap_fb_t;
|
||||
|
||||
void init_ap_fb(e2ap_fb_t* fb);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
51
openair2/E2AP/lib/v1/ap/e2ap_types/CMakeLists.txt
Normal file
51
openair2/E2AP/lib/v1/ap/e2ap_types/CMakeLists.txt
Normal file
@@ -0,0 +1,51 @@
|
||||
set(e2ap_src_types
|
||||
ric_subscription_request.c
|
||||
ric_subscription_response.c
|
||||
ric_subscription_failure.c
|
||||
ric_indication.c
|
||||
ric_subscription_delete_request.c
|
||||
ric_subscription_delete_response.c
|
||||
ric_subscription_delete_failure.c
|
||||
ric_control_request.c
|
||||
ric_control_ack.c
|
||||
ric_control_failure.c
|
||||
e2ap_error_indication.c
|
||||
e2_setup_request.c
|
||||
e2_setup_response.c
|
||||
e2_setup_failure.c
|
||||
|
||||
e42_setup_request.c
|
||||
e42_setup_response.c
|
||||
e42_ric_control_request.c
|
||||
e2_node_connected.c
|
||||
e42_ric_subscription_request.c
|
||||
e42_ric_subscription_delete_request.c
|
||||
|
||||
e2ap_reset_request.c
|
||||
e2ap_reset_response.c
|
||||
ric_service_update.c
|
||||
ric_service_update_ack.c
|
||||
ric_service_update_failure.c
|
||||
ric_service_query.c
|
||||
e2_node_configuration_update.c
|
||||
common/e2ap_ran_function_id_rev.c
|
||||
common/e2ap_ran_function_id.c
|
||||
common/ric_action.c
|
||||
common/ric_gen_id.c
|
||||
common/ric_action_admitted.c
|
||||
common/ric_action_not_admitted.c
|
||||
common/e2ap_criticality_diagnostics.c
|
||||
common/e2ap_cause.c
|
||||
common/e2ap_global_node_id.c
|
||||
common/e2ap_global_ric_id.c
|
||||
common/e2ap_ran_function.c
|
||||
common/e2ap_time_to_wait.c
|
||||
common/e2ap_rejected_ran_function.c
|
||||
common/e2ap_node_component_config_update.c
|
||||
common/transport_layer_info.c
|
||||
common/e2ap_plmn.c
|
||||
common/ric_subsequent_action.c
|
||||
)
|
||||
|
||||
add_library(e2ap_types_obj OBJECT ${e2ap_src_types})
|
||||
target_link_libraries(e2ap_types_obj PUBLIC ds)
|
||||
48
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_cause.c
Normal file
48
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_cause.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 "e2ap_cause.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
bool eq_cause(const cause_t* m0, const cause_t* m1)
|
||||
{
|
||||
if(m0 == m1) return true;
|
||||
|
||||
if(m0 == NULL || m1 == NULL)
|
||||
return false;
|
||||
|
||||
const int rc = memcmp(m0, m1, sizeof(cause_t));
|
||||
if( rc != 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cause_t cp_cause(cause_t const* src)
|
||||
{
|
||||
assert(src != NULL);
|
||||
cause_t dst = *src;
|
||||
return dst;
|
||||
}
|
||||
|
||||
95
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_cause.h
Normal file
95
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_cause.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 E2AP_CAUSE_H
|
||||
#define E2AP_CAUSE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum {
|
||||
CAUSE_NOTHING, /* NO COMPONENTS PRESENT */
|
||||
CAUSE_RICREQUEST,
|
||||
CAUSE_RICSERVICE,
|
||||
CAUSE_TRANSPORT,
|
||||
CAUSE_PROTOCOL,
|
||||
CAUSE_MISC
|
||||
} cause_e;
|
||||
|
||||
typedef enum {
|
||||
CAUSE_RIC_RAN_FUNCTION_ID_INVALID = 0,
|
||||
CAUSE_RIC_ACTION_NOT_SUPPORTED = 1,
|
||||
CAUSE_RIC_EXCESSIVE_ACTIONS = 2,
|
||||
CAUSE_RIC_DUPLICATE_ACTION = 3,
|
||||
CAUSE_RIC_DUPLICATE_EVENT = 4,
|
||||
CAUSE_RIC_FUNCTION_RESOURCE_LIMIT = 5,
|
||||
CAUSE_RIC_REQUEST_ID_UNKNOWN = 6,
|
||||
CAUSE_RIC_INCONSISTENT_ACTION_SUBSEQUENT_ACTION_SEQUENCE = 7,
|
||||
CAUSE_RIC_CONTROL_MESSAGE_INVALID = 8,
|
||||
CAUSE_RIC_CALL_PROCESS_ID_INVALID = 9,
|
||||
CAUSE_RIC_UNSPECIFIED = 10
|
||||
} cause_RIC_e;
|
||||
|
||||
typedef enum {
|
||||
CAUSE_RICSERVICE_FUNCTION_NOT_REQUIRED = 0,
|
||||
CAUSE_RICSERVICE_EXCESSIVE_FUNCTIONS = 1,
|
||||
CAUSE_RICSERVICE_RIC_RESOURCE_LIMIT = 2
|
||||
} cause_RIC_service_e;
|
||||
|
||||
typedef enum {
|
||||
CAUSE_TRANSPORT_UNSPECIFIED = 0,
|
||||
CAUSE_TRANSPORT_TRANSPORT_RESOURCE_UNAVAILABLE = 1
|
||||
} cause_transport_e;
|
||||
|
||||
typedef enum {
|
||||
CAUSE_PROTOCOL_TRANSFER_SYNTAX_ERROR = 0,
|
||||
CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT = 1,
|
||||
CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE_AND_NOTIFY = 2,
|
||||
CAUSE_PROTOCOL_MESSAGE_NOT_COMPATIBLE_WITH_RECEIVER_STATE = 3,
|
||||
CAUSE_PROTOCOL_SEMANTIC_ERROR = 4,
|
||||
CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE = 5,
|
||||
CAUSE_PROTOCOL_UNSPECIFIED = 6
|
||||
} cause_protocol_e;
|
||||
|
||||
typedef enum {
|
||||
CAUSE_MISC_CONTROL_PROCESSING_OVERLOAD = 0,
|
||||
CAUSE_MISC_HARDWARE_FAILURE = 1,
|
||||
CAUSE_MISC_OM_INTERVENTION = 2,
|
||||
CAUSE_MISC_UNSPECIFIED = 3
|
||||
} cause_misc_e;
|
||||
|
||||
/* Cause */
|
||||
typedef struct {
|
||||
cause_e present;
|
||||
union {
|
||||
cause_RIC_e ricRequest;
|
||||
cause_RIC_service_e ricService;
|
||||
cause_transport_e transport;
|
||||
cause_protocol_e protocol;
|
||||
cause_misc_e misc;
|
||||
};
|
||||
} cause_t;
|
||||
|
||||
bool eq_cause(const cause_t* m0, const cause_t* m1);
|
||||
|
||||
cause_t cp_cause(cause_t const* src);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 E2AP_CONNECTION_SETUP_FAILED_H
|
||||
#define E2AP_CONNECTION_SETUP_FAILED_H
|
||||
|
||||
#include "e2ap_cause.h"
|
||||
#include "e2ap_tnl_information.h"
|
||||
|
||||
typedef struct{
|
||||
cause_t cause;
|
||||
e2ap_tnl_information_t info;
|
||||
} e2_connection_setup_failed_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 E2AP_CONNECTION_UPDATE_H
|
||||
#define E2AP_CONNECTION_UPDATE_H
|
||||
|
||||
#include "e2ap_tnl_information.h"
|
||||
#include "e2ap_tnl_usage.h"
|
||||
|
||||
typedef struct{
|
||||
e2ap_tnl_information_t info;
|
||||
e2ap_tnl_usage_e usage;
|
||||
} e2_connection_update_item_t;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 E2AP_CONNECTIOIN_UPDATE_REMOVE_H
|
||||
#define E2AP_CONNECTIOIN_UPDATE_REMOVE_H
|
||||
|
||||
#include "e2ap_tnl_information.h"
|
||||
|
||||
typedef struct{
|
||||
e2ap_tnl_information_t info;
|
||||
} e2_connection_update_remove_item_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
36
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_criticality.h
Normal file
36
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_criticality.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 E2AP_CRITICALITY_H
|
||||
#define E2AP_CRITICALITY_H
|
||||
|
||||
|
||||
typedef enum {
|
||||
REJECT,
|
||||
IGNORE,
|
||||
NOTIFY
|
||||
} criticality_e;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 "e2ap_criticality_diagnostics.h"
|
||||
#include <assert.h>
|
||||
|
||||
bool eq_criticality_diagnostics(const criticality_diagnostics_t* m0, const criticality_diagnostics_t* m1)
|
||||
{
|
||||
if(m0 == m1) return true;
|
||||
|
||||
if(m0 != NULL || m1 != NULL) return false;
|
||||
|
||||
assert(0!=0 && "Not implemented");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 E2AP_CRITICALITY_DIAGNOSTICS_H
|
||||
#define E2AP_CRITICALITY_DIAGNOSTICS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ric_gen_id.h"
|
||||
#include "e2ap_criticality.h"
|
||||
#include "ric_gen_id.h"
|
||||
#include "e2ap_ie_criticality_diagnostics.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
INITIATING_MESSAGE,
|
||||
SUCCESSFUL_OUTCOME,
|
||||
UNSUCCESSFUL_OUTCOME
|
||||
} triggering_message_e;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t* procedure_code; //optional
|
||||
triggering_message_e* trig_msg; // optional
|
||||
criticality_e* proc_crit; // optional
|
||||
ric_gen_id_t* req_id; // optional
|
||||
ie_criticality_diagnostics_t* ie;
|
||||
size_t len_ie;
|
||||
} criticality_diagnostics_t;
|
||||
|
||||
bool eq_criticality_diagnostics(const criticality_diagnostics_t* m0, const criticality_diagnostics_t* m1);
|
||||
|
||||
#endif
|
||||
|
||||
187
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_global_node_id.c
Normal file
187
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_global_node_id.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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 "e2ap_global_node_id.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool eq_global_e2_node_id(const global_e2_node_id_t* m0, const global_e2_node_id_t* m1)
|
||||
{
|
||||
if(m0 == m1) return true;
|
||||
|
||||
if(m0 == NULL || m1 == NULL) return false;
|
||||
|
||||
if (NODE_IS_MONOLITHIC(m0->type) && NODE_IS_MONOLITHIC(m1->type)) {
|
||||
// compare gNB/eNB
|
||||
if(m0->type != m1->type)
|
||||
return false;
|
||||
|
||||
if(eq_plmn(&m0->plmn, &m1->plmn) == false)
|
||||
return false;
|
||||
|
||||
if(m0->nb_id != m1->nb_id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} else if ((NODE_IS_CU(m0->type) || NODE_IS_DU(m0->type)) && (NODE_IS_CU(m1->type) || NODE_IS_DU(m1->type))) {
|
||||
// compare gNB/eNB-CU/DU
|
||||
if(m0->cu_du_id == NULL || m1->cu_du_id == NULL) return false;
|
||||
|
||||
if(m0->type != m1->type)
|
||||
return false;
|
||||
|
||||
if(eq_plmn(&m0->plmn, &m1->plmn) == false)
|
||||
return false;
|
||||
|
||||
if(m0->nb_id != m1->nb_id)
|
||||
return false;
|
||||
|
||||
if(*m0->cu_du_id != *m1->cu_du_id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// compare gNB/eNB and gNB/eNB-CU/DU
|
||||
// avoid diff type with same plmn/nb_id
|
||||
if(eq_plmn(&m0->plmn, &m1->plmn) == false)
|
||||
return false;
|
||||
|
||||
if(m0->nb_id != m1->nb_id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
global_e2_node_id_t cp_global_e2_node_id(global_e2_node_id_t const* src)
|
||||
{
|
||||
assert(src != NULL);
|
||||
global_e2_node_id_t dst = {0};
|
||||
|
||||
dst.type = src->type;
|
||||
dst.plmn = cp_plmn(&src->plmn);
|
||||
dst.nb_id = src->nb_id;
|
||||
if (src->cu_du_id != NULL) {
|
||||
dst.cu_du_id = calloc(1, sizeof(uint64_t));
|
||||
assert(dst.cu_du_id != NULL && "memory exhausted");
|
||||
*dst.cu_du_id = *src->cu_du_id;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void free_global_e2_node_id(global_e2_node_id_t* src)
|
||||
{
|
||||
if (src->cu_du_id != NULL)
|
||||
free (src->cu_du_id);
|
||||
}
|
||||
|
||||
bool eq_global_e2_node_id_wrapper(const void* m0_v, const void* m1_v)
|
||||
{
|
||||
assert(m0_v != NULL);
|
||||
assert(m1_v != NULL);
|
||||
|
||||
global_e2_node_id_t* m0 = (global_e2_node_id_t*)m0_v;
|
||||
global_e2_node_id_t* m1 = (global_e2_node_id_t*)m1_v;
|
||||
|
||||
return eq_global_e2_node_id(m0,m1);
|
||||
}
|
||||
|
||||
int cmp_global_e2_node_id(const global_e2_node_id_t* m0, const global_e2_node_id_t* m1)
|
||||
{
|
||||
assert(m0 != NULL);
|
||||
assert(m1 != NULL);
|
||||
|
||||
if (NODE_IS_MONOLITHIC(m0->type) && NODE_IS_MONOLITHIC(m1->type)) {
|
||||
// compare gNB/eNB
|
||||
if (m0->type < m1->type)
|
||||
return -1;
|
||||
else if(m0->type > m1->type)
|
||||
return 1;
|
||||
|
||||
int rc = cmp_plmn(&m0->plmn, &m1->plmn);
|
||||
if(rc != 0)
|
||||
return rc;
|
||||
|
||||
if (m0->nb_id < m1->nb_id)
|
||||
return -1;
|
||||
else if(m0->nb_id > m1->nb_id)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
} else if ((NODE_IS_CU(m0->type) || NODE_IS_DU(m0->type)) && (NODE_IS_CU(m1->type) || NODE_IS_DU(m1->type))) {
|
||||
// compare gNB/eNB-CU/DU
|
||||
if (m0->type < m1->type)
|
||||
return -1;
|
||||
else if(m0->type > m1->type)
|
||||
return 1;
|
||||
|
||||
int rc = cmp_plmn(&m0->plmn, &m1->plmn);
|
||||
if(rc != 0)
|
||||
return rc;
|
||||
|
||||
if (m0->nb_id < m1->nb_id)
|
||||
return -1;
|
||||
else if(m0->nb_id > m1->nb_id)
|
||||
return 1;
|
||||
|
||||
if (*m0->cu_du_id < *m1->cu_du_id)
|
||||
return -1;
|
||||
else if(*m0->cu_du_id > *m1->cu_du_id)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
// compare gNB/eNB and gNB/eNB-CU/DU
|
||||
// avoid diff type with same plmn/nb_id
|
||||
int rc = cmp_plmn(&m0->plmn, &m1->plmn);
|
||||
if(rc != 0)
|
||||
return rc;
|
||||
|
||||
if (m0->nb_id < m1->nb_id)
|
||||
return -1;
|
||||
else if(m0->nb_id > m1->nb_id)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int cmp_global_e2_node_id_wrapper(const void* m0_v, const void* m1_v)
|
||||
{
|
||||
assert(m0_v != NULL);
|
||||
assert(m1_v != NULL);
|
||||
|
||||
global_e2_node_id_t* m0 = (global_e2_node_id_t*)m0_v;
|
||||
global_e2_node_id_t* m1 = (global_e2_node_id_t*)m1_v;
|
||||
|
||||
return cmp_global_e2_node_id(m0,m1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 E2AP_GLOBAL_NODE_ID_H
|
||||
#define E2AP_GLOBAL_NODE_ID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "e2ap_plmn.h"
|
||||
#include "common/ngran_types.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct global_e2_node_id {
|
||||
ngran_node_t type;
|
||||
plmn_t plmn;
|
||||
uint32_t nb_id;
|
||||
uint64_t *cu_du_id;
|
||||
} global_e2_node_id_t;
|
||||
|
||||
global_e2_node_id_t cp_global_e2_node_id(global_e2_node_id_t const* src);
|
||||
|
||||
void free_global_e2_node_id(global_e2_node_id_t* src);
|
||||
|
||||
bool eq_global_e2_node_id(const global_e2_node_id_t* m0, const global_e2_node_id_t* m1);
|
||||
|
||||
bool eq_global_e2_node_id(const global_e2_node_id_t* m0, const global_e2_node_id_t* m1);
|
||||
|
||||
bool eq_global_e2_node_id_wrapper(const void* m0_v, const void* m1_v );
|
||||
|
||||
int cmp_global_e2_node_id(const global_e2_node_id_t* m0, const global_e2_node_id_t* m1);
|
||||
|
||||
int cmp_global_e2_node_id_wrapper(const void* m0_v, const void* m1_v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 "e2ap_global_ric_id.h"
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
bool eq_global_ric_id(const global_ric_id_t* m0, const global_ric_id_t* m1)
|
||||
{
|
||||
if(m0 == m1) return true;
|
||||
|
||||
if(m0 == NULL || m1 == NULL) return false;
|
||||
|
||||
if(eq_plmn(&m0->plmn, &m1->plmn) == false)
|
||||
return false;
|
||||
|
||||
if(m0->near_ric_id.double_word != m1->near_ric_id.double_word)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 E2AP_GLOBAL_RIC_H
|
||||
#define E2AP_GLOBAL_RIC_H
|
||||
|
||||
#include "e2ap_plmn.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct{
|
||||
plmn_t plmn;
|
||||
|
||||
union{
|
||||
uint32_t double_word;
|
||||
uint8_t bytes[4];
|
||||
} near_ric_id;
|
||||
|
||||
} global_ric_id_t;
|
||||
|
||||
|
||||
bool eq_global_ric_id(const global_ric_id_t* m0, const global_ric_id_t* m1);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 E2AP_IE_CRITICALITY_DIAGNOSTICS_H
|
||||
#define E2AP_IE_CRITICALITY_DIAGNOSTICS_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "e2ap_criticality.h"
|
||||
|
||||
typedef enum {
|
||||
NOT_UNDERSTOOD,
|
||||
MISSING
|
||||
} type_of_error_t;
|
||||
|
||||
typedef struct ie_criticality_diagnostics {
|
||||
criticality_e crit;
|
||||
uint16_t id;
|
||||
type_of_error_t type;
|
||||
} ie_criticality_diagnostics_t;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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 "e2ap_node_component_config_update.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static
|
||||
byte_array_t* create_assign_ba(byte_array_t* src)
|
||||
{
|
||||
byte_array_t* dst = calloc(1, sizeof(byte_array_t));
|
||||
assert(dst != NULL && "Memory ehausted");
|
||||
*dst = copy_byte_array(*src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
e2_node_component_config_update_t cp_e2_node_component_config_update(const e2_node_component_config_update_t* src)
|
||||
{
|
||||
assert(src != NULL);
|
||||
e2_node_component_config_update_t dst = {
|
||||
.e2_node_component_type = src->e2_node_component_type,
|
||||
};
|
||||
|
||||
if(src->id_present != NULL){
|
||||
dst.id_present = calloc(1,sizeof(e2_node_component_id_present_e ));
|
||||
assert(dst.id_present != NULL && "Memory exhausted");
|
||||
dst.id_present = src->id_present;
|
||||
// Does not matter the value of src->id_present
|
||||
dst.gnb_cu_up_id = src->gnb_cu_up_id;
|
||||
}
|
||||
|
||||
dst.update_present = src->update_present;
|
||||
if(dst.update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_GNB_CONFIG_UPDATE){
|
||||
dst.gnb.ngap_gnb_cu_cp = create_assign_ba(src->gnb.ngap_gnb_cu_cp);
|
||||
dst.gnb.xnap_gnb_cu_cp = create_assign_ba(src->gnb.xnap_gnb_cu_cp);
|
||||
dst.gnb.e1ap_gnb_cu_cp = create_assign_ba(src->gnb.e1ap_gnb_cu_cp);
|
||||
dst.gnb.f1ap_gnb_cu_cp = create_assign_ba(src->gnb.f1ap_gnb_cu_cp);
|
||||
} else if (dst.update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_EN_GNB_CONFIG_UPDATE ){
|
||||
dst.en_gnb.x2ap_en_gnb = create_assign_ba(src->en_gnb.x2ap_en_gnb);
|
||||
} else if (dst.update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_NG_ENB_CONFIG_UPDATE ){
|
||||
dst.ng_enb.ngap_ng_enb = create_assign_ba(src->ng_enb.ngap_ng_enb);
|
||||
dst.ng_enb.xnap_ng_enb = create_assign_ba(src->ng_enb.xnap_ng_enb);
|
||||
|
||||
} else if (dst.update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_ENB_CONFIG_UPDATE ){
|
||||
dst.enb.s1ap_enb = create_assign_ba(src->enb.s1ap_enb);
|
||||
dst.enb.x2ap_enb = create_assign_ba(src->enb.x2ap_enb);
|
||||
} else {
|
||||
assert(0 != 0 && "Not foreseen switch case");
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void free_e2_node_component_config_update(e2_node_component_config_update_t* src)
|
||||
{
|
||||
assert(src != NULL);
|
||||
|
||||
if(src->id_present != NULL){
|
||||
free(src->id_present);
|
||||
}
|
||||
|
||||
if(src->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_GNB_CONFIG_UPDATE){
|
||||
free_byte_array(*src->gnb.ngap_gnb_cu_cp);
|
||||
free_byte_array(*src->gnb.xnap_gnb_cu_cp);
|
||||
free_byte_array(*src->gnb.e1ap_gnb_cu_cp);
|
||||
free_byte_array(*src->gnb.f1ap_gnb_cu_cp);
|
||||
} else if (src->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_EN_GNB_CONFIG_UPDATE ){
|
||||
free_byte_array(*src->en_gnb.x2ap_en_gnb);
|
||||
} else if (src->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_NG_ENB_CONFIG_UPDATE ){
|
||||
free_byte_array(*src->ng_enb.ngap_ng_enb);
|
||||
free_byte_array(*src->ng_enb.xnap_ng_enb);
|
||||
} else if (src->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_ENB_CONFIG_UPDATE ){
|
||||
free_byte_array(*src->enb.s1ap_enb);
|
||||
free_byte_array(*src->enb.x2ap_enb);
|
||||
} else {
|
||||
assert(0 != 0 && "Not foreseen switch case");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
bool eq_e2_node_component_id_present(const e2_node_component_id_present_e* m0, const e2_node_component_id_present_e* m1)
|
||||
{
|
||||
if(m0 == m1) return true;
|
||||
|
||||
if(m0 == NULL || m1 == NULL)
|
||||
return false;
|
||||
|
||||
if(*m0 != *m1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eq_e2_node_component_config_update(const e2_node_component_config_update_t* m0, const e2_node_component_config_update_t* m1)
|
||||
{
|
||||
if(m0 == m1) return true;
|
||||
|
||||
if(m0 == NULL || m1 == NULL) return false;
|
||||
|
||||
|
||||
if(m0->e2_node_component_type != m1->e2_node_component_type)
|
||||
return false;
|
||||
|
||||
if(eq_e2_node_component_id_present(m0->id_present,m1->id_present) == false)
|
||||
return false;
|
||||
|
||||
if(m0->gnb_cu_up_id != m1->gnb_cu_up_id)
|
||||
return false;
|
||||
|
||||
if(m0->update_present != m1->update_present)
|
||||
return false;
|
||||
|
||||
if(m0->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_GNB_CONFIG_UPDATE){
|
||||
if(eq_byte_array(m0->gnb.ngap_gnb_cu_cp, m1->gnb.ngap_gnb_cu_cp) == false)
|
||||
return false;
|
||||
if(eq_byte_array(m0->gnb.xnap_gnb_cu_cp, m1->gnb.xnap_gnb_cu_cp) == false )
|
||||
return false;
|
||||
if(eq_byte_array(m0->gnb.e1ap_gnb_cu_cp, m1->gnb.e1ap_gnb_cu_cp) == false )
|
||||
return false;
|
||||
if(eq_byte_array(m0->gnb.f1ap_gnb_cu_cp, m1->gnb.f1ap_gnb_cu_cp) == false )
|
||||
return false;
|
||||
} else if (m0->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_EN_GNB_CONFIG_UPDATE){
|
||||
if(eq_byte_array(m0->en_gnb.x2ap_en_gnb, m1->en_gnb.x2ap_en_gnb) == false)
|
||||
return false;
|
||||
} else if(m0->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_NG_ENB_CONFIG_UPDATE){
|
||||
if(eq_byte_array(m0->ng_enb.ngap_ng_enb, m1->ng_enb.ngap_ng_enb) == false)
|
||||
return false;
|
||||
if(eq_byte_array(m0->ng_enb.xnap_ng_enb, m1->ng_enb.xnap_ng_enb) == false)
|
||||
return false;
|
||||
} else if(m0->update_present == E2_NODE_COMPONENT_CONFIG_UPDATE_ENB_CONFIG_UPDATE){
|
||||
if(eq_byte_array(m0->enb.s1ap_enb, m1->enb.s1ap_enb) == false)
|
||||
return false;
|
||||
if(eq_byte_array(m0->enb.x2ap_enb, m1->enb.x2ap_enb) == false)
|
||||
return false;
|
||||
} else {
|
||||
assert(0!=0 && "Error, case not foreseen");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 E2AP_NODE_COMPONENT_CONFIG_UPDATE_H
|
||||
#define E2AP_NODE_COMPONENT_CONFIG_UPDATE_H
|
||||
|
||||
#include "byte_array.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
E2_NODE_COMPONENT_CONFIG_UPDATE_NOTHING,
|
||||
E2_NODE_COMPONENT_CONFIG_UPDATE_GNB_CONFIG_UPDATE,
|
||||
E2_NODE_COMPONENT_CONFIG_UPDATE_EN_GNB_CONFIG_UPDATE,
|
||||
E2_NODE_COMPONENT_CONFIG_UPDATE_NG_ENB_CONFIG_UPDATE,
|
||||
E2_NODE_COMPONENT_CONFIG_UPDATE_ENB_CONFIG_UPDATE
|
||||
} e2_node_component_config_update_present_e;
|
||||
|
||||
typedef enum {
|
||||
E2_NODE_COMPONENT_ID_E2_NODE_COMPONENT_TYPE_GNB_CU_UP,
|
||||
E2_NODE_COMPONENT_ID_E2_NODE_COMPONENT_TYPE_GNB_DU
|
||||
} e2_node_component_id_present_e;
|
||||
|
||||
|
||||
typedef enum {
|
||||
E2_NODE_COMPONENT_TYPE_GNB = 0,
|
||||
E2_NODE_COMPONENT_TYPE_GNB_CU_UP = 1,
|
||||
E2_NODE_COMPONENT_TYPE_GNB_DU = 2,
|
||||
E2_NODE_COMPONENT_TYPE_EN_GNB = 3,
|
||||
E2_NODE_COMPONENT_TYPE_ENB = 4,
|
||||
E2_NODE_COMPONENT_TYPE_NG_ENB = 5
|
||||
} e2_node_component_type_e;
|
||||
|
||||
typedef struct {
|
||||
e2_node_component_type_e e2_node_component_type;
|
||||
e2_node_component_id_present_e* id_present; // optional
|
||||
union {
|
||||
uint64_t gnb_cu_up_id;
|
||||
uint64_t gnb_du_id;
|
||||
};
|
||||
e2_node_component_config_update_present_e update_present;
|
||||
union {
|
||||
struct {
|
||||
byte_array_t* ngap_gnb_cu_cp;
|
||||
byte_array_t* xnap_gnb_cu_cp;
|
||||
byte_array_t* e1ap_gnb_cu_cp;
|
||||
byte_array_t* f1ap_gnb_cu_cp;
|
||||
} gnb;
|
||||
struct {
|
||||
byte_array_t* x2ap_en_gnb;
|
||||
} en_gnb;
|
||||
struct {
|
||||
byte_array_t* ngap_ng_enb;
|
||||
byte_array_t* xnap_ng_enb;
|
||||
} ng_enb;
|
||||
struct {
|
||||
byte_array_t* s1ap_enb;
|
||||
byte_array_t* x2ap_enb;
|
||||
} enb;
|
||||
};
|
||||
} e2_node_component_config_update_t;
|
||||
|
||||
e2_node_component_config_update_t cp_e2_node_component_config_update(const e2_node_component_config_update_t* src);
|
||||
|
||||
void free_e2_node_component_config_update(e2_node_component_config_update_t* src);
|
||||
|
||||
|
||||
bool eq_e2_node_component_config_update(const e2_node_component_config_update_t* m0, const e2_node_component_config_update_t* m1);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 E2_NODE_CONFIGURATION_UPDATE_ACK_ITEM_H
|
||||
#define E2_NODE_CONFIGURATION_UPDATE_ACK_ITEM_H
|
||||
|
||||
#include "e2ap_cause.h"
|
||||
#include "e2ap_node_component_config_update.h"
|
||||
|
||||
typedef struct{
|
||||
e2_node_component_type_e e2_node_component_type;
|
||||
e2_node_component_id_present_e* id_present; // optional
|
||||
union {
|
||||
uint64_t gnb_cu_up_id;
|
||||
uint64_t gnb_du_id;
|
||||
};
|
||||
|
||||
long update_outcome;
|
||||
cause_t *failure_cause; /* OPTIONAL */
|
||||
} e2_node_component_config_update_ack_item_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
83
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_plmn.c
Normal file
83
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_plmn.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 "e2ap_plmn.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
plmn_t cp_plmn(const plmn_t* src)
|
||||
{
|
||||
assert(src != NULL);
|
||||
|
||||
plmn_t dst = {0};
|
||||
|
||||
dst.mcc = src->mcc;
|
||||
dst.mnc = src->mnc;
|
||||
dst.mnc_digit_len = src->mnc_digit_len;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool eq_plmn(const plmn_t* m0, const plmn_t* m1)
|
||||
{
|
||||
if(m0 == m1) return true;
|
||||
|
||||
if(m0 == NULL || m1 == NULL) return false;
|
||||
|
||||
if(m0->mcc != m1->mcc)
|
||||
return false;
|
||||
|
||||
if(m0->mnc != m1->mnc)
|
||||
return false;
|
||||
|
||||
if(m0->mnc_digit_len != m1->mnc_digit_len)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int cmp_plmn(const plmn_t* m0, const plmn_t* m1)
|
||||
{
|
||||
assert(m0 != NULL);
|
||||
assert(m1 != NULL);
|
||||
|
||||
if(m0->mcc < m1->mcc)
|
||||
return -1;
|
||||
else if(m0->mcc > m1->mcc )
|
||||
return 1;
|
||||
|
||||
if(m0->mnc < m1->mnc)
|
||||
return -1;
|
||||
else if(m0->mnc > m1->mnc )
|
||||
return 1;
|
||||
|
||||
if(m0->mnc_digit_len < m1->mnc_digit_len)
|
||||
return -1;
|
||||
else if(m0->mnc_digit_len > m1->mnc_digit_len)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
54
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_plmn.h
Normal file
54
openair2/E2AP/lib/v1/ap/e2ap_types/common/e2ap_plmn.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 E2AP_PLMN_H
|
||||
#define E2AP_PLMN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint8_t mnc_digit_len;
|
||||
} plmn_t;
|
||||
|
||||
bool eq_plmn(const plmn_t* m0, const plmn_t* m1);
|
||||
|
||||
plmn_t cp_plmn(const plmn_t* src);
|
||||
|
||||
int cmp_plmn(const plmn_t* m0, const plmn_t* m1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user