Commit 3cc67189 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/e1-issue-712' into integration_2024_w04

parents a0de76ca f3f8e840
......@@ -63,6 +63,8 @@ Calling the `build_oai` script with the `-h` option gives the list of all availa
- `--ninja` is to use the `ninja` build tool, which speeds up compilation.
- `-c` is to clean the workspace and force a complete rebuild.
`build_oai` also provides various options to enable runtime error checkers, i.e. sanitizers in order to find various types of bugs in the codebase and eventually enhance the stability of the OAI softmodems. Refer to [sanitizers.md](./dev_tools/sanitizers.md) for more details.
## Installing dependencies
Install all dependencies by issuing the `-I` option. To install furthermore libraries for optional libraries, use the `--install-optional-packages` option. The `-I` option will also install dependencies for an SDR when paired with `-w`. For instance, in order to install all dependencies and the ones for USRP, run:
......
......@@ -17,17 +17,22 @@ connection setup only in split-mode, the rest is the same for CU):
sequenceDiagram
participant c as CUCP
participant u as CUUP
Note over c,u: E1 Setup Procedure
u->c: SCTP connection setup (in split mode)
u->>c: E1AP Setup Request
u->>c: E1 Setup Request
Note over c: Execute rrc_gNB_process_e1_setup_req()
c->>u: E1AP Setup Response
c->>u: E1 Setup Response
c-->>u: E1 Setup Failure
Note over c,u: E1 Bearer Context Setup Procedure
Note over c: Receives PDU session setup request from AMF
c->>u: Bearer Context Setup Request
Note over u: Execute e1_bearer_context_setup()<br/>Configure DRBs and create GTP Tunnels for F1-U and N3
u->>c: Bearer Context Setup Response
Note over c: Execute rrc_gNB_process_e1_setup_req()<br/>Sends F1-U UL TNL info to DU and receives DL TNL info
Note over c,u: E1 Bearer Context Modification (CU-CP Initiated) Procedure
c->>u: Bearer Context Modification Request
Note over u: Execute e1_bearer_context_modif()<br/>Updates GTP Tunnels with received info
u->>c: Bearer Context Modification Response
......@@ -40,19 +45,63 @@ sequenceDiagram
Note over c: Execute rrc_gNB_process_e1_bearer_context_release_cplt()
```
The files that implement the callback towards these handlers are in
- `cucp_cuup_direct.c`: integrated CU (for CP=>UP messages)
- `cucp_cuup_e1ap.c`: E1 split mode (for CP=>UP messages)
- `cuup_cucp_direct.c`: integrated CU (for UP=>CP messages)
- `cuup_cucp_e1ap.c`: E1 split mode (for UP=>CP messages)
The implementation of callbacks towards these handlers is distributed across the following file, depending on the operating mode:
| Mode | CP=>UP messages |UP=>CP messages |
| --------------| --------------------|--------------------|
| Integrated CU | `cucp_cuup_direct.c`|`cuup_cucp_direct.c`|
| E1 Split | `cucp_cuup_e1ap.c` |`cuup_cucp_e1ap.c` |
As long as concerns E1 Interface Management Procedures, the code flow of request messages towards northbound looks like this:
```mermaid
sequenceDiagram
participant r as RRC
participant c as CUCP
participant u as CUUP
Note over u: E1AP_CUUP_task (SCTP Handler)
Note over u: ASN1 encoder
u->>c: e.g. E1 Setup Request (SCTP)
Note over c: E1AP_CUCP_task (SCTP Handler)
Note over c: ASN1 decoder
c->>r: E1AP_SETUP_REQ (ITTI)
Note over r: TASK_RRC_GNB (RRC Handler)
r->>c: E1AP_SETUP_RESP (ITTI)
Note over c: E1AP_CUCP_task (E1AP Callback)
Note over c: ASN1 encoder
c->>u: e.g. E1 Setup Response/Failure
Note over u: E1AP_CUUP_task (SCTP Handler)
Note over u: ASN1 decoder
```
# 2. Running the E1 Split
The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](./F1-design.md) for local deployment of the DU.
## 2.1 Configuration File
The gNB is started based on the node type that is specified in the configuration file. To start a gNB instance in CUCP or CUUP, the `tr_s_preference` should be set to "f1" and the config member `E1_INTERFACE` should be present in the config file. The `type` parameter within the `E1_INTERFACE` should be set to `cp`, and executable `nr-softmodem` should be used to run a CU-CP. The type should be `up` and executable `nr-cuup` should be used to run the CU-UP. Further, there are the parameters `ipv4_cucp` and `ipv4_cuup` to specify the IP addresses of the respective network functions.
The gNB is started based on the node type that is specified in the configuration file. The following parameters must be configured accordingly.
On either CUCP and CUUP:
* The southbound transport preference `gNBs.[0].tr_s_preference` set to `f1`
* config section `E1_INTERFACE` should be present
On the CU-CP:
* `type` parameter within the `E1_INTERFACE` should be set to `cp`
On the CU-UP:
* `type` parameter within the `E1_INTERFACE` should be set to `up`
Executables:
* executable `nr-softmodem` to run a CU-CP
* executable `nr-cuup` to run the CU-UP
In the `E1_INTERFACE` configuration section, the parameters `ipv4_cucp` and `ipv4_cuup` must be configured to specify the IP addresses of the respective network functions.
For CUCP, a typical `E1_INTERFACE` config looks like
For CUCP, a typical `E1_INTERFACE` config looks like:
```
E1_INTERFACE =
(
......@@ -64,7 +113,7 @@ E1_INTERFACE =
)
```
For CUUP, it is
For CUUP, it is:
```
E1_INTERFACE =
(
......@@ -77,7 +126,7 @@ E1_INTERFACE =
```
One could take an existing CU configuration file and add the above parameters to run the gNB as CUCP or CUUP.
The CUUP uses the IP address specified in `local_s_address` for F1-U and `GNB_IPV4_ADDRESS_FOR_NGU` for N3 links. Note that `local_s_address` is under `gNBs` and `GNB_IPV4_ADDRESS_FOR_NGU` is part of the `NETWORK_INTERFACES` config member.
The CUUP uses the IP address specified in `gNBs.[0].local_s_address` for F1-U and `GNB_IPV4_ADDRESS_FOR_NGU` for N3 links. Note that `local_s_address` is under `gNBs` and `GNB_IPV4_ADDRESS_FOR_NGU` is part of the `NETWORK_INTERFACES` config member.
Alternatively, you can use the config files `ci-scripts/conf_files/gnb-cucp.sa.f1.conf` and `ci-scripts/conf_files/gnb-cuup.sa.f1.conf`.
......
......@@ -20,15 +20,15 @@ The F1 interface is the functional split of 3GPP between the CU (centralized
unit: PDCP, RRC, SDAP) and the DU (distributed unit: RLC, MAC, PHY). It is
standardized in TS 38.470 - 38.473 for 5G NR. No equivalent for 4G exists.
We assume that each DU handles only one cell. Multiple DUs connected to one CU
We assume that each DU handles only one cell. Multiple DUs connected to one CU
are supported. Mobility over F1 is not yet supported.
# Control plane status (F1-C)
## Implementation Status
Note that OAI uses F1 "internally". That means, that even if you run a
monolithic gNB, the internal information exchange uses F1. You can therefore
Note that OAI uses F1 "internally". That means, that even **if you run a
monolithic gNB, the internal information exchange uses F1**. You can therefore
expect that everything working in a monolithic deployment should also work in
F1. The current implementation is based on R16.3.
......@@ -118,13 +118,13 @@ see [this `docker-compose` file](../ci-scripts/yaml_files/5g_f1_rfsimulator/dock
The rules to decide if a config triggers a start of a DU, CU, or monolithic
gNB, are, in order:
1. If the `MACRLCs` section lists `f1` as northbound transport preference
1. If the `MACRLCs` section lists `f1` as **northbound transport preference**
(`tr_n_preference`), it is a DU.
2. If the `gNBs` section lists `f1` as a southound transport preference
2. If the `gNBs` section lists `f1` as a **southound transport preference**
(`tr_s_preference`), it is a CU.
3. It is a (monolithic) gNB.
## Configuration of F1 IP/port information
## Local network deployment of F1
For a local deployment, you should update the following fields.
We assume that the CU will bind on `192.168.70.129` towards the core,
......
......@@ -191,22 +191,30 @@ Furthermore, the gNB and UE support
## gNB F1AP
- Integration of F1AP messages and procedures for the control plane exchanges between the CU and DU entities according to 38.473 Rel. 16
- F1 Setup request/response
- F1 Setup request/response/failure
- F1 DL/UL RRC message transfer
- F1 Initial UL RRC message transfer
- F1 UE Context setup request/response
- F1 UE Context modification request/response
- F1 UE Context release
- F1 UE Context modification required
- F1 UE Context release req/cmd/complete
- F1 gNB CU configuration update
- Interface with RRC
- Interface with gtp-u (tunnel creation/handling for F1-U interface)
## gNB E1AP
- Integration of E1AP messages and procedures for exchange between CU-CP and CU-UP according to 38.463 Rel. 16
- gNB-CU-UP E1 Setup Setup request/response
- E1 Bearer Context Setup
- Integration of E1AP messages and procedures for exchange between CU-CP and CU-UP according to TS 38.463 Rel. 16
- E1 Setup (gNB-CU-UP initiated)
- E1 Setup Request
- E1 Setup Response
- E1 Setup Failure
- E1 Bearer Context Setup (gNB-CU-CP initiated)
- E1 Bearer Context Setup Request
- E1 Bearer Context Setup Response
- Bearer Context Modification (gNB-CU-CP initiated)
- E1 Bearer Context Modification Request
- E1 Bearer Context Modification Response
- Interface with RRC and PDCP
## gNB GTP-U
......
......@@ -21,6 +21,7 @@
- [BUILD.md](./BUILD.md): how to build the sources
- [cross-compile.md](./cross-compile.md): how to cross-compile OAI for ARM
- [clang-format.md](./clang-format.md): how to format the code
- [sanitizers.md](./dev_tools/sanitizers.md): how to run with ASan/UBSan/MemSAN/TSan
- [environment-variables.md](./environment-variables.md): the environment variables used by OAI
There is some general information in the [OpenAirInterface Gitlab Wiki](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/home)
......
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./../images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI Build Procedures</font></b>
</td>
</tr>
</table>
[[_TOC_]]
# Sanitize options in `build_oai`
The `build_oai` script provides various [Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) to add run-time instrumentation to the code and enable runtime error checkers, i.e. sanitizers, in order to help find various types of bugs in the codebase and eventually enhance the stability of the OAI softmodems. The following sanitizers can be enabled using different build options:
## Address Sanitizer (ASAN)
[Address Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) is enabled using the `--sanitize-address` option or its shorthand `-fsanitize=address`. It serves as a fast memory error detector and helps detect issues like out-of-bounds accesses, use-after-free bugs, and memory leaks.
### Run OAI Softmodem with ASAN on
It is necessary to add the envinronment variable `LD_LIBRARY_PATH` to the run command, e.g.:
```
cd cmake_targets/ran_build/build
sudo LD_LIBRARY_PATH=. ./nr-softmodem ...
```
## Undefined Behavior Sanitizer (UBSAN)
[Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) (UBSAN) is a runtime undefined behavior checker. It uses compile-time instrumentation to catch undefined behavior by inserting code that performs specific checks before operations that may cause it. UBSAN can be activated with the `--sanitize-undefined` option or `-fsanitize=undefined`.
UBSAN offers a range of suboptions that enable precise checks for various types of undefined behavior at runtime. These suboptions can be set by tweaking the [CMakeLists.txt](../../CMakeLists.txt) file. Here is an overview of some key suboptions:
* `-fsanitize=shift`: Enables checks for the result of shift operations, with suboptions for base and exponent.
* `-fsanitize=integer-divide-by-zero`: Detects integer division by zero.
* `-fsanitize=null`: Enables pointer checking, issuing an error message when dereferencing a NULL pointer or binding a reference to a NULL pointer.
* `-fsanitize=signed-integer-overflow`: Detects signed integer overflow.
* `-fsanitize=bounds`: Instruments array bounds, detecting various out-of-bounds accesses.
* `-fsanitize=alignment`: Checks the alignment of pointers when dereferenced or when a reference is bound to an insufficiently aligned target.
* `-fsanitize=object-size`: Checks out-of-bounds pointer accesses.
* `-fsanitize=float-divide-by-zero`: Detects floating-point division by zero.
## Memory Sanitizer
To enable [Memory Sanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), use the `--sanitize-memory` option or `-fsanitize=memory`. It requires clang and is incompatible with ASAN and UBSAN. Building with this option helps catch issues related to uninitialized memory reads.
To build with Memory Sanitizer, use the following command:
```
CC=/usr/bin/clang CXX=/usr/bin/clang++ ./build_oai ... --sanitize-memory
```
## Thread Sanitizer
[Thread Sanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) can be activated using the `--sanitize-thread` option or `-fsanitize=thread`. This sanitizer helps identify data races and other threading-related issues in the code.
# Summary of Sanitizer Options
- `--sanitize`: Shortcut for using both ASAN and UBSAN.
- `--sanitize-address` or `-fsanitize=address`: Enable ASAN on all targets.
- `--sanitize-undefined` or `-fsanitize=undefined`: Enable UBSAN on all targets.
- `--sanitize-memory` or `-fsanitize=memory`: Enable Memory Sanitizer on all targets (requires clang).
- `--sanitize-thread` or `-fsanitize=thread`: Enable Thread Sanitizer on all targets.
......@@ -400,7 +400,7 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
}
}
// If CU
// E1AP initialisation, whether the node is a CU or has integrated CU
if (node_type == ngran_gNB_CU || node_type == ngran_gNB) {
MessageDef *msg = RCconfig_NR_CU_E1(NULL);
instance_t inst = 0;
......
......@@ -22,18 +22,27 @@
/* gNB_CUUP application layer -> E1AP messages */
MESSAGE_DEF(E1AP_REGISTER_REQ, MESSAGE_PRIORITY_MED, e1ap_register_req_t, e1ap_register_req)
/* E1AP messages -> RRC (CU-CP) */
MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req)
/* E1AP -> RRC to inform about lost connection */
MESSAGE_DEF(E1AP_LOST_CONNECTION, MESSAGE_PRIORITY_MED, e1ap_lost_connection_t, e1ap_lost_connection)
/* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */
/* E1AP Interface Management Messages */
/* E1AP Setup Request: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req)
/* E1AP Setup Response: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_setup_resp)
/* E1AP Setup Failure: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_SETUP_FAIL, MESSAGE_PRIORITY_MED, e1ap_setup_fail_t, e1ap_setup_fail)
/* E1AP Bearer Context Management Procedures */
/* E1AP Bearer Context Setup Request: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req)
/* E1AP Bearer Context Setup Response: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp)
/* E1AP Bearer Context Modification Request: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req)
/* E1AP Bearer Context Modification Response: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, e1ap_bearer_modif_resp_t, e1ap_bearer_modif_resp)
/* E1AP Bearer Context Release Request: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cmd_t, e1ap_bearer_release_cmd)
/* E1AP Bearer Context Release Response: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CPLT, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cplt_t, e1ap_bearer_release_cplt)
......@@ -44,12 +44,14 @@
#define E1AP_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_register_req
#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req
#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp
#define E1AP_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_fail
#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
#define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
#define E1AP_BEARER_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_modif_resp
#define E1AP_BEARER_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cmd
#define E1AP_BEARER_CONTEXT_RELEASE_CPLT(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cplt
#define E1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.e1ap_lost_connection
typedef net_ip_address_t e1ap_net_ip_address_t;
......@@ -94,6 +96,11 @@ typedef struct e1ap_setup_resp_s {
long transac_id;
} e1ap_setup_resp_t;
/* E1AP Setup Failure */
typedef struct e1ap_setup_fail_s {
long transac_id;
} e1ap_setup_fail_t;
typedef struct cell_group_s {
long id;
} cell_group_t;
......@@ -273,4 +280,10 @@ typedef struct e1ap_bearer_modif_resp_s {
pdu_session_modif_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
} e1ap_bearer_modif_resp_t;
/* E1AP Connection Loss indication */
typedef struct e1ap_lost_connection_t {
int dummy;
} e1ap_lost_connection_t;
#endif /* E1AP_MESSAGES_TYPES_H */
......@@ -36,6 +36,10 @@
#define E1AP_NUM_MSG_HANDLERS 14
typedef int (*e1ap_message_processing_t)(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p);
/**
* @brief E1AP messages handlers
*/
const e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = {
{0, 0, 0}, /* Reset */
......@@ -61,17 +65,17 @@ const e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3
const char *const e1ap_direction2String(int e1ap_dir)
{
static const char *e1ap_direction_String[] = {
"", /* Nothing */
"Initiating message", /* initiating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
"", /* Nothing */
"Initiating message", /* initiating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(e1ap_direction_String[e1ap_dir]);
return (e1ap_direction_String[e1ap_dir]);
}
int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_t *const data, const uint32_t data_length)
static int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_t *const data, const uint32_t data_length)
{
E1AP_E1AP_PDU_t pdu= {0};
E1AP_E1AP_PDU_t pdu = {0};
int ret;
DevAssert(data != NULL);
......@@ -81,19 +85,25 @@ int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_
}
const E1AP_ProcedureCode_t procedureCode = pdu.choice.initiatingMessage->procedureCode;
/* Checking procedure Code and direction of message */
if ((procedureCode >= E1AP_NUM_MSG_HANDLERS) || (pdu.present > E1AP_E1AP_PDU_PR_unsuccessfulOutcome) || (pdu.present <= E1AP_E1AP_PDU_PR_NOTHING)) {
if ((procedureCode >= E1AP_NUM_MSG_HANDLERS) || (pdu.present > E1AP_E1AP_PDU_PR_unsuccessfulOutcome)
|| (pdu.present <= E1AP_E1AP_PDU_PR_NOTHING)) {
LOG_E(E1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", assoc_id, procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, &pdu);
return -1;
}
if (e1ap_message_processing[procedureCode][pdu.present - 1] == NULL) {
// No handler present. This can mean not implemented or no procedure for eNB (wrong direction).
LOG_E(E1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", assoc_id, procedureCode, e1ap_direction2String(pdu.present - 1));
ret=-1;
// No handler present. This can mean not implemented or no procedure for eNB
// (wrong direction).
LOG_E(E1AP,
"[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id,
procedureCode,
e1ap_direction2String(pdu.present - 1));
ret = -1;
} else {
/* Calling the right handler */
LOG_D(E1AP, "Calling handler with instance %ld\n",instance);
LOG_D(E1AP, "Calling handler with instance %ld\n", instance);
ret = (*e1ap_message_processing[procedureCode][pdu.present - 1])(assoc_id, getCxtE1(instance), &pdu);
}
......@@ -101,37 +111,37 @@ int e1ap_handle_message(instance_t instance, sctp_assoc_t assoc_id, const uint8_
return ret;
}
void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind)
static void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind)
{
int result;
DevAssert(sctp_data_ind != NULL);
e1ap_handle_message(instance, sctp_data_ind->assoc_id,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
e1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->buffer, sctp_data_ind->buffer_length);
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
int e1ap_send_RESET(bool isCu, sctp_assoc_t assoc_id, E1AP_Reset_t *Reset)
{
AssertFatal(false,"Not implemented yet\n");
E1AP_E1AP_PDU_t pdu= {0};
AssertFatal(false, "Not implemented yet\n");
E1AP_E1AP_PDU_t pdu = {0};
return e1ap_encode_send(isCu, assoc_id, &pdu, 0, __func__);
}
int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) {
AssertFatal(false,"Not implemented yet\n");
int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1ap_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -140,16 +150,16 @@ int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, ui
*/
int e1ap_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication) {
AssertFatal(false,"Not implemented yet\n");
int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
/*
E1 Setup: can be sent on both ways, to be refined
*/
......@@ -207,7 +217,7 @@ static void fill_SETUP_REQUEST(e1ap_setup_req_t *setup, E1AP_E1AP_PDU_t *pdu)
int numSupportedPLMNs = setup->supported_plmns;
for (int i=0; i < numSupportedPLMNs; i++) {
for (int i = 0; i < numSupportedPLMNs; i++) {
asn1cSequenceAdd(ieC5->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN);
/* 5.1 PLMN Identity */
PLMN_ID_t *id = &setup->plmn[i].id;
......@@ -257,25 +267,36 @@ void e1ap_send_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_setup_resp_t *e1
e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
}
/**
* @brief E1 Setup Failure ASN1 messager builder
* @ref 9.2.1.6 GNB-CU-UP E1 SETUP FAILURE of 3GPP TS 38.463
*/
static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu)
{
/* Create */
/* 0. pdu Type */
pdu->present = E1AP_E1AP_PDU_PR_unsuccessfulOutcome;
asn1cCalloc(pdu->choice.unsuccessfulOutcome, initMsg);
/* mandatory */
/**
* Message Type IE
* - procedureCode (integer)
* - Type of Message (choice)
* @ref clause 9.3.1.1 of 3GPP TS 38.463
*/
initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup;
initMsg->criticality = E1AP_Criticality_reject;
initMsg->value.present = E1AP_UnsuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupFailure;
E1AP_GNB_CU_UP_E1SetupFailure_t *out = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
/* mandatory */
/* c1. Transaction ID (integer value) */
/* c1. Transaction ID (integer value), clause 9.3.1.53 of 3GPP TS 38.463 */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC1);
ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID;
ieC1->criticality = E1AP_Criticality_reject;
ieC1->value.present = E1AP_GNB_CU_UP_E1SetupFailureIEs__value_PR_TransactionID;
ieC1->value.choice.TransactionID = transac_id;
/* mandatory */
/* c2. cause (integer value) */
/* c2. cause (integer value), clause 9.3.1.2 of 3GPP TS 38.463 */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC2);
ieC2->id = E1AP_ProtocolIE_ID_id_Cause;
ieC2->criticality = E1AP_Criticality_ignore;
......@@ -284,33 +305,34 @@ static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu)
ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified;
}
/**
* @brief E1 Setup Failure ASN1 messager encoder
*/
void e1apCUCP_send_SETUP_FAILURE(sctp_assoc_t assoc_id, long transac_id)
{
LOG_D(E1AP, "CU-CP: Encoding E1AP Setup Failure for transac_id %ld...\n", transac_id);
E1AP_E1AP_PDU_t pdu = {0};
fill_SETUP_FAILURE(transac_id, &pdu);
e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
}
void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
e1ap_setup_req_t *req) {
static void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_setup_req_t *req)
{
E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie;
E1AP_GNB_CU_UP_E1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest;
/* transac_id */
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_TransactionID, true);
req->transac_id = ie->value.choice.TransactionID;
LOG_D(E1AP, "gNB CU UP E1 setup request transaction ID: %ld\n", req->transac_id);
/* gNB CU UP ID */
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID, true);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID, true);
asn_INTEGER2ulong(&ie->value.choice.GNB_CU_UP_ID, &req->gNB_cu_up_id);
LOG_D(E1AP, "gNB CU UP ID: %ld\n", req->gNB_cu_up_id);
/* gNB CU UP name */
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_gNB_CU_UP_Name, false);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_UP_Name, false);
req->gNB_cu_up_name = NULL;
if (ie != NULL) {
req->gNB_cu_up_name = calloc(ie->value.choice.GNB_CU_UP_Name.size + 1, sizeof(char));
......@@ -320,18 +342,17 @@ void extract_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
}
/* CN Support */
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_CNSupport, true);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_CNSupport, true);
AssertFatal(ie->value.choice.CNSupport == E1AP_CNSupport_c_5gc, "only 5GC CN Support supported\n");
/* Supported PLMNs */
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_SupportedPLMNs, true);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_SupportedPLMNs, true);
req->supported_plmns = ie->value.choice.SupportedPLMNs_List.list.count;
LOG_D(E1AP, "Number of supported PLMNs: %d\n", req->supported_plmns);
for (int i=0; i < req->supported_plmns; i++) {
E1AP_SupportedPLMNs_Item_t *supported_plmn_item = (E1AP_SupportedPLMNs_Item_t *)(ie->value.choice.SupportedPLMNs_List.list.array[i]);
for (int i = 0; i < req->supported_plmns; i++) {
E1AP_SupportedPLMNs_Item_t *supported_plmn_item =
(E1AP_SupportedPLMNs_Item_t *)(ie->value.choice.SupportedPLMNs_List.list.array[i]);
/* PLMN Identity */
PLMN_ID_t *id = &req->plmn[i].id;
......@@ -389,8 +410,7 @@ int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst
/* transac_id */
long transaction_id;
long old_transaction_id = inst->cuup.setupReq.transac_id;
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ie, in, E1AP_ProtocolIE_ID_id_TransactionID, true);
transaction_id = ie->value.choice.TransactionID;
LOG_D(E1AP, "gNB CU UP E1 setup response transaction ID: %ld\n", transaction_id);
......@@ -404,18 +424,29 @@ int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst
return 0;
}
/**
* @brief E1 Setup Failure ASN1 messager decoder on CU-UP
*/
int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
{
LOG_D(E1AP, "CU-UP: Decoding E1AP Setup Failure...\n");
E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie;
DevAssert(pdu != NULL);
E1AP_GNB_CU_UP_E1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
/* Transaction ID */
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, E1AP_ProtocolIE_ID_id_TransactionID, true);
long transaction_id;
long old_transaction_id = inst->cuup.setupReq.transac_id;
transaction_id = ie->value.choice.TransactionID;
if (old_transaction_id != transaction_id)
LOG_E(E1AP, "Transaction IDs do not match %ld != %ld\n", old_transaction_id, transaction_id);
E1AP_free_transaction_identifier(transaction_id);
/* Cause */
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in,
E1AP_ProtocolIE_ID_id_Cause, true);
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, E1AP_ProtocolIE_ID_id_Cause, true);
LOG_E(E1AP, "received E1 Setup Failure, please check the CU-CP output and the CU-UP parameters\n");
exit(1);
return 0;
}
......@@ -445,7 +476,7 @@ static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu)
int numSupportedPLMNs = 1;
for (int i=0; i < numSupportedPLMNs; i++) {
for (int i = 0; i < numSupportedPLMNs; i++) {
asn1cSequenceAdd(ieC2->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN);
/* 5.1 PLMN Identity */
OCTET_STRING_fromBuf(&supportedPLMN->pLMN_Identity, "OAI", strlen("OAI"));
......@@ -460,7 +491,7 @@ static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu)
int numTNLAtoRemoveList = 1;
for (int i=0; i < numTNLAtoRemoveList; i++) {
for (int i = 0; i < numTNLAtoRemoveList; i++) {
asn1cSequenceAdd(ieC2->value.choice.GNB_CU_UP_TNLA_To_Remove_List.list, E1AP_GNB_CU_UP_TNLA_To_Remove_Item_t, TNLAtoRemove);
TNLAtoRemove->tNLAssociationTransportLayerAddress.present = E1AP_CP_TNL_Information_PR_endpoint_IP_Address;
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &TNLAtoRemove->tNLAssociationTransportLayerAddress.choice.endpoint_IP_Address); // TODO: correct me
......@@ -480,13 +511,13 @@ void e1apCUUP_send_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id)
int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(void)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(void)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -498,23 +529,19 @@ int e1apCUCP_handle_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu)
E1AP_GNB_CU_UP_E1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest;
*/
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
uint32_t stream,
E1AP_E1AP_PDU_t *pdu)
int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
uint32_t stream,
E1AP_E1AP_PDU_t *pdu)
int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -522,25 +549,27 @@ int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
E1 release
*/
int e1ap_send_RELEASE_REQUEST(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1ap_send_RELEASE_REQUEST(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1ap_handle_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -612,7 +641,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
msgNGRAN->criticality = E1AP_Criticality_reject;
msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List;
E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
for(pdu_session_to_setup_t *i=bearerCxt->pduSession; i < bearerCxt->pduSession+bearerCxt->numPDUSessions; i++) {
for (pdu_session_to_setup_t *i = bearerCxt->pduSession; i < bearerCxt->pduSession + bearerCxt->numPDUSessions; i++) {
asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Setup_Item_t, ieC6_1);
ieC6_1->pDU_Session_ID = i->sessionId;
ieC6_1->pDU_Session_Type = i->sessionType;
......@@ -632,7 +661,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress);
INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID);
for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRB2Setup; j++) {
for (DRB_nGRAN_to_setup_t *j = i->DRBnGRanList; j < i->DRBnGRanList + i->numDRB2Setup; j++) {
asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1);
ieC6_1_1->dRB_ID = j->id;
......@@ -648,12 +677,12 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
roTimer->t_Reordering = j->reorderingTimer;
ieC6_1_1->pDCP_Configuration.rLC_Mode = j->rLC_Mode;
for (cell_group_t *k=j->cellGroupList; k < j->cellGroupList+j->numCellGroups; k++) {
for (cell_group_t *k = j->cellGroupList; k < j->cellGroupList + j->numCellGroups; k++) {
asn1cSequenceAdd(ieC6_1_1->cell_Group_Information.list, E1AP_Cell_Group_Information_Item_t, ieC6_1_1_1);
ieC6_1_1_1->cell_Group_ID = k->id;
}
for (qos_flow_to_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlow2Setup; k++) {
for (qos_flow_to_setup_t *k = j->qosFlows; k < j->qosFlows + j->numQosFlow2Setup; k++) {
asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1);
ieC6_1_1_1->qoS_Flow_Identifier = k->qfi;
......@@ -697,66 +726,78 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r
pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome;
asn1cCalloc(pdu->choice.successfulOutcome, msg);
msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup;
msg->criticality = E1AP_Criticality_reject;
msg->criticality = E1AP_Criticality_reject;
msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse;
E1AP_BearerContextSetupResponse_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse;
/* mandatory */
/* c1. gNB-CU-CP UE E1AP ID */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC1);
ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
ieC1->criticality = E1AP_Criticality_reject;
ieC1->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
ieC1->criticality = E1AP_Criticality_reject;
ieC1->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_cp_ue_id;
/* mandatory */
/* c2. gNB-CU-UP UE E1AP ID */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC2);
ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
ieC2->criticality = E1AP_Criticality_reject;
ieC2->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
ieC2->criticality = E1AP_Criticality_reject;
ieC2->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
ieC2->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_up_ue_id;
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC3);
ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse;
ieC3->criticality = E1AP_Criticality_reject;
ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse;
ieC3->criticality = E1AP_Criticality_reject;
ieC3->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse;
/*if (0) { // EUTRAN
ieC3->value.choice.System_BearerContextSetupResponse.present = E1AP_System_BearerContextSetupResponse_PR_e_UTRAN_BearerContextSetupResponse;
E1AP_ProtocolIE_Container_4932P21_t *msgEUTRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P21_t));
ieC3->value.choice.System_BearerContextSetupResponse.choice.e_UTRAN_BearerContextSetupResponse = (struct E1AP_ProtocolIE_Container *) msgEUTRAN_list;
asn1cSequenceAdd(msgEUTRAN_list->list, E1AP_EUTRAN_BearerContextSetupResponse_t, msgEUTRAN);
msgEUTRAN->id = E1AP_ProtocolIE_ID_id_DRB_Setup_List_EUTRAN;
msgEUTRAN->criticality = E1AP_Criticality_reject;
msgEUTRAN->value.present = E1AP_EUTRAN_BearerContextSetupResponse__value_PR_DRB_Setup_List_EUTRAN;
E1AP_DRB_Setup_List_EUTRAN_t *drbSetup = &msgEUTRAN->value.choice.DRB_Setup_List_EUTRAN;
ieC3->value.choice.System_BearerContextSetupResponse.present =
E1AP_System_BearerContextSetupResponse_PR_e_UTRAN_BearerContextSetupResponse;
E1AP_ProtocolIE_Container_4932P21_t *msgEUTRAN_list = calloc(1,
sizeof(E1AP_ProtocolIE_Container_4932P21_t));
ieC3->value.choice.System_BearerContextSetupResponse.choice.e_UTRAN_BearerContextSetupResponse
= (struct E1AP_ProtocolIE_Container *) msgEUTRAN_list;
asn1cSequenceAdd(msgEUTRAN_list->list,
E1AP_EUTRAN_BearerContextSetupResponse_t, msgEUTRAN); msgEUTRAN->id =
E1AP_ProtocolIE_ID_id_DRB_Setup_List_EUTRAN; msgEUTRAN->criticality =
E1AP_Criticality_reject; msgEUTRAN->value.present =
E1AP_EUTRAN_BearerContextSetupResponse__value_PR_DRB_Setup_List_EUTRAN;
E1AP_DRB_Setup_List_EUTRAN_t *drbSetup =
&msgEUTRAN->value.choice.DRB_Setup_List_EUTRAN;
for (drb_setup_t *i=resp->DRBList; i < resp->DRBList+resp->numDRBs; i++) {
asn1cSequenceAdd(drbSetup->list, E1AP_DRB_Setup_Item_EUTRAN_t, ieC3_1);
ieC3_1->dRB_ID = i->drbId;
ieC3_1->s1_DL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
ieC3_1->s1_DL_UP_TNL_Information.present =
E1AP_UP_TNL_Information_PR_gTPTunnel;
asn1cCalloc(ieC3_1->s1_DL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel);
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress);
INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID);
for (up_params_t *j=i->UpParamList; j < i->UpParamList+i->numUpParam; j++) {
asn1cSequenceAdd(ieC3_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1);
ieC3_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress,
&gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(i->teId,
&gTPTunnel->gTP_TEID);
for (up_params_t *j=i->UpParamList; j < i->UpParamList+i->numUpParam; j++)
{ asn1cSequenceAdd(ieC3_1->uL_UP_Transport_Parameters.list,
E1AP_UP_Parameters_Item_t, ieC3_1_1); ieC3_1_1->uP_TNL_Information.present =
E1AP_UP_TNL_Information_PR_gTPTunnel;
asn1cCalloc(ieC3_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(j->tlAddress, &gTPTunnel->transportLayerAddress);
INT32_TO_OCTET_STRING(j->teId, &gTPTunnel->gTP_TEID);
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(j->tlAddress,
&gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(j->teId,
&gTPTunnel->gTP_TEID);
}
}
} else */{
ieC3->value.choice.System_BearerContextSetupResponse.present = E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse;
} else */
{
ieC3->value.choice.System_BearerContextSetupResponse.present =
E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse;
E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P22_t));
ieC3->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list;
ieC3->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse =
(struct E1AP_ProtocolIE_Container *)msgNGRAN_list;
asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupResponse_t, msgNGRAN);
msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List;
msgNGRAN->criticality = E1AP_Criticality_reject;
msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List;
E1AP_PDU_Session_Resource_Setup_List_t *pduSetup = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List;
for (const pdu_session_setup_t *i=resp->pduSession; i < resp->pduSession+resp->numPDUSessions; i++) {
for (const pdu_session_setup_t *i = resp->pduSession; i < resp->pduSession + resp->numPDUSessions; i++) {
asn1cSequenceAdd(pduSetup->list, E1AP_PDU_Session_Resource_Setup_Item_t, ieC3_1);
ieC3_1->pDU_Session_ID = i->id;
......@@ -765,11 +806,11 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress);
INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID);
for (const DRB_nGRAN_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRBSetup; j++) {
for (const DRB_nGRAN_setup_t *j = i->DRBnGRanList; j < i->DRBnGRanList + i->numDRBSetup; j++) {
asn1cSequenceAdd(ieC3_1->dRB_Setup_List_NG_RAN.list, E1AP_DRB_Setup_Item_NG_RAN_t, ieC3_1_1);
ieC3_1_1->dRB_ID = j->id;
for (const up_params_t *k=j->UpParamList; k < j->UpParamList+j->numUpParam; k++) {
for (const up_params_t *k = j->UpParamList; k < j->UpParamList + j->numUpParam; k++) {
asn1cSequenceAdd(ieC3_1_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1_1);
ieC3_1_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
asn1cCalloc(ieC3_1_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
......@@ -777,7 +818,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r
INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID);
}
for (const qos_flow_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlowSetup; k++) {
for (const qos_flow_setup_t *k = j->qosFlows; k < j->qosFlows + j->numQosFlowSetup; k++) {
asn1cSequenceAdd(ieC3_1_1->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, ieC3_1_1_1);
ieC3_1_1_1->qoS_Flow_Identifier = k->qfi;
}
......@@ -786,7 +827,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r
if (i->numDRBFailed > 0)
ieC3_1->dRB_Failed_List_NG_RAN = calloc(1, sizeof(E1AP_DRB_Failed_List_NG_RAN_t));
for (const DRB_nGRAN_failed_t *j=i->DRBnGRanFailedList; j < i->DRBnGRanFailedList+i->numDRBFailed; j++) {
for (const DRB_nGRAN_failed_t *j = i->DRBnGRanFailedList; j < i->DRBnGRanFailedList + i->numDRBFailed; j++) {
asn1cSequenceAdd(ieC3_1->dRB_Failed_List_NG_RAN->list, E1AP_DRB_Failed_Item_NG_RAN_t, ieC3_1_1);
ieC3_1_1->dRB_ID = j->id;
......@@ -824,19 +865,20 @@ void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1
e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__);
}
int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
e1ap_bearer_setup_req_t *bearerCxt) {
void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *bearerCxt)
{
const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
E1AP_BearerContextSetupRequestIEs_t *ie;
LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
for (int i=0; i < in->protocolIEs.list.count; i++) {
for (int i = 0; i < in->protocolIEs.list.count; i++) {
ie = in->protocolIEs.list.array[i];
switch(ie->id) {
......@@ -898,7 +940,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2SetupList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
bearerCxt->numPDUSessions = pdu2SetupList->list.count;
for (int i=0; i < pdu2SetupList->list.count; i++) {
for (int i = 0; i < pdu2SetupList->list.count; i++) {
pdu_session_to_setup_t *pdu_session = bearerCxt->pduSession + i;
E1AP_PDU_Session_Resource_To_Setup_Item_t *pdu2Setup = pdu2SetupList->list.array[i];
......@@ -923,7 +965,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
E1AP_DRB_To_Setup_List_NG_RAN_t *drb2SetupList = &pdu2Setup->dRB_To_Setup_List_NG_RAN;
pdu_session->numDRB2Setup = drb2SetupList->list.count;
for (int j=0; j < drb2SetupList->list.count; j++) {
for (int j = 0; j < drb2SetupList->list.count; j++) {
DRB_nGRAN_to_setup_t *drb = pdu_session->DRBnGRanList + j;
E1AP_DRB_To_Setup_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j];
......@@ -948,7 +990,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information;
drb->numCellGroups = cellGroupList->list.count;
for (int k=0; k < cellGroupList->list.count; k++) {
for (int k = 0; k < cellGroupList->list.count; k++) {
E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k];
drb->cellGroupList[k].id = cg2Setup->cell_Group_ID;
......@@ -956,7 +998,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
E1AP_QoS_Flow_QoS_Parameter_List_t *qos2SetupList = &drb2Setup->qos_flow_Information_To_Be_Setup;
drb->numQosFlow2Setup = qos2SetupList->list.count;
for (int k=0; k < qos2SetupList->list.count; k++) {
for (int k = 0; k < qos2SetupList->list.count; k++) {
qos_flow_to_setup_t *qos_flow = drb->qosFlows + k;
E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k];
......@@ -993,8 +1035,6 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu,
break;
}
}
}
int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
......@@ -1012,14 +1052,14 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upc
return 0;
}
void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu,
e1ap_bearer_setup_resp_t *bearerCxt) {
void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_resp_t *bearerCxt)
{
const E1AP_BearerContextSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse;
E1AP_BearerContextSetupResponseIEs_t *ie;
LOG_D(E1AP, "Bearer context setup response number of IEs %d\n", in->protocolIEs.list.count);
for (int i=0; i < in->protocolIEs.list.count; i++) {
for (int i = 0; i < in->protocolIEs.list.count; i++) {
ie = in->protocolIEs.list.array[i];
switch(ie->id) {
......@@ -1049,7 +1089,7 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu,
E1AP_PDU_Session_Resource_Setup_List_t *pduSetupList = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List;
bearerCxt->numPDUSessions = pduSetupList->list.count;
for (int i=0; i < pduSetupList->list.count; i++) {
for (int i = 0; i < pduSetupList->list.count; i++) {
pdu_session_setup_t *pduSetup = bearerCxt->pduSession + i;
E1AP_PDU_Session_Resource_Setup_Item_t *pdu_session = pduSetupList->list.array[i];
pduSetup->id = pdu_session->pDU_Session_ID;
......@@ -1063,14 +1103,14 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu,
}
pduSetup->numDRBSetup = pdu_session->dRB_Setup_List_NG_RAN.list.count;
for (int j=0; j < pdu_session->dRB_Setup_List_NG_RAN.list.count; j++) {
for (int j = 0; j < pdu_session->dRB_Setup_List_NG_RAN.list.count; j++) {
DRB_nGRAN_setup_t *drbSetup = pduSetup->DRBnGRanList + j;
E1AP_DRB_Setup_Item_NG_RAN_t *drb = pdu_session->dRB_Setup_List_NG_RAN.list.array[j];
drbSetup->id = drb->dRB_ID;
drbSetup->numUpParam = drb->uL_UP_Transport_Parameters.list.count;
for (int k=0; k < drb->uL_UP_Transport_Parameters.list.count; k++) {
for (int k = 0; k < drb->uL_UP_Transport_Parameters.list.count; k++) {
up_params_t *UL_UP_param = drbSetup->UpParamList + k;
E1AP_UP_Parameters_Item_t *in_UL_UP_param = drb->uL_UP_Transport_Parameters.list.array[k];
......@@ -1126,7 +1166,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_up
int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -1170,18 +1210,18 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
msgNGRAN->criticality = E1AP_Criticality_reject;
msgNGRAN->value.present = E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List;
E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List;
for(pdu_session_to_setup_t *i=bearerCxt->pduSessionMod; i < bearerCxt->pduSessionMod+bearerCxt->numPDUSessionsMod; i++) {
for (pdu_session_to_setup_t *i = bearerCxt->pduSessionMod; i < bearerCxt->pduSessionMod + bearerCxt->numPDUSessionsMod; i++) {
asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Modify_Item_t, ieC3_1);
ieC3_1->pDU_Session_ID = i->sessionId;
for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanModList; j < i->DRBnGRanModList+i->numDRB2Modify; j++) {
for (DRB_nGRAN_to_setup_t *j = i->DRBnGRanModList; j < i->DRBnGRanModList + i->numDRB2Modify; j++) {
asn1cCalloc(ieC3_1->dRB_To_Modify_List_NG_RAN, drb2Mod_List);
asn1cSequenceAdd(drb2Mod_List->list, E1AP_DRB_To_Modify_Item_NG_RAN_t, drb2Mod);
drb2Mod->dRB_ID = j->id;
if (j->numDlUpParam > 0) {
asn1cCalloc(drb2Mod->dL_UP_Parameters, DL_UP_Param_List);
for (up_params_t *k=j->DlUpParamList; k < j->DlUpParamList+j->numDlUpParam; k++) {
for (up_params_t *k = j->DlUpParamList; k < j->DlUpParamList + j->numDlUpParam; k++) {
asn1cSequenceAdd(DL_UP_Param_List->list, E1AP_UP_Parameters_Item_t, DL_UP_Param);
DL_UP_Param->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
asn1cCalloc(DL_UP_Param->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
......@@ -1268,19 +1308,20 @@ static int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc
return e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__);
}
int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu,
e1ap_bearer_setup_req_t *bearerCxt) {
void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *bearerCxt)
{
const E1AP_BearerContextModificationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest;
E1AP_BearerContextModificationRequestIEs_t *ie;
LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
for (int i=0; i < in->protocolIEs.list.count; i++) {
for (int i = 0; i < in->protocolIEs.list.count; i++) {
ie = in->protocolIEs.list.array[i];
switch(ie->id) {
......@@ -1311,7 +1352,7 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu,
E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2ModList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List;
bearerCxt->numPDUSessionsMod = pdu2ModList->list.count;
for (int i=0; i < pdu2ModList->list.count; i++) {
for (int i = 0; i < pdu2ModList->list.count; i++) {
pdu_session_to_setup_t *pdu_session = bearerCxt->pduSessionMod + i;
E1AP_PDU_Session_Resource_To_Modify_Item_t *pdu2Mod = pdu2ModList->list.array[i];
......@@ -1319,7 +1360,7 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu,
E1AP_DRB_To_Modify_List_NG_RAN_t *drb2ModList = pdu2Mod->dRB_To_Modify_List_NG_RAN;
pdu_session->numDRB2Modify = drb2ModList->list.count;
for (int j=0; j < drb2ModList->list.count; j++) {
for (int j = 0; j < drb2ModList->list.count; j++) {
DRB_nGRAN_to_setup_t *drb = pdu_session->DRBnGRanModList + j;
E1AP_DRB_To_Modify_Item_NG_RAN_t *drb2Mod = drb2ModList->list.array[j];
......@@ -1327,9 +1368,9 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu,
E1AP_UP_Parameters_t *dl_up_paramList = drb2Mod->dL_UP_Parameters;
drb->numDlUpParam = dl_up_paramList->list.count;
for (int k=0; k < dl_up_paramList->list.count; k++) {
for (int k = 0; k < dl_up_paramList->list.count; k++) {
up_params_t *dl_up_param = drb->DlUpParamList + k;
E1AP_UP_Parameters_Item_t *dl_up_param_in = dl_up_paramList->list.array[k];
E1AP_UP_Parameters_Item_t *dl_up_param_in = dl_up_paramList->list.array[k];
if (dl_up_param_in->uP_TNL_Information.choice.gTPTunnel) { // Optional IE
DevAssert(dl_up_param_in->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel);
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->transportLayerAddress,
......@@ -1351,7 +1392,9 @@ void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *pdu,
}
}
int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id,
e1ap_upcp_inst_t *e1_inst,
const E1AP_E1AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage);
......@@ -1403,7 +1446,7 @@ static void extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(const E1AP_E1AP_PDU_t *
E1AP_PDU_Session_Resource_Modified_List_t *pduModifiedList = &msgNGRAN->value.choice.PDU_Session_Resource_Modified_List;
resp->numPDUSessionsMod = pduModifiedList->list.count;
for (int i=0; i < pduModifiedList->list.count; i++) {
for (int i = 0; i < pduModifiedList->list.count; i++) {
pdu_session_modif_t *pduModified = &resp->pduSessionMod[i];
E1AP_PDU_Session_Resource_Modified_Item_t *mod_it = pduModifiedList->list.array[i];
pduModified->id = mod_it->pDU_Session_ID;
......@@ -1416,7 +1459,7 @@ static void extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(const E1AP_E1AP_PDU_t *
AssertFatal(mod_it->dRB_Failed_To_Modify_List_NG_RAN == NULL, "not implemented\n");
pduModified->numDRBModified = mod_it->dRB_Modified_List_NG_RAN->list.count;
for (int j=0; j < mod_it->dRB_Modified_List_NG_RAN->list.count; j++) {
for (int j = 0; j < mod_it->dRB_Modified_List_NG_RAN->list.count; j++) {
DRB_nGRAN_modified_t *drbModified = &pduModified->DRBnGRanModList[j];
E1AP_DRB_Modified_Item_NG_RAN_t *drb = mod_it->dRB_Modified_List_NG_RAN->list.array[j];
......@@ -1433,7 +1476,9 @@ static void extract_BEARER_CONTEXT_MODIFICATION_RESPONSE(const E1AP_E1AP_PDU_t *
}
}
int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id,
e1ap_upcp_inst_t *e1_inst,
const E1AP_E1AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome);
......@@ -1453,17 +1498,19 @@ int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance,
uint32_t stream,
E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -1472,7 +1519,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance,
uint32_t stream,
E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -1481,7 +1528,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
uint32_t stream,
E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
/*
......@@ -1554,19 +1601,20 @@ int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, const e
return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
}
int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu,
e1ap_bearer_release_cmd_t *bearerCxt) {
void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_release_cmd_t *bearerCxt)
{
const E1AP_BearerContextReleaseCommand_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextReleaseCommand;
E1AP_BearerContextReleaseCommandIEs_t *ie;
LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
for (int i=0; i < in->protocolIEs.list.count; i++) {
for (int i = 0; i < in->protocolIEs.list.count; i++) {
ie = in->protocolIEs.list.array[i];
switch(ie->id) {
......@@ -1612,14 +1660,14 @@ int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_u
return 0;
}
void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu,
e1ap_bearer_release_cplt_t *bearerCxt) {
void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_release_cplt_t *bearerCxt)
{
const E1AP_BearerContextReleaseComplete_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete;
E1AP_BearerContextReleaseCompleteIEs_t *ie;
LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
for (int i=0; i < in->protocolIEs.list.count; i++) {
for (int i = 0; i < in->protocolIEs.list.count; i++) {
ie = in->protocolIEs.list.array[i];
switch(ie->id) {
......@@ -1664,7 +1712,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance,
uint32_t stream,
E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -1672,8 +1720,9 @@ int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance,
BEARER CONTEXT INACTIVITY NOTIFICATION
*/
int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
......@@ -1682,39 +1731,42 @@ int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance,
uint32_t stream,
E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
/*
DL DATA
*/
int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance) {
AssertFatal(false,"Not implemented yet\n");
int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance)
{
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUCP_handle_DL_DATA_NOTIFICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
int e1apCUCP_handle_send_DATA_USAGE_REPORT(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu)
{
AssertFatal(false,"Not implemented yet\n");
AssertFatal(false, "Not implemented yet\n");
return -1;
}
static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) {
openAddr_t tmp= {0};
strncpy(tmp.originHost, IPaddrs->my_addr, sizeof(tmp.originHost)-1);
sprintf(tmp.originService, "%d", IPaddrs->my_portd);
static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs)
{
openAddr_t tmp = {0};
strncpy(tmp.originHost, IPaddrs->my_addr, sizeof(tmp.originHost) - 1);
sprintf(tmp.originService, "%d", IPaddrs->my_portd);
sprintf(tmp.destinationService, "%d", IPaddrs->remote_portd);
return gtpv1Init(tmp);
}
......@@ -1742,12 +1794,26 @@ static void e1apCUUP_send_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_setup_req_t
e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__);
}
static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp)
static void e1_task_handle_sctp_association_resp(E1_t type,
instance_t instance,
sctp_new_association_resp_t *sctp_new_association_resp)
{
DevAssert(sctp_new_association_resp != NULL);
getCxtE1(instance)->sockState = sctp_new_association_resp->sctp_state;
if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN) {
LOG_I(E1AP, "Received SCTP shutdown for assoc_id %d, removing CUCP endpoint\n", sctp_new_association_resp->assoc_id);
/* inform RRC that the CU-UP is gone */
MessageDef *message_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_LOST_CONNECTION);
message_p->ittiMsgHeader.originInstance = sctp_new_association_resp->assoc_id;
itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p);
return;
}
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
LOG_W(E1AP,
"Received unsuccessful result for SCTP association (%u), instance "
"%ld, cnx_id %u\n",
sctp_new_association_resp->sctp_state,
instance,
sctp_new_association_resp->ulp_cnx_id);
......@@ -1796,7 +1862,8 @@ void cuup_init_n3(instance_t instance)
N3GTPUInst = &getCxtE1(instance)->gtpInstN3;
}
void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) {
void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr)
{
LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket)\n");
MessageDef *message_p = NULL;
message_p = itti_alloc_new_message (TASK_CUCP_E1, 0, SCTP_INIT_MSG);
......@@ -1832,7 +1899,16 @@ void e1apHandleTimer(instance_t myInstance)
e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->net_config);
}
void *E1AP_CUCP_task(void *arg) {
/**
* @brief E1AP Centralized Unit Control Plane (CU-CP) task function.
*
* This is the main task loop for the E1AP CUCP module:
* it listens for incoming messages from the Inter-Task Interface (ITTI)
* and calls the relevant handlers for each message type.
*
*/
void *E1AP_CUCP_task(void *arg)
{
LOG_I(E1AP, "Starting E1AP at CU CP\n");
MessageDef *msg = NULL;
e1ap_common_init();
......@@ -1840,7 +1916,7 @@ void *E1AP_CUCP_task(void *arg) {
while (1) {
itti_receive_msg(TASK_CUCP_E1, &msg);
instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg);
instance_t myInstance = ITTI_MSG_DESTINATION_INSTANCE(msg);
const int msgType = ITTI_MSG_ID(msg);
LOG_D(E1AP, "CUCP received %s for instance %ld\n", messages_info[msgType].name, myInstance);
sctp_assoc_t assoc_id = msg->ittiMsgHeader.originInstance;
......@@ -1875,6 +1951,10 @@ void *E1AP_CUCP_task(void *arg) {
e1ap_send_SETUP_RESPONSE(assoc_id, &E1AP_SETUP_RESP(msg));
break;
case E1AP_SETUP_FAIL:
e1apCUCP_send_SETUP_FAILURE(assoc_id, E1AP_SETUP_FAIL(msg).transac_id);
break;
case E1AP_BEARER_CONTEXT_SETUP_REQ:
e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
break;
......@@ -1895,11 +1975,19 @@ void *E1AP_CUCP_task(void *arg) {
result = itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d) in E1AP_CUCP_task!\n", result);
msg = NULL;
}
}
void *E1AP_CUUP_task(void *arg) {
/**
* @brief E1AP Centralized Unit User Plane (CU-UP) task function.
*
* This is the main task loop for the E1AP CUUP module:
* it listens for incoming messages from the Inter-Task Interface (ITTI)
* and calls the relevant handlers for each message type.
*
*/
void *E1AP_CUUP_task(void *arg)
{
LOG_I(E1AP, "Starting E1AP at CU UP\n");
e1ap_common_init();
int result;
......@@ -1935,21 +2023,21 @@ void *E1AP_CUUP_task(void *arg) {
const e1ap_upcp_inst_t *inst = getCxtE1(myInstance);
AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance);
e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->cuup.assoc_id, resp);
} break;
} break;
case E1AP_BEARER_CONTEXT_MODIFICATION_RESP: {
const e1ap_bearer_modif_resp_t *resp = &E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg);
const e1ap_upcp_inst_t *inst = getCxtE1(myInstance);
AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance);
e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(inst->cuup.assoc_id, resp);
} break;
} break;
case E1AP_BEARER_CONTEXT_RELEASE_CPLT: {
const e1ap_bearer_release_cplt_t *cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg);
const e1ap_upcp_inst_t *inst = getCxtE1(myInstance);
AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance);
e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->cuup.assoc_id, cplt);
} break;
} break;
default:
LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n");
......@@ -1959,7 +2047,5 @@ void *E1AP_CUUP_task(void *arg) {
result = itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d) in E1AP_CUUP_task!\n", result);
msg = NULL;
}
}
......@@ -148,7 +148,7 @@ void *gNB_app_task(void *args_p)
AssertFatal(false, "Create task for E1AP CP failed\n");
E1_t e1type = CPtype;
MessageDef *msg = RCconfig_NR_CU_E1(&e1type);
AssertFatal(msg != NULL, "Send inti to task for E1AP CP failed\n");
AssertFatal(msg != NULL, "Send ITTI to task for E1AP CP failed\n");
// this sends the E1AP_REGISTER_REQ to CU-CP so it sets up the socket
// it does NOT use the E1AP part
itti_send_msg_to_task(TASK_CUCP_E1, 0, msg);
......
......@@ -129,6 +129,9 @@ sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_
sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd);
int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req);
/* Process indication of E1 connection loss on CU-CP */
void rrc_gNB_process_e1_lost_connection(gNB_RRC_INST *rrc, e1ap_lost_connection_t *lc, sctp_assoc_t assoc_id);
void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
instance_t instance);
......
......@@ -2065,6 +2065,9 @@ static pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi,
return NULL;
}
/**
* @brief E1AP Bearer Context Setup Response processing on CU-CP
*/
void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance)
{
gNB_RRC_INST *rrc = RC.nrrrc[0];
......@@ -2172,6 +2175,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req);
}
/**
* @brief E1AP Bearer Context Modification Response processing on CU-CP
*/
void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp)
{
gNB_RRC_INST *rrc = RC.nrrrc[0];
......@@ -2188,6 +2194,9 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t
}
}
/**
* @brief E1AP Bearer Context Release processing
*/
void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cplt_t *cplt)
{
// there is not really anything to do here as of now
......@@ -2467,6 +2476,10 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_e1_bearer_context_release_cplt(&E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p));
break;
case E1AP_LOST_CONNECTION: /* CUCP */
rrc_gNB_process_e1_lost_connection(RC.nrrrc[0], &E1AP_LOST_CONNECTION(msg_p), msg_p->ittiMsgHeader.originInstance);
break;
case NGAP_PAGING_IND:
rrc_gNB_process_PAGING_IND(msg_p, instance);
break;
......
......@@ -122,6 +122,26 @@ sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue
return ue_data.e1_assoc_id;
}
/* CU-CP Functions */
/**
* @brief Trigger E1AP Setup Failure on CU-CP
*/
static void e1ap_setup_failure(sctp_assoc_t assoc_id, uint64_t transac_id)
{
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, E1AP_SETUP_FAIL);
msg_p->ittiMsgHeader.originInstance = assoc_id;
e1ap_setup_fail_t *setup_fail = &E1AP_SETUP_FAIL(msg_p);
setup_fail->transac_id = transac_id;
LOG_I(NR_RRC, "Triggering E1AP Setup Failure for transac_id %ld, assoc_id %ld\n",
transac_id,
msg_p->ittiMsgHeader.originInstance);
itti_send_msg_to_task(TASK_CUCP_E1, 0 /*unused by callee*/, msg_p);
}
/**
* @brief E1AP Setup Request processing on CU-CP
*/
int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
{
AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n");
......@@ -138,6 +158,7 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
c->setup_req->gNB_cu_up_id,
c->setup_req->gNB_cu_up_name,
c->assoc_id);
e1ap_setup_failure(assoc_id, req->transac_id);
return -1;
}
}
......@@ -151,11 +172,12 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
id->mnc,
rrc->configuration.mcc[i],
rrc->configuration.mnc[i]);
e1ap_setup_failure(assoc_id, req->transac_id);
return -1;
}
}
LOG_I(RRC, "Accepting new CU-UP ID %ld name %s (assoc_id %d)\n", req->gNB_cu_up_id, req->gNB_cu_up_name, assoc_id);
LOG_I(NR_RRC, "Accepting new CU-UP ID %ld name %s (assoc_id %d)\n", req->gNB_cu_up_id, req->gNB_cu_up_name, assoc_id);
nr_rrc_cuup_container_t *cuup = malloc(sizeof(*cuup));
AssertFatal(cuup, "out of memory\n");
cuup->setup_req = malloc(sizeof(*cuup->setup_req));
......@@ -172,3 +194,28 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
return 0;
}
/**
* @brief RRC Processing of the indication of E1 connection loss on CU-CP
*/
void rrc_gNB_process_e1_lost_connection(gNB_RRC_INST *rrc, e1ap_lost_connection_t *lc, sctp_assoc_t assoc_id)
{
LOG_I(NR_RRC, "Received E1 connection loss indication on RRC\n");
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
nr_rrc_cuup_container_t e = {.assoc_id = assoc_id};
nr_rrc_cuup_container_t *cuup = RB_FIND(rrc_cuup_tree, &rrc->cuups, &e);
if (cuup == NULL) {
LOG_W(NR_RRC, "CU-UP for assoc_id %d not found!\n", assoc_id);
return;
}
if (cuup->setup_req != NULL) {
e1ap_setup_req_t *req = cuup->setup_req;
LOG_I(NR_RRC, "releasing CU-UP %s on assoc_id %d\n", req->gNB_cu_up_name, assoc_id);
free(cuup->setup_req);
}
nr_rrc_cuup_container_t *removed = RB_REMOVE(rrc_cuup_tree, &rrc->cuups, cuup);
// Free relevant CU-UP structures
free(cuup);
DevAssert(removed != NULL);
rrc->num_cuups--;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment