Merge remote-tracking branch 'origin/f1-multiple-du' into integration_2023_w44

This commit is contained in:
Robert Schmidt
2023-11-13 16:23:58 +01:00
76 changed files with 1278 additions and 1107 deletions
+1
View File
@@ -60,6 +60,7 @@ ForEachMacros:
- foreach - foreach
- Q_FOREACH - Q_FOREACH
- BOOST_FOREACH - BOOST_FOREACH
- RB_FOREACH
IncludeBlocks: Preserve IncludeBlocks: Preserve
IncludeCategories: IncludeCategories:
- Regex: '^<ext/.*\.h>' - Regex: '^<ext/.*\.h>'
+1
View File
@@ -1292,6 +1292,7 @@ set(L2_NR_SRC
${NR_RRC_DIR}/rrc_gNB_NGAP.c ${NR_RRC_DIR}/rrc_gNB_NGAP.c
${NR_RRC_DIR}/rrc_gNB_radio_bearers.c ${NR_RRC_DIR}/rrc_gNB_radio_bearers.c
${NR_RRC_DIR}/rrc_gNB_cuup.c ${NR_RRC_DIR}/rrc_gNB_cuup.c
${NR_RRC_DIR}/rrc_gNB_du.c
) )
set(L2_SRC_UE set(L2_SRC_UE
+1 -1
View File
@@ -1245,7 +1245,7 @@ class Containerize():
fullStatus = True fullStatus = True
if anyLogs: if anyLogs:
# Analyzing log file(s)! # Analyzing log file(s)!
listOfPossibleRanContainers = ['enb', 'gnb', 'cu', 'du'] listOfPossibleRanContainers = ['enb*', 'gnb*', 'cu*', 'du*']
for container in listOfPossibleRanContainers: for container in listOfPossibleRanContainers:
filenames = './*-oai-' + container + '.log' filenames = './*-oai-' + container + '.log'
cmd = f'ls {filenames}' cmd = f'ls {filenames}'
@@ -75,15 +75,11 @@ security = {
drb_ciphering = "yes"; drb_ciphering = "yes";
drb_integrity = "no"; drb_integrity = "no";
}; };
log_config :
{ log_config : {
global_log_level ="info"; global_log_level = "info";
hw_log_level ="info"; pdcp_log_level = "info";
phy_log_level ="info"; rrc_log_level = "info";
mac_log_level ="info"; f1ap_log_level = "info";
rlc_log_level ="debug"; ngap_log_level = "info";
pdcp_log_level ="info"; };
rrc_log_level ="info";
f1ap_log_level ="debug";
ngap_log_level ="debug";
};
@@ -217,7 +217,7 @@ THREAD_STRUCT = (
rfsimulator: { rfsimulator: {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs" IQfile = "/tmp/rfsimulator.iqs"
@@ -217,21 +217,17 @@ THREAD_STRUCT = (
); );
rfsimulator: { rfsimulator: {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs" IQfile = "/tmp/rfsimulator.iqs"
} }
log_config : log_config: {
{ global_log_level = "info";
global_log_level ="info"; hw_log_level = "info";
hw_log_level ="info"; phy_log_level = "info";
phy_log_level ="info"; mac_log_level = "info";
mac_log_level ="info"; rlc_log_level = "info";
rlc_log_level ="info"; f1ap_log_level = "info";
pdcp_log_level ="info"; };
rrc_log_level ="info";
f1ap_log_level ="debug";
ngap_log_level ="debug";
};
@@ -230,7 +230,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -240,7 +240,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -232,7 +232,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -230,7 +230,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -229,7 +229,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
+17 -18
View File
@@ -32,9 +32,8 @@
000022 000022
000023 000023
000024 000024
000025
020021 020021
020022
030021
100021 100021
</TestCaseRequestedList> </TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList> <TestCaseExclusionList></TestCaseExclusionList>
@@ -72,33 +71,33 @@
<testCase id="000023"> <testCase id="000023">
<class>DeployGenObject</class> <class>DeployGenObject</class>
<desc>Deploy OAI 5G DU RF sim SA</desc> <desc>Deploy 3 OAI 5G DUs RF sim SA</desc>
<yaml_path>yaml_files/5g_f1_rfsimulator</yaml_path> <yaml_path>yaml_files/5g_f1_rfsimulator</yaml_path>
<services>oai-du</services> <services>oai-du oai-du2 oai-du3</services>
<nb_healthy>8</nb_healthy> <nb_healthy>10</nb_healthy>
</testCase> </testCase>
<testCase id="000024"> <testCase id="000024">
<class>DeployGenObject</class> <class>DeployGenObject</class>
<desc>Deploy OAI 5G NR-UE RF sim SA</desc> <desc>Deploy OAI 5G NR-UE RF sim SA</desc>
<yaml_path>yaml_files/5g_f1_rfsimulator</yaml_path> <yaml_path>yaml_files/5g_f1_rfsimulator</yaml_path>
<services>oai-nr-ue</services> <services>oai-nr-ue oai-nr-ue2</services>
<nb_healthy>9</nb_healthy> <nb_healthy>12</nb_healthy>
</testCase>
<testCase id="000025">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
<yaml_path>yaml_files/5g_f1_rfsimulator</yaml_path>
<services>oai-nr-ue3</services>
<nb_healthy>13</nb_healthy>
</testCase> </testCase>
<testCase id="020021"> <testCase id="020021">
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc> <desc>Ping ext-dn from all NR-UEs</desc>
<id>rfsim5g_ue</id> <id>rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3</id>
<ping_args> -c 20 192.168.72.135</ping_args> <ping_args> -c 20 192.168.72.135 -i0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020022">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<ping_args>-c 20 12.1.1.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
@@ -198,6 +198,42 @@ services:
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
oai-du2:
image: oaisoftwarealliance/oai-gnb:develop
privileged: true
container_name: rfsim5g-oai-du2
environment:
USE_ADDITIONAL_OPTIONS: --sa --rfsim --gNBs.[0].gNB_ID 0xe01 --gNBs.[0].nr_cellid 87654321 --gNBs.[0].servingCellConfigCommon.[0].physCellId 1 --MACRLCs.[0].local_n_address 192.168.71.143 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-cu
networks:
public_net:
ipv4_address: 192.168.71.143
volumes:
- ../../conf_files/gnb-du.sa.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
retries: 5
oai-du3:
image: oaisoftwarealliance/oai-gnb:develop
privileged: true
container_name: rfsim5g-oai-du3
environment:
USE_ADDITIONAL_OPTIONS: --sa --rfsim --gNBs.[0].gNB_ID 0xe02 --gNBs.[0].nr_cellid 11111111 --gNBs.[0].servingCellConfigCommon.[0].physCellId 2 --MACRLCs.[0].local_n_address 192.168.71.144 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-cu
networks:
public_net:
ipv4_address: 192.168.71.144
volumes:
- ../../conf_files/gnb-du.sa.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue: oai-nr-ue:
image: oaisoftwarealliance/oai-nr-ue:develop image: oaisoftwarealliance/oai-nr-ue:develop
privileged: true privileged: true
@@ -216,6 +252,42 @@ services:
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
oai-nr-ue2:
image: oaisoftwarealliance/oai-nr-ue:develop
privileged: true
container_name: rfsim5g-oai-nr-ue2
environment:
USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001101 -C 3619200000 --rfsimulator.serveraddr 192.168.71.143 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-du2
networks:
public_net:
ipv4_address: 192.168.71.151
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue3:
image: oaisoftwarealliance/oai-nr-ue:develop
privileged: true
container_name: rfsim5g-oai-nr-ue3
environment:
USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001102 -C 3619200000 --rfsimulator.serveraddr 192.168.71.144 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-du3
networks:
public_net:
ipv4_address: 192.168.71.152
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
networks: networks:
public_net: public_net:
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -71,7 +71,7 @@ int add_bearer(char *buf, int debug, telnet_printfunc_t prnt)
} }
// verify it exists in RRC as well // verify it exists in RRC as well
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti);
if (!rrcue) if (!rrcue)
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
@@ -95,7 +95,7 @@ int release_bearer(char *buf, int debug, telnet_printfunc_t prnt)
} }
// verify it exists in RRC as well // verify it exists in RRC as well
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti);
if (!rrcue) if (!rrcue)
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
+1 -1
View File
@@ -87,7 +87,7 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt)
rnti = strtol(buf, NULL, 16); rnti = strtol(buf, NULL, 16);
if (rnti < 1 || rnti >= 0xfffe) if (rnti < 1 || rnti >= 0xfffe)
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); ue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti);
if (!ue) if (!ue)
ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n"); ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n");
} }
+256 -186
View File
@@ -12,204 +12,44 @@
</tr> </tr>
</table> </table>
# 1. Introduction [[_TOC_]]
We use OpenAirInterface source code, and it's regular deployment scheme. # Introduction
F1 specification is in 3GPP documents: TS 38.470 header document and all documents listed in chapter 2 References of TS 38.470. 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.
This document explains how the source code works. We assume that each DU handles only one cell. Multiple DUs connected to one CU
are supported. Mobility over F1 is not yet supported.
Offered features and deployment instructions are described in: # Control plane status (F1-C)
https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/f1-interface
# 2. Common multi-threading architecture # ## Implementation Status
The CU and DU interfaces are based on ITTI threads (see oai/common/utils/ocp_itti/itti.md) 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.
All OAI upper layers use the ITTI framework to run isolated threads dedicated to one feature. Note that NSA does NOT follow this logic yet, and does not work with F1.
The lower layers adopt case by case specific software architecture.
```mermaid The following messages are currently implemented:
graph TD
Linux[configuration file] --> APP[gNB_app_task]
Socks[Linux UDP] --> GTP[nr_gtpv1u_gNB_task]
APP --> CU
APP --> DU
A[Linux SCTP] -->|sockets| SCTP(OAI itti thread TASK_SCTP)
SCTP-->|TASK_NGAP| NG[ngap_gNB_task]
NG-->|TASK_SCTP| SCTP
SCTP-->|TASK_DU_F1| DU[F1AP_DU_task]
SCTP-->|TASK_CU_F1| CU[F1AP_CU_task]
CU-->|TASK_RRC_GNB| RRC
RRC -->|non ITTI| PHY[OAI L1+L2]
RRC -->|API calls to create tunnels| GTP
PHY --> |user plane| GTP
CU --> |TASK_GTPV1_U| GTP
DU --> |TASK_GTPV1_U| GTP
```
A "task" is a Linux thread running infinite waiting loop on one ITTI queue
app task manages the initial configuration - F1 Setup Request and F1 Setup Response/Failure
- Initial UL RRC, UL/DL RRC Message Transfer
- F1 UE Context management messages for the "good case"
* Setup Request/Response
* Modification Request/Response
* Release Request/Command/Complete
sctp task mamanges the SCTP Linux sockets All other messages are not implemented or not working reliably:
CU code runs in the task F1AP_CU_task. It stores it's private data context in a static variable. No mutex is used, as the single interface to CU ITTI tast in incoming ITTI messages. CU task is a single ITTI queue, but multiple CU could exist in one Linux process, using the "instance id" (called "module id" also) to create separate contextual information for each CU instance. - F1 CU/DU configuration updade
- Paging messages
- Warning Message transmissions
DU code runs in the task F1AP_DU_task. The design is similar to CU task ## High-level F1-C code structure
All GTP-U tunnels are managed in a Linux Thread, that have partially ITTI design:
1. tunnel creation/deletion is by C API functions direct calls (a mutex protects it)
2. outgoing packets are pushed in a ITTI queue to the gtp thread
3. incoming packets are sent to the tunnel creator using a C callback (the callback function is given in tunnel creation order). The callback should not block
# 3. CU F1AP messages #
## startup
CU thread starts when the CU starts. It opens listening socket on F1AP_PORT_NUMBER by sending the appropriate message to TASK_SCTP.
It will accept the first incoming connection on this port
## F1 SETUP
DU has connected, and sent this message.
The CU receives, decode it and send relevant information to RRC thread by message F1AP_SETUP_REQ
## F1 SETUP response
RRC sends two messages to CU F1 task: the information to encode the F1 setup response and a second message to encode F1AP_GNB_CU_CONFIGURATION_UPDATE
Upon reception of these two messages the CU task encodes and sends the messages to the DU
## UE entry
When CCH channel decoding finds a new UE identity, it call rrc_gNB_generate_RRCSetup() that will send F1AP_DL_RRC_MESSAGE to the CU task.
The CU encodes and sends to DU DLRRCMessageTransfer
## UE attach/detach
When rrc_gNB_process_RRCReconfigurationComplete() occurs, the RRC sends to CU task the message F1AP_UE_CONTEXT_SETUP_REQ. The CU task encodes the F1 message UEContextSetup and send it to the DU over F1AP.
This function rrc_gNB_process_RRCReconfigurationComplete() also creates the GTP-U user plane bearers.
## F1AP incoming messages
SCTP tasks sends a ITTI message SCTP_DATA_IND to the CU task.
A array of functions pointers and the F1AP standard identifier "procedureCode", the CU calls the appropriate function
Hereafter the most significant messages processing
### CU_handle_F1_SETUP_REQUEST
Transcodes information to the same message toward RRC (F1AP_SETUP_REQ)
### CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER
Transcodes information to the same message toward RRC (NR_RRC_MAC_CCCH_DATA_IND)
### CU_handle_UL_RRC_MESSAGE_TRANSFER
Encode and send data to PDCP (calling pdcp_data_ind ()) for processing UL data.
# DU F1 Messages
## Startup
The task "gNB app" after rzading the configuration file, sends a first message F1AP_SETUP_REQ to DU task
Using this message, the uniq DU task (Linux Thread) creates a DU instance context memory space, calls SCTP task to create a socket to the CU.
When it receives from the SCTP task the socket creation success, the DU task encodes+sends the F1 setup message to the CU.
## F1AP_INITIAL_UL_RRC_MESSAGE
When MAC layer push UL data to DU task, the DU sends to CU the message InitialULRRCMessageTransfer
## F1AP_UL_RRC_MESSAGE
In case of SRB bearer, the RLC layer use this message to push rlc bearer payload to DU task, that forward to CU
## pdcp_data_ind
This function call in RLC, when it is a DRB will be replaced by F1-U transport to CU
## F1AP incoming messages
SCTP tasks sends a ITTI message SCTP_DATA_IND to the DU task.
A array of functions pointers and the F1AP standard identifier "procedureCode", the DU calls the appropriate function
Hereafter the most significant messages processing
### DU_send_F1_SETUP_RESPONSE
Decode the CU message, then encode a message to TASK_GNB_APP. The thread "APP" extracts the system information block and reconfigure the DU with: du_extract_and_decode_SI(), configure_gnb_du_mac()
### DU_handle_gNB_CU_CONFIGURATION_UPDATE
No developped
### DU_handle_UE_CONTEXT_SETUP_REQUEST
Push data to RLC layer for transmisstion in DL (to the UE) by calling enqueue_rlc_data_req()
### DU_handle_DL_RRC_MESSAGE_TRANSFER
Depending on the content, adds UE context in DU low layers and/or send data to the UE with rlc_data_req()
# F1-U messages
The data path by itself doesn't make any difficulty:
1. for UL, rlc calls pdcp_data_ind (DRB) or sends a message to RRC (SRB). So, we can replace pdcp_data_ind() by du_pdcp_data_ind() that will push the message in the GTP tunnel. In CU, assuming the tunnel is in place, the right call back decapsulate the transport (cu_ul_recv()), then calls pdcp_data_ind() in CU
The SRB are sent in DU RRC tasks via itti F1AP_UL_RRC_MESSAGE (see above the processing)
2. For DL, pdcp (in CU for DRBs) calls rlc_data_req (by a decoupling queue and thread rlc_data_req_thread, so function du_rlc_data_req() or enqueue_rlc_data_req()). in DU, assuming the gtp-u tunnel exists, a reception call back (du_dl_recv()) decapsulate the gtp-u packet and calls du_rlc_data_req()
Hereafter the processing design, that doesn't require to setup a new context storage, as we can use the GTP-U internal tables: rnti+rb=>teid for outgoing gtp-u packets and teid=>rnti+rb for incoming gtp-u packets
In CU case, the DRB tunnel to DU and the tunnel on N3 have the same key (rnti, rb id), but they run in two different GTP-U instances.
Each instance binds on diffrent sockets.
For F1-U, both DU and CU binds on the full quadruplet (IP source, port source, IP destination, port destination) from the configuration file parameters:
local_s_address, remote_s_address,local_s_portd, remote_s_portd
These 4 values are in:
CU: at cell level (same level as nr_cellid parameter), they are read if tr_s_preference = "f1"; is set
DU: in block MACRLCs, if tr_n_preference = "f1"; is set in this block
## tunnels setup
In GTP-U, TS 29.281 specifies a option header (NR RAN Container This extension header may be transmitted in a G-PDU over the X2-U, Xn-U and F1-U user plane interfaces), but it is not mandatory optional header (as is the N3 one).
So, we can use this header a something reliable with other vendors implementation.
In DL, we need to associate the packet with: rnti, rb (radio bearer) and "mui" (a OAI internal id that is optional and may be removed soon) to call rlc_data_req()
In UL, we need also the RNTI, the rb
So, we need to create a gtp-u tunnel for each rb over F1, then manage in CU and DU the association between a uniq TEid and the pair(rnti, rb). This is already what we have in existing OAI GTP-U layer interface.
In F1AP, for each "DRB to Be Setup Item IEs", we have a field TNL (transport network layer) to set a specific GTP tunnel (@IP, TEid, udp port is always 2152). This is the same for each message related to DRBs. (F1AP carries the SRB payload inside F1AP).
So, For each F1AP containing DRB setup/modification/deletion, the related GTP-U tunnels will be modified one to one.
The exception is the intialisation of new tunnel: in the call to tunnel creation, we need to send the remote TEID, but we don't know yet if we are the initial source. In this case, we issue a dummy (0xFFFF) remote teid; when we receive the remote answer, we get the source teid, that we can inform GTP-U with (using update tunnel).
## processing on GTP-U incoming message
Du_dl_recv() or cu_ul_recv() are called because we have set this callbacks in creat/update tunnel calls to gtp-u. As gtp-u maintains a pair(rnti,rbid) associated to each tunnel, the functions can be very simple stateless callback that calls pdcp_data_ind() or rlc_data_req() to get back in normal processing path
## CU/DU outgoing
DU rlc north output goes to du_pdcp_data_ind() that push a outgoing packet request to gtp-u, using the rnti+rb as ids. GTP-U must have the tunnel existing, then it simply implement the same as in N3 for exemple.
CU pdcp south output calls cu_rlc_data_ind() that do the same symetric processing.
# High-level F1-C code structure
The F1 interface is used internally between CU (mostly RRC) and DU (mostly MAC) The F1 interface is used internally between CU (mostly RRC) and DU (mostly MAC)
to exchange information. In DL, the CU sends messages as defined by the to exchange information. In DL, the CU sends messages as defined by the
@@ -252,3 +92,233 @@ Monolithic: mac_rrc_dl_direct.c | |
| | | |
+-------------+ +-------------+
``` ```
# Data plane status (F1-U)
F1-U uses GTP-U for information exchange. The GTP protocol uses some extensions
for NR-U protocol to report buffer status, but this is not properly tested and
might malfunction. One limitation is that the current implementation
acknowledges each packet individually.
Multiple DUs at one CU are supported in the data plane (as in the control plane).
# How to run
As mentioned earlier, OAI uses F1 internally. It is always compiled in.
To start CU/DU, you use `./nr-softmodem` with the appropriate configuration
files, for instance:
```
sudo cmake_targets/ran_build/build/nr-softmodem --sa -O ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf
sudo cmake_targets/ran_build/build/nr-softmodem --sa -O ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf
```
These files are tested in the CI, and are configured for use in docker,
see [this `docker-compose` file](../ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml).
## Configuration of F1 IP/port information
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,
`127.0.0.3` towards the DU, and the DU `127.0.0.4` towards the CU.
In the CU file:
- Update the `gNBs.[0].amf_ip_address` and `gNBs.[0].NETWORK_INTERFACES`
section towards the core (typically, OAI CN is configured to provide a docker
bridge on `192.168.70.129` and the AMF is on `192.168.70.132`):
- `gNBs.[0].amf_ip_address.[0].ipv4 192.168.70.132`
- `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 192.168.70.129`
- `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 192.168.70.132`
- Set `gNBs.[0].tr_s_preference` (transport south-bound) to `f1`
- Update the `gNBs.[0].local_s_address` (CU-local south address) for the F1-C
south-bound interface: `127.0.0.3`
- Note: the `gNBs.[0].remote_s_address` (CU-remote/DU south address) is
ignored, but we recommend to put `0.0.0.0` ("any")
- Ports should match the ones in the DU config, but for simplicity and
standards-conformity, simply set all to 2152:
- `local_s_portc` in CU should match `remote_n_portc` in DU
- `local_s_portd` in CU should match `remote_n_portd` in DU
- `remote_s_portc` in CU should match `local_n_portc` in DU
- `remote_s_portd` in CU should match `local_n_portd` in DU
In the DU file:
- Set `MACRLCs.[0].tr_n_preference` to `f1`
- Update `MACRLCs.[0].local_n_address` (local north-bound address of the DU) to
`127.0.0.4`
- Update `MACRLCs.[].remote_n_address` (remote north-bound address of the CU)
to `127.0.0.3`
Note: all `local_*_if_name` parameters are ignored.
## Configuration of multiple DUs
Upon F1 Setup Request of a new DU, the CU cross-checks that
- no DUs have the same gNB-DU IDs, taken from `gNBs.[0].gNB_ID`, and
- no cells have the same NR Cell ID, taken from `gNBs.[0].nr_cellid`, and
- no cells have the same physical cell IDs, taken from `gNBs.[0].servingCellConfigCommon.[0].physCellId`.
If any of these are the same, the CU will reject the DU with an F1 Setup
Failure. Thus, you should make sure that in the DU's configs, these parameters
are set differently.
You have to of course make sure that the local interface of the DU
(`MACRLCs.[0].local_n_address`) is different as well.
Assuming you use RFsim, you should make the RFsimulator server side (typically
the gNB) bind on different hosts (`rfsimulator.serverport`).
# Code documentation
## Common multi-threading architecture
The CU and DU interfaces are based on ITTI threads (see `common/utils/ocp_itti/itti.md`)
adopted by all OAI upper layers to run isolated threads dedicated to one feature.
```mermaid
graph TD
Linux[configuration file] --> APP[gNB_app_task]
Socks[Linux UDP] --> GTP[nr_gtpv1u_gNB_task]
APP --> CU
APP --> DU
A[Linux SCTP] -->|sockets| SCTP(OAI itti thread TASK_SCTP)
SCTP-->|TASK_NGAP| NG[ngap_gNB_task]
NG-->|TASK_SCTP| SCTP
SCTP-->|TASK_DU_F1| DU[F1AP_DU_task]
SCTP-->|TASK_CU_F1| CU[F1AP_CU_task]
CU-->|TASK_RRC_GNB| RRC
RRC -->|non ITTI| PHY[OAI L1+L2]
RRC -->|API calls to create tunnels| GTP
PHY --> |user plane| GTP
CU --> |TASK_GTPV1_U| GTP
DU --> |TASK_GTPV1_U| GTP
```
A "task" is a Linux thread running an infinite waiting loop on one ITTI queue.
The `app` task manages the initial configuration; the `sctp` task manages the
SCTP Linux sockets.
The CU encoding/decoding runs in the task executing `F1AP_CU_task()`. It stores its private data context in a static variable.
The DU encoding/decoding runs in the task executing `F1AP_DU_task()`. The design is similar to CU task.
All GTP-U tunnels are managed in a Linux Thread, that have partially ITTI design:
1. tunnel creation/deletion is by C API functions direct calls (a mutex protects it)
2. outgoing packets are pushed in a ITTI queue to the gtp thread
3. incoming packets are sent to the tunnel creator using a C callback (the callback function is given in tunnel creation order). The callback should not block
## F1-C messages towards the CU
The CU thread starts when the CU starts. It opens listening socket on the
configuration-specified IP/port by sending the appropriate message to
`TASK_SCTP`. It will accept any incoming connection and forward any F1 message
to RRC.
You can trace any message by looking up the handler
`cu_task_handle_sctp_data_ind()`, which ultimately triggers a corresponding
ITTI message sent to RRC. All ITTI messages arriving are dispatched in the ITTI
message handling function in `rrc_gNB.c`. For your convenience, find below a
table of same messages that might arrive from the DU and how they are
forwarded.
After handling messages, the RRC uses a callback that determines if messages go
directly to the MAC or are sent to the CU ITTI task (see
[above](#high-level-f1-c-code-structure))
You might also want to consult TS 38.401 regarding the message exchange.
| Incoming F1 message | ITTI message to RRC | RRC handler | Comments |
|---------------------|---------------------|-------------|----------|
| F1 Setup Request | `F1AP_SETUP_REQ` | `rrc_gNB_process_f1_setup_req()` | will trigger either a response or failure |
| Initial UL RRC Message Transfer | `F1AP_INITIAL_UL_RRC_MESSAGE` | `rrc_gNB_process_initial_ul_rrc_message()` | first message from UE, follows up with RRC Setup or Reestablishment |
| UL RRC Message Transfer | `F1AP_UL_RRC_MESSAGE` | `rrc_gNB_decode_dcch()` | UL RRC messages contain DCCH |
| UE Context Response | `F1AP_UE_CONTEXT_SETUP_RESP` | `rrc_CU_process_ue_context_setup_response()` | does not trigger a follow-up, as UE sends Security Response |
| UE Context Modification Response | `F1AP_UE_CONTEXT_MODIFICATION_RESP` | `rrc_CU_process_ue_context_modification_response()` | triggers Reconfiguration if CellGroup in answer |
| UE Context Modification Required | `F1AP_UE_CONTEXT_MODIFICATION_REQUIRED` | `rrc_CU_process_ue_modification_required()` | triggers Reconfiguration |
| UE Context Release Request | `F1AP_UE_CONTEXT_RELEASE_REQ` | `rrc_CU_process_ue_context_release_request()` | RRC will trigger UE release |
| UE Context Release Complete | `F1AP_UE_CONTEXT_RELEASE_COMPLETE` | `rrc_CU_process_ue_context_release_complete()` | frees UE Context, signals to NGAP |
## F1-C Messages towards the DU
The task "gNB app", after reading the configuration file, sends a message
`F1AP_DU_REGISTER_REQ` to the DU task. This message contains network
configuration for the establishment of the SCTP connection, as well as the F1
Setup Request to be sent to the CU.
Using the network configuration, the DU task sets up an SCTP connection via the
SCTP task. When it receives from the SCTP task the socket creation success,
the DU task encodes and sends the F1 setup message to the CU.
Similarly as for the CU, you can trace any message by looking up the handler
`du_task_handle_sctp_data_ind()`. Unlike in the CU, the decoders do NOT send an
ITTI message, but directly call into the scheduler via a message handling
function. This handler acquires the scheduler mutex and executes the
corresponding message handling functionality. All handlers are in
`mac_rrc_dl_handler.c`.
After handling messages, the MAC uses a callback that determines if messages
are sent back to RRC via ITTI, or are sent to the DU ITTI task (see
[above](#high-level-f1-c-code-structure))
You might also want to consult TS 38.401 regarding the message exchange.
| Incoming F1 message | MAC handler | Comments |
|---------------------|-------------|----------|
| F1 Setup Response | `f1_setup_response()` | the DU does not start the radio before receiving this message |
| DL RRC Message Transfer | `dl_rrc_message_transfer()` | Processing timer started if reconfiguration is present[^footnote-reconfig] |
| UE Context Setup Request | `ue_context_setup_request()` | |
| UE Context Modification Request | `ue_context_modification_request()` | |
| UE Context Modification Confirm | `ue_context_modification_confirm()` | |
| UE Context Modification Refuse | `ue_context_modification_refuse()` | Will trigger release request |
| UE Context Release Command | `ue_context_release_command()` | Starts timer for release if UE in sync |
[^footnote-reconfig]: The DU does not decode RRC messages, and does not know
whether an RRC message is a reconfiguration. However, the spec mandates that
a reconfiguration has to be triggered if the CU receives a CellGroupConfig,
originating at the DU. See also flag `expect_reconfiguration`.
## F1-U messages
### General
In the DU in UL, RLC checks in `deliver_sdu()` if we are operating in split
mode, and either (direct) calls `pdcp_data_ind` (DRB) or (f1ap) sends an
`GTPV1U_TUNNEL_DATA_REQ` ITTI message to the GTP task.
In the CU in UL, assuming the tunnel is in place, GTP decapsulates the packet
and calls the callback `cu_f1u_data_req()`, which calls `pdcp_data_ind()` in CU.
In the CU in DL, the PDCP function `deliver_pdu_drb_gnb()` either (direct) calls
into the RLC via `enqueue_rlc_data_req()`, or (f1ap) sends a
`GTPV1U_TUNNEL_DATA_REQ` ITTI message to the GTP task.
In the DU in DL, assuming the GTP-U tunnel exists, GTP decapsulates the packet
and calls the reception call back `du_rlc_data_req()`, which calls
`enqueue_rlc_data_req()` in turn.
## Tunnel Setup
In GTP-U, TS 29.281 specifies a optional header (NR RAN Container). This
extension header may be transmitted in a G-PDU over the X2-U, Xn-U and F1-U user
plane interfaces, but it is not mandatory.
Note that the GTP-U uses internal tables. Instead of exposing TEIDs, it uses the
UE ID (RNTI, RRC UE ID) and Radio Bearer ID to map to a TEID for outgoing GTP-U
packets. Upon receiving, it does the reverse and calls the callbacks. In the CU
case, the DRB tunnel to DU and the tunnel on N3 have the same keys (RRC UE ID,
RB ID), but they run in two different GTP-U instances. Each instance binds on
diffrent sockets, which is the reason you cannot have the same interface for
F1-U and N3/NG-U interfaces (this can be considered a design flaw).
In F1AP, for each "DRB to Be Setup Item IEs", we have a field TNL (transport
network layer) to set a specific GTP tunnel (@IP, TEid). This is the same for
each message related to DRBs.
So, For each F1AP containing DRB setup/modification/deletion, the related GTP-U
tunnels will be modified one to one. The exception is the intialisation of new
tunnel: in the call to tunnel creation, we need to send the remote TEID, but we
don't know yet if we are the initial source. In this case, we issue a dummy
(0xFFFF) remote TEID; when we receive the remote answer, we get the source teid,
with which the GTP-U endpoint is updadet.
+5 -4
View File
@@ -393,10 +393,11 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
return -1; return -1;
} }
LOG_I(NR_RRC, "Creating NR RRC gNB Task, that will also create TASKS\n"); if (!NODE_IS_DU(node_type)) {
if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n");
return -1; return -1;
}
} }
// If CU // If CU
@@ -38,7 +38,7 @@ void read_gtp_sm(void * data)
UE_iterator(UE_info->list, UE) UE_iterator(UE_info->list, UE)
{ {
uint16_t const rnti = UE->rnti; uint16_t const rnti = UE->rnti;
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[mod_id], rnti); struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[mod_id], rnti);
if (ue_context_p != NULL) { if (ue_context_p != NULL) {
gtp->msg.ngut[i].rnti = ue_context_p->ue_context.rnti; gtp->msg.ngut[i].rnti = ue_context_p->ue_context.rnti;
int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions; int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions;
@@ -43,7 +43,7 @@ matched_ues_mac_t filter_ues_by_s_nssai_in_du_or_monolithic(test_cond_e const co
{ {
if (NODE_IS_MONOLITHIC(RC.nrrrc[0]->node_type)) if (NODE_IS_MONOLITHIC(RC.nrrrc[0]->node_type))
{ {
rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti); rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], ue->rnti);
ngap_ue_context_list = ngap_get_ue_context(rrc_ue_context_list->ue_context.rrc_ue_id); ngap_ue_context_list = ngap_get_ue_context(rrc_ue_context_list->ue_context.rrc_ue_id);
assert(ngap_ue_context_list->gNB_instance[0].s_nssai[0][0].sST == value && "Please, check the condition for S-NSSAI. At the moment, OAI supports eMBB"); assert(ngap_ue_context_list->gNB_instance[0].s_nssai[0][0].sST == value && "Please, check the condition for S-NSSAI. At the moment, OAI supports eMBB");
} }
@@ -589,7 +589,7 @@ kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3_in_monolithic(const matched_ues_ma
for (size_t i = 0; i<msg_frm_3.ue_meas_report_lst_len; i++) for (size_t i = 0; i<msg_frm_3.ue_meas_report_lst_len; i++)
{ {
// Fill UE ID data // Fill UE ID data
rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], matched_ues.ue_list[i].rnti); rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], matched_ues.ue_list[i].rnti);
msg_frm_3.meas_report_per_ue[i].ue_meas_report_lst.type = GNB_UE_ID_E2SM; msg_frm_3.meas_report_per_ue[i].ue_meas_report_lst.type = GNB_UE_ID_E2SM;
msg_frm_3.meas_report_per_ue[i].ue_meas_report_lst.gnb = fill_gnb_data(rrc_ue_context_list); msg_frm_3.meas_report_per_ue[i].ue_meas_report_lst.gnb = fill_gnb_data(rrc_ue_context_list);
+3 -1
View File
@@ -401,7 +401,9 @@ typedef struct f1ap_cudu_inst_s {
f1ap_net_config_t net_config; f1ap_net_config_t net_config;
/* SCTP information */ /* SCTP information */
sctp_assoc_t assoc_id; struct {
sctp_assoc_t assoc_id;
} du;
uint16_t sctp_in_streams; uint16_t sctp_in_streams;
uint16_t sctp_out_streams; uint16_t sctp_out_streams;
+18 -57
View File
@@ -35,7 +35,8 @@
#include "f1ap_itti_messaging.h" #include "f1ap_itti_messaging.h"
#include "f1ap_cu_interface_management.h" #include "f1ap_cu_interface_management.h"
int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset)
{
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
@@ -49,11 +50,11 @@ int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream,
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) { int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge)
{
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
/* /*
Error Indication Error Indication
*/ */
@@ -62,7 +63,7 @@ int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication) { int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication) {
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
@@ -194,54 +195,13 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3
memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size); memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size);
sys_info->sib1_length = DUsi->sIB1_message.size; sys_info->sib1_length = DUsi->sIB1_message.size;
} }
// char *measurement_timing_information[F1AP_MAX_NB_CELLS]; itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p);
// uint8_t ranac[F1AP_MAX_NB_CELLS];
// int fdd_flag = f1ap_setup_req->fdd_flag;
// union {
// struct {
// uint32_t ul_nr_arfcn;
// uint8_t ul_scs;
// uint8_t ul_nrb;
// uint32_t dl_nr_arfcn;
// uint8_t dl_scs;
// uint8_t dl_nrb;
// uint32_t sul_active;
// uint32_t sul_nr_arfcn;
// uint8_t sul_scs;
// uint8_t sul_nrb;
// uint8_t num_frequency_bands;
// uint16_t nr_band[32];
// uint8_t num_sul_frequency_bands;
// uint16_t nr_sul_band[32];
// } fdd;
// struct {
// uint32_t nr_arfcn;
// uint8_t scs;
// uint8_t nrb;
// uint32_t sul_active;
// uint32_t sul_nr_arfcn;
// uint8_t sul_scs;
// uint8_t sul_nrb;
// uint8_t num_frequency_bands;
// uint16_t nr_band[32];
// uint8_t num_sul_frequency_bands;
// uint16_t nr_sul_band[32];
// } tdd;
// } nr_mode_info[F1AP_MAX_NB_CELLS];
if (req->num_cells_available > 0) {
itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p);
} else {
CU_send_F1_SETUP_FAILURE(instance);
itti_free(TASK_CU_F1,message_p);
return -1;
}
return 0; return 0;
} }
int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp) int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_setup_resp)
{ {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
uint8_t *buffer=NULL; uint8_t *buffer=NULL;
@@ -339,11 +299,12 @@ int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup
} }
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
int CU_send_F1_SETUP_FAILURE(instance_t instance) { int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail)
{
LOG_D(F1AP, "CU_send_F1_SETUP_FAILURE\n"); LOG_D(F1AP, "CU_send_F1_SETUP_FAILURE\n");
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
uint8_t *buffer=NULL; uint8_t *buffer=NULL;
@@ -406,7 +367,7 @@ int CU_send_F1_SETUP_FAILURE(instance_t instance) {
} }
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -419,12 +380,12 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure) { F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure) {
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge) { F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge) {
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
@@ -433,8 +394,8 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
gNB-CU Configuration Update gNB-CU Configuration Update
*/ */
//void CU_send_gNB_CU_CONFIGURATION_UPDATE(F1AP_GNBCUConfigurationUpdate_t *GNBCUConfigurationUpdate) { int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update)
int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update) { {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
uint8_t *buffer; uint8_t *buffer;
uint32_t len; uint32_t len;
@@ -520,7 +481,7 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configu
LOG_DUMPMSG(F1AP, LOG_DUMP_CHAR, buffer, len, "F1AP gNB-CU CONFIGURATION UPDATE : "); LOG_DUMPMSG(F1AP, LOG_DUMP_CHAR, buffer, len, "F1AP gNB-CU CONFIGURATION UPDATE : ");
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -546,7 +507,7 @@ int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
AssertFatal(0, "Not implemented yet\n"); AssertFatal(0, "Not implemented yet\n");
} }
int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(sctp_assoc_t assoc_id,
F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse) { F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse) {
AssertFatal(0, "Not implemented yet\n"); AssertFatal(0, "Not implemented yet\n");
} }
+9 -9
View File
@@ -36,41 +36,41 @@
/* /*
* Reset * Reset
*/ */
int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset);
int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge);
/* /*
* Error Indication * Error Indication
*/ */
int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication); int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication);
/* /*
* F1 Setup * F1 Setup
*/ */
int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp); int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_setup_resp);
int CU_send_F1_SETUP_FAILURE(instance_t instance); int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail);
/* /*
* gNB-DU Configuration Update * gNB-DU Configuration Update
*/ */
int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure); F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure);
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge); F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge);
/* /*
* gNB-CU Configuration Update * gNB-CU Configuration Update
*/ */
int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update); int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update);
int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
sctp_assoc_t assoc_id, sctp_assoc_t assoc_id,
uint32_t stream, uint32_t stream,
@@ -89,7 +89,7 @@ int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
uint32_t stream, uint32_t stream,
F1AP_F1AP_PDU_t *pdu); F1AP_F1AP_PDU_t *pdu);
int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(sctp_assoc_t assoc_id,
F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse); F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse);
#endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */ #endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */
+3 -2
View File
@@ -37,7 +37,8 @@
extern f1ap_setup_req_t *f1ap_du_data_from_du; extern f1ap_setup_req_t *f1ap_du_data_from_du;
int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) { int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging)
{
F1AP_F1AP_PDU_t pdu = {0}; F1AP_F1AP_PDU_t pdu = {0};
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
@@ -114,6 +115,6 @@ int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) {
return -1; return -1;
} }
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
+1 -1
View File
@@ -32,5 +32,5 @@
#ifndef F1AP_CU_PAGING_H_ #ifndef F1AP_CU_PAGING_H_
#define F1AP_CU_PAGING_H_ #define F1AP_CU_PAGING_H_
int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging); int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging);
#endif /* F1AP_DU_PAGING_H_ */ #endif /* F1AP_DU_PAGING_H_ */
+4 -4
View File
@@ -88,6 +88,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t
// create an ITTI message and copy SDU // create an ITTI message and copy SDU
message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
message_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p);
ul_rrc->gNB_DU_ue_id = du_ue_id; ul_rrc->gNB_DU_ue_id = du_ue_id;
ul_rrc->nr_cellid = nr_cellid; // CU instance ul_rrc->nr_cellid = nr_cellid; // CU instance
@@ -107,9 +108,8 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t
/* /*
DL RRC Message Transfer. DL RRC Message Transfer.
*/ */
//void CU_send_DL_RRC_MESSAGE_TRANSFER(F1AP_DLRRCMessageTransfer_t *DLRRCMessageTransfer) { int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *f1ap_dl_rrc)
int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, {
f1ap_dl_rrc_message_t *f1ap_dl_rrc) {
LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n"); LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n");
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_DLRRCMessageTransfer_t *out; F1AP_DLRRCMessageTransfer_t *out;
@@ -207,7 +207,7 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance,
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
+1 -1
View File
@@ -35,7 +35,7 @@
int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, f1ap_dl_rrc_message_t *f1ap_dl_rrc); int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *f1ap_dl_rrc);
int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
+33 -31
View File
@@ -53,20 +53,12 @@ static void cu_task_handle_sctp_association_ind(instance_t instance,
sctp_new_association_ind_t *sctp_new_association_ind, sctp_new_association_ind_t *sctp_new_association_ind,
eth_params_t *IPaddrs) eth_params_t *IPaddrs)
{ {
createF1inst(instance, NULL, NULL);
// save the assoc id // save the assoc id
f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance);
f1ap_cu_data->assoc_id = sctp_new_association_ind->assoc_id; // we don't need the assoc_id, subsequent messages (the first being F1 Setup
// Request), will deliver the assoc_id
f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams; f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams;
f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams; f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams;
if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) {
getCxt(instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs);
AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener");
} else
LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n");
// Fixme: fully inconsistent instances management
// dirty global var is a bad fix
CUuniqInstance=getCxt(instance)->gtpInst;
} }
static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
@@ -76,7 +68,6 @@ static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_a
f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance);
AssertFatal(f1ap_cu_data != NULL, "illegal state: SCTP shutdown for non-existing F1AP endpoint\n"); AssertFatal(f1ap_cu_data != NULL, "illegal state: SCTP shutdown for non-existing F1AP endpoint\n");
LOG_I(F1AP, "Received SCTP shutdown for assoc_id %d, removing endpoint\n", sctp_new_association_resp->assoc_id); LOG_I(F1AP, "Received SCTP shutdown for assoc_id %d, removing endpoint\n", sctp_new_association_resp->assoc_id);
destroyF1inst(instance);
/* inform RRC that the DU is gone */ /* inform RRC that the DU is gone */
MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_LOST_CONNECTION); MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_LOST_CONNECTION);
message_p->ittiMsgHeader.originInstance = sctp_new_association_resp->assoc_id; message_p->ittiMsgHeader.originInstance = sctp_new_association_resp->assoc_id;
@@ -139,12 +130,25 @@ void *F1AP_CU_task(void *arg) {
// Hardcoded instance id! // Hardcoded instance id!
IPaddrs = &RC.nrrrc[0]->eth_params_s; IPaddrs = &RC.nrrrc[0]->eth_params_s;
cu_task_send_sctp_init_req(0, IPaddrs->my_addr); const int instance = 0;
createF1inst(instance, NULL, NULL);
cu_task_send_sctp_init_req(instance, IPaddrs->my_addr);
if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) {
getCxt(instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs);
AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener");
} else {
LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n");
}
// Fixme: fully inconsistent instances management
// dirty global var is a bad fix
CUuniqInstance=getCxt(instance)->gtpInst;
while (1) { while (1) {
itti_receive_msg(TASK_CU_F1, &received_msg); itti_receive_msg(TASK_CU_F1, &received_msg);
LOG_D(F1AP, "CU Task Received %s for instance %ld\n", sctp_assoc_t assoc_id = ITTI_MSG_ORIGIN_INSTANCE(received_msg);
ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg)); LOG_D(F1AP, "CU Task Received %s for instance %ld: sending SCTP message via assoc_id %d\n",
ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg), assoc_id);
switch (ITTI_MSG_ID(received_msg)) { switch (ITTI_MSG_ID(received_msg)) {
case SCTP_NEW_ASSOCIATION_IND: case SCTP_NEW_ASSOCIATION_IND:
cu_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(received_msg), cu_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(received_msg),
@@ -163,59 +167,55 @@ void *F1AP_CU_task(void *arg) {
break; break;
case F1AP_SETUP_RESP: // from rrc case F1AP_SETUP_RESP: // from rrc
CU_send_F1_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_F1_SETUP_RESPONSE(assoc_id,
&F1AP_SETUP_RESP(received_msg)); &F1AP_SETUP_RESP(received_msg));
break; break;
case F1AP_SETUP_FAILURE:
CU_send_F1_SETUP_FAILURE(assoc_id, &F1AP_SETUP_FAILURE(received_msg));
break;
case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc
CU_send_gNB_CU_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_gNB_CU_CONFIGURATION_UPDATE(assoc_id,
&F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg)); &F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg));
break; break;
case F1AP_DL_RRC_MESSAGE: // from rrc case F1AP_DL_RRC_MESSAGE: // from rrc
CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_DL_RRC_MESSAGE_TRANSFER(assoc_id,
&F1AP_DL_RRC_MESSAGE(received_msg)); &F1AP_DL_RRC_MESSAGE(received_msg));
free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container); free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container);
break; break;
case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc
CU_send_UE_CONTEXT_SETUP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_UE_CONTEXT_SETUP_REQUEST(assoc_id,
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); &F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
break; break;
case F1AP_UE_CONTEXT_MODIFICATION_REQ: case F1AP_UE_CONTEXT_MODIFICATION_REQ:
CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_UE_CONTEXT_MODIFICATION_REQUEST(assoc_id,
&F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg));
break; break;
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_UE_CONTEXT_RELEASE_COMMAND(assoc_id,
&F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg));
break; break;
case F1AP_PAGING_IND: case F1AP_PAGING_IND:
CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_Paging(assoc_id,
&F1AP_PAGING_IND(received_msg)); &F1AP_PAGING_IND(received_msg));
break; break;
case F1AP_UE_CONTEXT_MODIFICATION_CONFIRM: case F1AP_UE_CONTEXT_MODIFICATION_CONFIRM:
CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(assoc_id,
&F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(received_msg)); &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(received_msg));
break; break;
case F1AP_UE_CONTEXT_MODIFICATION_REFUSE: case F1AP_UE_CONTEXT_MODIFICATION_REFUSE:
CU_send_UE_CONTEXT_MODIFICATION_REFUSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), CU_send_UE_CONTEXT_MODIFICATION_REFUSE(assoc_id,
&F1AP_UE_CONTEXT_MODIFICATION_REFUSE(received_msg)); &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(received_msg));
break; break;
// case F1AP_SETUP_RESPONSE: // This is from RRC
// CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp)
// break;
// case F1AP_SETUP_FAILURE: // This is from RRC
// CU_send_F1_SETUP_FAILURE(instance, *f1ap_setup_ind, &(F1AP_SETUP_FAILURE) f1ap_setup_failure)
// break;
case TERMINATE_MESSAGE: case TERMINATE_MESSAGE:
LOG_W(F1AP, " *** Exiting F1AP thread\n"); LOG_W(F1AP, " *** Exiting F1AP thread\n");
itti_exit_task(); itti_exit_task();
@@ -232,5 +232,7 @@ void *F1AP_CU_task(void *arg) {
received_msg = NULL; received_msg = NULL;
} // while } // while
destroyF1inst(instance);
return NULL; return NULL;
} }
+19 -15
View File
@@ -65,8 +65,8 @@ static void setQos(F1AP_NonDynamic5QIDescriptor_t *toFill) {
} }
} }
int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req)
f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) { {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
/* Create */ /* Create */
/* 0. Message Type */ /* 0. Message Type */
@@ -506,7 +506,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
/*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/
/* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */
transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } }; transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } };
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(instance)->gtpInst, f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst,
f1ap_ue_context_setup_req->gNB_CU_ue_id, f1ap_ue_context_setup_req->gNB_CU_ue_id,
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
@@ -625,7 +625,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
// return -1; // return -1;
// } // }
LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len); LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len);
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -636,6 +636,7 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_
F1AP_UEContextSetupResponseIEs_t *ie; F1AP_UEContextSetupResponseIEs_t *ie;
DevAssert(pdu); DevAssert(pdu);
msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_SETUP_RESP); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_SETUP_RESP);
msg_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_setup_t *f1ap_ue_context_setup_resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); f1ap_ue_context_setup_t *f1ap_ue_context_setup_resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
container = &pdu->choice.successfulOutcome->value.choice.UEContextSetupResponse; container = &pdu->choice.successfulOutcome->value.choice.UEContextSetupResponse;
int i; int i;
@@ -769,6 +770,7 @@ int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_i
int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_UE_CONTEXT_RELEASE_REQ); MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg);
F1AP_UEContextReleaseRequest_t *container; F1AP_UEContextReleaseRequest_t *container;
F1AP_UEContextReleaseRequestIEs_t *ie; F1AP_UEContextReleaseRequestIEs_t *ie;
@@ -822,9 +824,8 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc
return 0; return 0;
} }
int CU_send_UE_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, f1ap_ue_context_release_cmd_t *cmd)
int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, {
f1ap_ue_context_release_cmd_t *cmd) {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextReleaseCommand_t *out; F1AP_UEContextReleaseCommand_t *out;
uint8_t *buffer=NULL; uint8_t *buffer=NULL;
@@ -909,7 +910,7 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -919,6 +920,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso
F1AP_UEContextReleaseCompleteIEs_t *ie; F1AP_UEContextReleaseCompleteIEs_t *ie;
DevAssert(pdu); DevAssert(pdu);
MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE);
msg_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p);
container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete; container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete;
/* GNB_CU_UE_F1AP_ID */ /* GNB_CU_UE_F1AP_ID */
@@ -948,7 +950,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso
return 0; return 0;
} }
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req) int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req)
{ {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextModificationRequest_t *out; F1AP_UEContextModificationRequest_t *out;
@@ -1548,7 +1550,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
&drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item;
/* dRBID */ /* dRBID */
drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id; drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id;
newGtpuDeleteOneTunnel(getCxt(instance)->gtpInst, newGtpuDeleteOneTunnel(getCxt(0)->gtpInst,
f1ap_ue_context_modification_req->gNB_CU_ue_id, f1ap_ue_context_modification_req->gNB_CU_ue_id,
f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id);
} }
@@ -1559,7 +1561,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context
LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n"); LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n");
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -1570,6 +1572,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t
F1AP_UEContextModificationResponseIEs_t *ie; F1AP_UEContextModificationResponseIEs_t *ie;
DevAssert(pdu); DevAssert(pdu);
msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
msg_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse; container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse;
int i; int i;
@@ -1698,6 +1701,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t
DevAssert(pdu != NULL); DevAssert(pdu != NULL);
MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED);
msg_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p); f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p);
F1AP_UEContextModificationRequired_t *container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequired; F1AP_UEContextModificationRequired_t *container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequired;
@@ -1826,7 +1830,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t
return 0; return 0;
} }
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm) int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(sctp_assoc_t assoc_id, f1ap_ue_context_modif_confirm_t *confirm)
{ {
F1AP_F1AP_PDU_t pdu = {0}; F1AP_F1AP_PDU_t pdu = {0};
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
@@ -1884,11 +1888,11 @@ int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context
LOG_E(F1AP, "Failed to encode F1 UE Context Modification Confirm\n"); LOG_E(F1AP, "Failed to encode F1 UE Context Modification Confirm\n");
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse) int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_refuse_t *refuse)
{ {
F1AP_F1AP_PDU_t pdu = {0}; F1AP_F1AP_PDU_t pdu = {0};
pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome; pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
@@ -1951,6 +1955,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_
LOG_E(F1AP, "Failed to encode F1 UE Context Modification Refuse\n"); LOG_E(F1AP, "Failed to encode F1 UE Context Modification Refuse\n");
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -36,7 +36,7 @@
/* /*
* UE Context Setup * UE Context Setup
*/ */
int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id,
f1ap_ue_context_setup_t *f1ap_ue_context_setup_req); f1ap_ue_context_setup_t *f1ap_ue_context_setup_req);
int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
@@ -51,7 +51,7 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc
/* /*
* UE Context Release (gNB-CU initiated) * UE Context Release (gNB-CU initiated)
*/ */
int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, int CU_send_UE_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id,
f1ap_ue_context_release_cmd_t *cmd); f1ap_ue_context_release_cmd_t *cmd);
int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
@@ -59,7 +59,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso
/* /*
* UE Context Modification (gNB-CU initiated) * UE Context Modification (gNB-CU initiated)
*/ */
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req); int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req);
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
@@ -68,9 +68,9 @@ int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t
*/ */
int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm); int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(sctp_assoc_t assoc_id, f1ap_ue_context_modif_confirm_t *confirm);
int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse); int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_refuse_t *refuse);
/* /*
* UE Inactivity Notification * UE Inactivity Notification
+22 -18
View File
@@ -55,11 +55,12 @@ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream,
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) { int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge) {
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset)
{
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
@@ -72,7 +73,8 @@ int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint
Error Indication Error Indication
*/ */
int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p) { int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p)
{
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
@@ -86,7 +88,7 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3
*/ */
// SETUP REQUEST // SETUP REQUEST
int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req) int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req)
{ {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
uint8_t *buffer; uint8_t *buffer;
@@ -298,7 +300,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req)
} }
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -317,7 +319,6 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint
F1AP_F1SetupResponseIEs_t *ie; F1AP_F1SetupResponseIEs_t *ie;
int TransactionId = -1; int TransactionId = -1;
int num_cells_to_activate = 0; int num_cells_to_activate = 0;
F1AP_Cells_to_be_Activated_List_Item_t *cell;
f1ap_setup_resp_t resp = {0}; f1ap_setup_resp_t resp = {0};
for (int i=0; i < in->protocolIEs.list.count; i++) { for (int i=0; i < in->protocolIEs.list.count; i++) {
@@ -365,7 +366,8 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint
"cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject"); "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject");
AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item, AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item,
"cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item"); "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item");
cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item; F1AP_Cells_to_be_Activated_List_Item_t *cell =
&cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item;
TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity,
resp.cells_to_activate[i].plmn.mcc, resp.cells_to_activate[i].plmn.mcc,
resp.cells_to_activate[i].plmn.mnc, resp.cells_to_activate[i].plmn.mnc,
@@ -377,6 +379,8 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint
cell->nRCGI.nRCellIdentity.buf[3], cell->nRCGI.nRCellIdentity.buf[3],
cell->nRCGI.nRCellIdentity.buf[4]); cell->nRCGI.nRCellIdentity.buf[4]);
BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, resp.cells_to_activate[i].nr_cellid); BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, resp.cells_to_activate[i].nr_cellid);
if (cell->nRPCI != NULL)
resp.cells_to_activate[i].nrpci = *cell->nRPCI;
F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions; F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions;
if (ext==NULL) if (ext==NULL)
@@ -492,10 +496,8 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
gNB-DU Configuration Update gNB-DU Configuration Update
*/ */
//void DU_send_gNB_DU_CONFIGURATION_UPDATE(F1AP_GNBDUConfigurationUpdate_t *GNBDUConfigurationUpdate) { int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t *f1ap_setup_req)
int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, {
instance_t du_mod_idP,
f1ap_setup_req_t *f1ap_setup_req) {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
uint8_t *buffer=NULL; uint8_t *buffer=NULL;
uint32_t len=0; uint32_t len=0;
@@ -891,14 +893,16 @@ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso
return 0; return 0;
} }
int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id,
f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure) { f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure) {
AssertFatal(1==0,"received gNB CU CONFIGURATION UPDATE FAILURE with cause %d\n", AssertFatal(1==0,"received gNB CU CONFIGURATION UPDATE FAILURE with cause %d\n",
GNBCUConfigurationUpdateFailure->cause); GNBCUConfigurationUpdateFailure->cause);
} }
int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(
f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge) { sctp_assoc_t assoc_id,
f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge)
{
AssertFatal(GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated == 0, AssertFatal(GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated == 0,
"%d cells failed to activate\n", "%d cells failed to activate\n",
GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated); GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated);
@@ -937,13 +941,13 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
} }
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id,
int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest)
F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) { {
AssertFatal(0, "Not implemented yet\n"); AssertFatal(0, "Not implemented yet\n");
} }
+8 -9
View File
@@ -37,20 +37,20 @@
* Reset * Reset
*/ */
int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge);
int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset);
int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
/* /*
* Error Indication * Error Indication
*/ */
int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p); int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p);
int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
/* /*
* F1 Setup * F1 Setup
*/ */
int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req); int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req);
int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
@@ -59,8 +59,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
/* /*
* gNB-DU Configuration Update * gNB-DU Configuration Update
*/ */
int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id,
instance_t du_mod_idP,
f1ap_setup_req_t *f1ap_du_data); f1ap_setup_req_t *f1ap_du_data);
int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
@@ -75,10 +74,10 @@ int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
*/ */
int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id,
f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure); f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure);
int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge); f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge);
@@ -86,7 +85,7 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
/* /*
* gNB-DU Resource Coordination * gNB-DU Resource Coordination
*/ */
int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id,
F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest); F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest);
int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
+1 -3
View File
@@ -87,9 +87,7 @@ int DU_handle_Paging(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
F1AP_ProtocolIE_ID_id_PagingCell_List, true); F1AP_ProtocolIE_ID_id_PagingCell_List, true);
for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { AssertFatal(false, "not implemented\n");
rrc_gNB_generate_pcch_msg((uint32_t)tmsi, pagingdrx, instance, CC_id);
}
return 0; return 0;
} }
+6 -8
View File
@@ -141,7 +141,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id
} }
/* UL RRC Message Transfer */ /* UL RRC Message Transfer */
int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg) int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg)
{ {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_InitialULRRCMessageTransfer_t *out; F1AP_InitialULRRCMessageTransfer_t *out;
@@ -170,7 +170,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini
ie2->criticality = F1AP_Criticality_reject; ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI; ie2->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI;
//Fixme: takes always the first cell //Fixme: takes always the first cell
addnRCGI(ie2->value.choice.NRCGI, &getCxt(instanceP)->setupReq.cell[0].info); addnRCGI(ie2->value.choice.NRCGI, &getCxt(0)->setupReq.cell[0].info);
/* mandatory */ /* mandatory */
/* c3. C_RNTI */ // 16 /* c3. C_RNTI */ // 16
asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3); asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3);
@@ -211,20 +211,18 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instanceP, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg)
{ {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_ULRRCMessageTransfer_t *out; F1AP_ULRRCMessageTransfer_t *out;
uint8_t *buffer = NULL; uint8_t *buffer = NULL;
uint32_t len; uint32_t len;
LOG_D(F1AP, LOG_D(F1AP,
"[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", "size %d UE RNTI %x in SRB %d\n",
instance,
__func__,
msg->rrc_container_length, msg->rrc_container_length,
msg->gNB_DU_ue_id, msg->gNB_DU_ue_id,
msg->srb_id); msg->srb_id);
@@ -277,6 +275,6 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_me
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
+2 -2
View File
@@ -38,8 +38,8 @@
int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg); int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg);
int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg); int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg);
#endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */
+14 -16
View File
@@ -76,11 +76,11 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat
} }
// save the assoc id // save the assoc id
f1ap_du_data->assoc_id = sctp_new_association_resp->assoc_id; f1ap_du_data->du.assoc_id = sctp_new_association_resp->assoc_id;
f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams; f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams;
f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams; f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams;
/* setup parameters for F1U and start the server */ /* setup parameters for F1U and start the server */
DU_send_F1_SETUP_REQUEST(instance, &f1ap_du_data->setupReq); DU_send_F1_SETUP_REQUEST(f1ap_du_data->du.assoc_id, &f1ap_du_data->setupReq);
} }
void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
@@ -102,8 +102,8 @@ void *F1AP_DU_task(void *arg) {
MessageDef *msg = NULL; MessageDef *msg = NULL;
itti_receive_msg(TASK_DU_F1, &msg); itti_receive_msg(TASK_DU_F1, &msg);
instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg);
LOG_D(F1AP, "DU Task Received %s for instance %ld\n", sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->du.assoc_id : 0;
ITTI_MSG_NAME(msg),myInstance); LOG_D(F1AP, "DU Task Received %s for instance %ld: sending SCTP messages via assoc_id %d\n", ITTI_MSG_NAME(msg), myInstance, assoc_id);
switch (ITTI_MSG_ID(msg)) { switch (ITTI_MSG_ID(msg)) {
case F1AP_SETUP_REQ: case F1AP_SETUP_REQ:
AssertFatal(false, "the F1AP_SETUP_REQ should not be received; use the F1AP_DU_REGISTER_REQ instead\n"); AssertFatal(false, "the F1AP_SETUP_REQ should not be received; use the F1AP_DU_REGISTER_REQ instead\n");
@@ -121,12 +121,12 @@ void *F1AP_DU_task(void *arg) {
} break; } break;
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_ORIGIN_INSTANCE(msg), DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id,
&F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg)); &F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg));
break; break;
case F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE: case F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE:
DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(myInstance, DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(assoc_id,
&F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(msg)); &F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(msg));
break; break;
@@ -144,34 +144,32 @@ void *F1AP_DU_task(void *arg) {
break; break;
case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc
{ DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_INITIAL_UL_RRC_MESSAGE(msg));
f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); break;
DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(myInstance, msgRrc);
} break;
case F1AP_UL_RRC_MESSAGE: // to rrc case F1AP_UL_RRC_MESSAGE: // to rrc
DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, &F1AP_UL_RRC_MESSAGE(msg)); DU_send_UL_NR_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_UL_RRC_MESSAGE(msg));
break; break;
case F1AP_UE_CONTEXT_SETUP_RESP: case F1AP_UE_CONTEXT_SETUP_RESP:
DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg)); DU_send_UE_CONTEXT_SETUP_RESPONSE(assoc_id, &F1AP_UE_CONTEXT_SETUP_RESP(msg));
break; break;
case F1AP_UE_CONTEXT_MODIFICATION_RESP: case F1AP_UE_CONTEXT_MODIFICATION_RESP:
DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg));
break; break;
case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC
DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance, DU_send_UE_CONTEXT_RELEASE_REQUEST(assoc_id,
&F1AP_UE_CONTEXT_RELEASE_REQ(msg)); &F1AP_UE_CONTEXT_RELEASE_REQ(msg));
break; break;
case F1AP_UE_CONTEXT_RELEASE_COMPLETE: case F1AP_UE_CONTEXT_RELEASE_COMPLETE:
DU_send_UE_CONTEXT_RELEASE_COMPLETE(myInstance, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); DU_send_UE_CONTEXT_RELEASE_COMPLETE(assoc_id, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg));
break; break;
case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED: case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED:
DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg)); DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg));
break; break;
case TERMINATE_MESSAGE: case TERMINATE_MESSAGE:
+21 -19
View File
@@ -205,7 +205,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i
return 0; return 0;
} }
int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *resp)
{
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextSetupResponse_t *out; F1AP_UEContextSetupResponse_t *out;
uint8_t *buffer=NULL; uint8_t *buffer=NULL;
@@ -329,7 +330,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
/* transportLayerAddress */ /* transportLayerAddress */
struct sockaddr_in addr= {0}; struct sockaddr_in addr= {0};
inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr);
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr,
&gTPTunnel->transportLayerAddress); &gTPTunnel->transportLayerAddress);
/* gTP_TEID */ /* gTP_TEID */
@@ -542,15 +543,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance) { int DU_send_UE_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id)
{
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
f1ap_ue_context_release_req_t *req) { int DU_send_UE_CONTEXT_RELEASE_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_release_req_t *req)
{
F1AP_F1AP_PDU_t pdu; F1AP_F1AP_PDU_t pdu;
F1AP_UEContextReleaseRequest_t *out; F1AP_UEContextReleaseRequest_t *out;
uint8_t *buffer=NULL; uint8_t *buffer=NULL;
@@ -617,7 +620,7 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -681,7 +684,7 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, sctp_assoc_t assoc
return 0; return 0;
} }
int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete) int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_release_complete_t *complete)
{ {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextReleaseComplete_t *out; F1AP_UEContextReleaseComplete_t *out;
@@ -764,7 +767,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -986,8 +989,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
return 0; return 0;
} }
//void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_resp_t *resp)
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp)
{ {
F1AP_F1AP_PDU_t pdu= {0}; F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextModificationResponse_t *out; F1AP_UEContextModificationResponse_t *out;
@@ -1079,7 +1081,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
transport_layer_addr_t tl_addr = {0}; transport_layer_addr_t tl_addr = {0};
memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address));
tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8;
drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(instance)->gtpInst, drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst,
resp->gNB_DU_ue_id, resp->gNB_DU_ue_id,
drb->drb_id, drb->drb_id,
drb->drb_id, drb->drb_id,
@@ -1098,7 +1100,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
/* transportLayerAddress */ /* transportLayerAddress */
struct sockaddr_in addr= {0}; struct sockaddr_in addr= {0};
inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr);
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr,
&gTPTunnel->transportLayerAddress); &gTPTunnel->transportLayerAddress);
/* gTP_TEID */ /* gTP_TEID */
@@ -1136,7 +1138,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel);
/* transportLayerAddress */ /* transportLayerAddress */
struct sockaddr_in addr= {0}; struct sockaddr_in addr= {0};
inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr);
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress);
/* gTP_TEID */ /* gTP_TEID */
INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID);
@@ -1211,7 +1213,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
/* 8.1 SCell_ToBeSetup_Item */ /* 8.1 SCell_ToBeSetup_Item */
F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item; F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item;
/* - sCell_ID */ /* - sCell_ID */
addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &getCxt(instance)->setupReq.cell[i].info); addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &getCxt(0)->setupReq.cell[i].info);
asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp); asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp);
tmp->present = F1AP_Cause_PR_radioNetwork; tmp->present = F1AP_Cause_PR_radioNetwork;
tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
@@ -1320,15 +1322,15 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(sctp_assoc_t assoc_id) {
AssertFatal(1==0,"Not implemented yet\n"); AssertFatal(1==0,"Not implemented yet\n");
} }
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required) int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(sctp_assoc_t assoc_id, f1ap_ue_context_modif_required_t *required)
{ {
/* 0. Message Type */ /* 0. Message Type */
F1AP_F1AP_PDU_t pdu = {0}; F1AP_F1AP_PDU_t pdu = {0};
@@ -1444,7 +1446,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_contex
return -1; return -1;
} }
f1ap_itti_send_sctp_data_req(instance, buffer, len); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0; return 0;
} }
@@ -36,16 +36,16 @@
/* /*
* UE Context Setup * UE Context Setup
*/ */
int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req); int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *req);
int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance); int DU_send_UE_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id);
/* /*
* UE Context Release Request (gNB-DU initiated) * UE Context Release Request (gNB-DU initiated)
*/ */
int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, int DU_send_UE_CONTEXT_RELEASE_REQUEST(sctp_assoc_t assoc_id,
f1ap_ue_context_release_req_t *req); f1ap_ue_context_release_req_t *req);
@@ -57,20 +57,20 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, sctp_assoc_t assoc
/* /*
* UE Context Release Complete (gNB-DU initiated) * UE Context Release Complete (gNB-DU initiated)
*/ */
int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete); int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_release_complete_t *complete);
/* /*
* UE Context Modification (gNB-CU initiated) * UE Context Modification (gNB-CU initiated)
*/ */
int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp); int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_resp_t *resp);
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(sctp_assoc_t assoc_id);
/* /*
* UE Context Modification Required (gNB-DU initiated) * UE Context Modification Required (gNB-DU initiated)
*/ */
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required); int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(sctp_assoc_t assoc_id, f1ap_ue_context_modif_required_t *required);
int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
+1
View File
@@ -34,6 +34,7 @@
typedef struct f1_ue_data_t { typedef struct f1_ue_data_t {
uint32_t secondary_ue; uint32_t secondary_ue;
sctp_assoc_t e1_assoc_id; sctp_assoc_t e1_assoc_id;
sctp_assoc_t du_assoc_id; // only used at the CU
} f1_ue_data_t; } f1_ue_data_t;
void cu_init_f1_ue_data(void); void cu_init_f1_ue_data(void);
+6 -19
View File
@@ -22,27 +22,14 @@
#include "f1ap_common.h" #include "f1ap_common.h"
#include "f1ap_itti_messaging.h" #include "f1ap_itti_messaging.h"
void f1ap_itti_send_sctp_data_req(instance_t instance, uint8_t *buffer, uint32_t buffer_length) void f1ap_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length)
{ {
MessageDef *message_p; instance_t instance = 0; // we have only one instance
sctp_data_req_t *sctp_data_req; MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, instance, SCTP_DATA_REQ);
message_p = itti_alloc_new_message(TASK_CU_F1, 0, SCTP_DATA_REQ); sctp_data_req_t *sctp_data_req = &message_p->ittiMsg.sctp_data_req;
sctp_data_req = &message_p->ittiMsg.sctp_data_req; sctp_data_req->assoc_id = assoc_id;
sctp_data_req->assoc_id = getCxt(instance)->assoc_id; sctp_data_req->buffer = buffer;
sctp_data_req->buffer = buffer;
sctp_data_req->buffer_length = buffer_length; sctp_data_req->buffer_length = buffer_length;
sctp_data_req->stream = 0; sctp_data_req->stream = 0;
LOG_D(F1AP, "Sending ITTI message to SCTP Task\n");
itti_send_msg_to_task(TASK_SCTP, instance, message_p); itti_send_msg_to_task(TASK_SCTP, instance, message_p);
} }
void f1ap_itti_send_sctp_close_association(instance_t instance)
{
MessageDef *message_p = NULL;
sctp_close_association_t *sctp_close_association_p = NULL;
message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION);
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
sctp_close_association_p->assoc_id = getCxt(instance)->assoc_id;
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
+1 -1
View File
@@ -22,6 +22,6 @@
#ifndef F1AP_ITTI_MESSAGING_H_ #ifndef F1AP_ITTI_MESSAGING_H_
#define F1AP_ITTI_MESSAGING_H_ #define F1AP_ITTI_MESSAGING_H_
void f1ap_itti_send_sctp_data_req(instance_t instance, uint8_t *buffer, uint32_t buffer_length); void f1ap_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length);
#endif /* F1AP_ITTI_MESSAGING_H_ */ #endif /* F1AP_ITTI_MESSAGING_H_ */
@@ -27,6 +27,7 @@
static void f1_setup_request_direct(const f1ap_setup_req_t *req) static void f1_setup_request_direct(const f1ap_setup_req_t *req)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
f1ap_setup_req_t *f1ap_msg = &F1AP_SETUP_REQ(msg); f1ap_setup_req_t *f1ap_msg = &F1AP_SETUP_REQ(msg);
f1ap_msg->gNB_DU_id = req->gNB_DU_id; f1ap_msg->gNB_DU_id = req->gNB_DU_id;
f1ap_msg->gNB_DU_name = strdup(req->gNB_DU_name); f1ap_msg->gNB_DU_name = strdup(req->gNB_DU_name);
@@ -71,6 +72,7 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req,
(void) req; /* we don't need the request -- it is to set up GTP in F1 case */ (void) req; /* we don't need the request -- it is to set up GTP in F1 case */
MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg); f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg);
/* copy all fields, but reallocate memory buffers! */ /* copy all fields, but reallocate memory buffers! */
*f1ap_msg = *resp; *f1ap_msg = *resp;
@@ -100,6 +102,7 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_
{ {
(void)req; /* we don't need the request -- it is to set up GTP in F1 case */ (void)req; /* we don't need the request -- it is to set up GTP in F1 case */
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg); f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg);
f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id; f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id;
@@ -152,6 +155,7 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_
static void ue_context_modification_required_direct(const f1ap_ue_context_modif_required_t *required) static void ue_context_modification_required_direct(const f1ap_ue_context_modif_required_t *required)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg); f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg);
f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id; f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id;
f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id; f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id;
@@ -177,6 +181,7 @@ static void ue_context_modification_required_direct(const f1ap_ue_context_modif_
static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg);
*f1ap_msg = *req; *f1ap_msg = *req;
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
@@ -185,6 +190,7 @@ static void ue_context_release_request_direct(const f1ap_ue_context_release_req_
static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg);
*f1ap_msg = *complete; *f1ap_msg = *complete;
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
@@ -193,6 +199,7 @@ static void ue_context_release_complete_direct(const f1ap_ue_context_release_com
static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
/* copy all fields, but reallocate rrc_containers! */ /* copy all fields, but reallocate rrc_containers! */
f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg);
*f1ap_msg = *ul_rrc; *f1ap_msg = *ul_rrc;
+8 -8
View File
@@ -25,16 +25,16 @@
#include "platform_types.h" #include "platform_types.h"
#include "f1ap_messages_types.h" #include "f1ap_messages_types.h"
typedef void (*f1_setup_response_func_t)(const f1ap_setup_resp_t *resp); typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp);
typedef void (*f1_setup_failure_func_t)(const f1ap_setup_failure_t *fail); typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail);
typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); typedef void (*ue_context_setup_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req);
typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); typedef void (*ue_context_modification_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req);
typedef void (*ue_context_modification_confirm_func_t)(const f1ap_ue_context_modif_confirm_t *confirm); typedef void (*ue_context_modification_confirm_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm);
typedef void (*ue_context_modification_refuse_func_t)(const f1ap_ue_context_modif_refuse_t *refuse); typedef void (*ue_context_modification_refuse_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse);
typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); typedef void (*ue_context_release_command_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd);
typedef void (*dl_rrc_message_transfer_func_t)(const f1ap_dl_rrc_message_t *dl_rrc); typedef void (*dl_rrc_message_transfer_func_t)(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc);
struct nr_mac_rrc_dl_if_s; struct nr_mac_rrc_dl_if_s;
void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc); void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc);
+56 -8
View File
@@ -24,14 +24,62 @@
#include "mac_rrc_dl.h" #include "mac_rrc_dl.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
static void f1_setup_response_direct(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
f1_setup_response(resp);
}
static void f1_setup_failure_direct(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
f1_setup_failure(fail);
}
static void ue_context_setup_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
ue_context_setup_request(req);
}
static void ue_context_modification_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
ue_context_modification_request(req);
}
static void ue_context_modification_confirm_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
ue_context_modification_confirm(confirm);
}
static void ue_context_modification_refuse_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
ue_context_modification_refuse(refuse);
}
static void ue_context_release_command_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
ue_context_release_command(cmd);
}
static void dl_rrc_message_transfer_direct(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
dl_rrc_message_transfer(dl_rrc);
}
void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
{ {
mac_rrc->f1_setup_response = f1_setup_response; mac_rrc->f1_setup_response = f1_setup_response_direct;
mac_rrc->f1_setup_failure = f1_setup_failure; mac_rrc->f1_setup_failure = f1_setup_failure_direct;
mac_rrc->ue_context_setup_request = ue_context_setup_request; mac_rrc->ue_context_setup_request = ue_context_setup_request_direct;
mac_rrc->ue_context_modification_request = ue_context_modification_request; mac_rrc->ue_context_modification_request = ue_context_modification_request_direct;
mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm; mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_direct;
mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse; mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse_direct;
mac_rrc->ue_context_release_command = ue_context_release_command; mac_rrc->ue_context_release_command = ue_context_release_command_direct;
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct;
} }
+16 -8
View File
@@ -24,9 +24,10 @@
#include "mac_rrc_dl.h" #include "mac_rrc_dl.h"
#include "nr_rrc_defs.h" #include "nr_rrc_defs.h"
static void f1_setup_response_f1ap(const f1ap_setup_resp_t *resp) static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP); MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_setup_resp_t *f1ap_msg = &F1AP_SETUP_RESP(msg); f1ap_setup_resp_t *f1ap_msg = &F1AP_SETUP_RESP(msg);
*f1ap_msg = *resp; *f1ap_msg = *resp;
if (resp->gNB_CU_name != NULL) if (resp->gNB_CU_name != NULL)
@@ -34,17 +35,19 @@ static void f1_setup_response_f1ap(const f1ap_setup_resp_t *resp)
itti_send_msg_to_task(TASK_CU_F1, 0, msg); itti_send_msg_to_task(TASK_CU_F1, 0, msg);
} }
static void f1_setup_failure_f1ap(const f1ap_setup_failure_t *fail) static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_FAILURE); MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_FAILURE);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_setup_failure_t *f1ap_msg = &F1AP_SETUP_FAILURE(msg); f1ap_setup_failure_t *f1ap_msg = &F1AP_SETUP_FAILURE(msg);
*f1ap_msg = *fail; *f1ap_msg = *fail;
itti_send_msg_to_task(TASK_CU_F1, 0, msg); itti_send_msg_to_task(TASK_CU_F1, 0, msg);
} }
static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg);
*f1ap_msg = *req; *f1ap_msg = *req;
AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n");
@@ -59,9 +62,10 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req)
itti_send_msg_to_task(TASK_CU_F1, 0, msg); itti_send_msg_to_task(TASK_CU_F1, 0, msg);
} }
static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req_t *req) static void ue_context_modification_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg); f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg);
*f1ap_msg = *req; *f1ap_msg = *req;
if (req->cu_to_du_rrc_information != NULL) { if (req->cu_to_du_rrc_information != NULL) {
@@ -110,9 +114,10 @@ static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req
itti_send_msg_to_task(TASK_CU_F1, 0, msg); itti_send_msg_to_task(TASK_CU_F1, 0, msg);
} }
static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_confirm_t *confirm) static void ue_context_modification_confirm_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_CONFIRM); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_CONFIRM);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_modif_confirm_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(msg); f1ap_ue_context_modif_confirm_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(msg);
f1ap_msg->gNB_CU_ue_id = confirm->gNB_CU_ue_id; f1ap_msg->gNB_CU_ue_id = confirm->gNB_CU_ue_id;
f1ap_msg->gNB_DU_ue_id = confirm->gNB_DU_ue_id; f1ap_msg->gNB_DU_ue_id = confirm->gNB_DU_ue_id;
@@ -127,17 +132,19 @@ static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_con
itti_send_msg_to_task(TASK_CU_F1, 0, msg); itti_send_msg_to_task(TASK_CU_F1, 0, msg);
} }
static void ue_context_modification_refuse_f1ap(const f1ap_ue_context_modif_refuse_t *refuse) static void ue_context_modification_refuse_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REFUSE); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REFUSE);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_modif_refuse_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(msg); f1ap_ue_context_modif_refuse_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(msg);
*f1ap_msg = *refuse; *f1ap_msg = *refuse;
itti_send_msg_to_task(TASK_CU_F1, 0, msg); itti_send_msg_to_task(TASK_CU_F1, 0, msg);
} }
static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) static void ue_context_release_command_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd)
{ {
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
message_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p); f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p);
*msg = *cmd; *msg = *cmd;
if (cmd->rrc_container_length > 0) { if (cmd->rrc_container_length > 0) {
@@ -149,11 +156,12 @@ static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t
itti_send_msg_to_task (TASK_CU_F1, 0, message_p); itti_send_msg_to_task (TASK_CU_F1, 0, message_p);
} }
static void dl_rrc_message_transfer_f1ap(const f1ap_dl_rrc_message_t *dl_rrc) static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc)
{ {
/* TODO call F1AP function directly? no real-time constraint here */ /* TODO call F1AP function directly? no real-time constraint here */
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
message_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p); f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p);
*msg = *dl_rrc; *msg = *dl_rrc;
if (dl_rrc->old_gNB_DU_ue_id) { if (dl_rrc->old_gNB_DU_ue_id) {
+6 -1
View File
@@ -366,6 +366,9 @@ typedef struct cucp_cuup_if_s {
} cucp_cuup_if_t; } cucp_cuup_if_t;
typedef struct nr_rrc_du_container_t { typedef struct nr_rrc_du_container_t {
/* Tree-related data */
RB_ENTRY(nr_rrc_du_container_t) entries;
sctp_assoc_t assoc_id; sctp_assoc_t assoc_id;
f1ap_setup_req_t *setup_req; f1ap_setup_req_t *setup_req;
NR_MIB_t *mib; NR_MIB_t *mib;
@@ -408,7 +411,9 @@ typedef struct gNB_RRC_INST_s {
nr_mac_rrc_dl_if_t mac_rrc; nr_mac_rrc_dl_if_t mac_rrc;
cucp_cuup_if_t cucp_cuup; cucp_cuup_if_t cucp_cuup;
nr_rrc_du_container_t *du; RB_HEAD(rrc_du_tree, nr_rrc_du_container_t) dus; // DUs, indexed by assoc_id
size_t num_dus;
RB_HEAD(rrc_cuup_tree, nr_rrc_cuup_container_t) cuups; // CU-UPs, indexed by assoc_id RB_HEAD(rrc_cuup_tree, nr_rrc_cuup_container_t) cuups; // CU-UPs, indexed by assoc_id
size_t num_cuups; size_t num_cuups;
+1 -1
View File
@@ -152,7 +152,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint); uint8_t *const kUPint);
int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx);
void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size); void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size);
/** @}*/ /** @}*/
+250 -558
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1355,6 +1355,7 @@ int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance)
&& RC.nrrrc[instance]->configuration.mnc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc && RC.nrrrc[instance]->configuration.mnc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
&& RC.nrrrc[instance]->configuration.tac == NGAP_PAGING_IND(msg_p).tac[tai_size]) { && RC.nrrrc[instance]->configuration.tac == NGAP_PAGING_IND(msg_p).tac[tai_size]) {
for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
AssertFatal(false, "to be implemented properly\n");
if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) { if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) {
MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND); MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND);
F1AP_PAGING_IND(m).plmn.mcc = RC.nrrrc[j]->configuration.mcc[0]; F1AP_PAGING_IND(m).plmn.mcc = RC.nrrrc[j]->configuration.mcc[0];
@@ -1367,7 +1368,7 @@ int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance)
LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx); LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx);
itti_send_msg_to_task(TASK_CU_F1, instance, m); itti_send_msg_to_task(TASK_CU_F1, instance, m);
} else { } else {
rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id); //rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id);
} // end of nodetype check } // end of nodetype check
} // end of cc loop } // end of cc loop
} // end of mcc mnc check } // end of mcc mnc check
+16 -3
View File
@@ -87,7 +87,19 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_i
return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
} }
rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP)
{
rrc_gNB_ue_context_t *ue_context_p;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_context_p->ue_context.rrc_ue_id);
if (ue_data.du_assoc_id == assoc_id && ue_context_p->ue_context.rnti == rntiP)
return ue_context_p;
}
LOG_W(NR_RRC, "search by RNTI %04x and assoc_id %d: no UE found\n", rntiP, assoc_id);
return NULL;
}
rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP)
{ {
rrc_gNB_ue_context_t *ue_context_p; rrc_gNB_ue_context_t *ue_context_p;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head))
@@ -157,7 +169,8 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// return a new ue context structure if ue_identityP, rnti not found in collection // return a new ue context structure if ue_identityP, rnti not found in collection
rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id,
rnti_t rnti,
gNB_RRC_INST *rrc_instance_pP, gNB_RRC_INST *rrc_instance_pP,
const uint64_t ue_identityP, const uint64_t ue_identityP,
uint32_t du_ue_id) uint32_t du_ue_id)
@@ -170,7 +183,7 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti,
gNB_RRC_UE_t *ue = &ue_context_p->ue_context; gNB_RRC_UE_t *ue = &ue_context_p->ue_context;
ue->rnti = rnti; ue->rnti = rnti;
ue->random_ue_identity = ue_identityP; ue->random_ue_identity = ue_identityP;
f1_ue_data_t ue_data = {.secondary_ue = du_ue_id}; f1_ue_data_t ue_data = {.secondary_ue = du_ue_id, .du_assoc_id = assoc_id};
AssertFatal(!cu_exists_f1_ue_data(ue->rrc_ue_id), AssertFatal(!cu_exists_f1_ue_data(ue->rrc_ue_id),
"UE F1 Context for ID %d already exists, logic bug\n", "UE F1 Context for ID %d already exists, logic bug\n",
ue->rrc_ue_id); ue->rrc_ue_id);
+4 -2
View File
@@ -41,7 +41,8 @@ RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue
rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance_pP); rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance_pP);
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue); rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue);
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP); rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP);
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP);
void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP); void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP);
@@ -50,7 +51,8 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context
rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP);
rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI);
rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(sctp_assoc_t assoc_id,
rnti_t rnti,
gNB_RRC_INST* rrc_instance_pP, gNB_RRC_INST* rrc_instance_pP,
const uint64_t ue_identityP, const uint64_t ue_identityP,
uint32_t du_ue_id); uint32_t du_ue_id);
+278
View File
@@ -0,0 +1,278 @@
/*
* 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 "rrc_gNB_du.h"
#include "common/ran_context.h"
#include "nr_rrc_defs.h"
#include "rrc_gNB_UE_context.h"
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "executables/softmodem-common.h"
static int du_compare(const nr_rrc_du_container_t *a, const nr_rrc_du_container_t *b)
{
if (a->assoc_id > b->assoc_id)
return 1;
if (a->assoc_id == b->assoc_id)
return 0;
return -1; /* a->assoc_id < b->assoc_id */
}
/* Tree management functions */
RB_GENERATE/*_STATIC*/(rrc_du_tree, nr_rrc_du_container_t, entries, du_compare);
static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell_info_t *info)
{
const gNB_RrcConfigurationReq *conf = &rrc->configuration;
return conf->num_plmn == 1 // F1 supports only one
&& conf->mcc[0] == info->plmn.mcc
&& conf->mnc[0] == info->plmn.mnc;
}
void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
{
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
gNB_RRC_INST *rrc = RC.nrrrc[0];
DevAssert(rrc);
LOG_I(NR_RRC, "Received F1 Setup Request from gNB_DU %lu (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id);
// check:
// - it is one cell
// - PLMN and Cell ID matches
// - no previous DU with the same ID
// else reject
if (req->num_cells_available != 1) {
LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available);
f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
return;
}
f1ap_served_cell_info_t *cell_info = &req->cell[0].info;
if (!rrc_gNB_plmn_matches(rrc, cell_info)) {
LOG_E(NR_RRC,
"PLMN mismatch: CU %d%d, DU %d%d\n",
rrc->configuration.mcc[0],
rrc->configuration.mnc[0],
cell_info->plmn.mcc,
cell_info->plmn.mnc);
f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
return;
}
nr_rrc_du_container_t *it = NULL;
RB_FOREACH(it, rrc_du_tree, &rrc->dus) {
if (it->setup_req->gNB_DU_id == req->gNB_DU_id) {
LOG_E(NR_RRC,
"gNB-DU ID: existing DU %s on assoc_id %d already has ID %ld, rejecting requesting gNB-DU\n",
it->setup_req->gNB_DU_name,
it->assoc_id,
it->setup_req->gNB_DU_id);
f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
return;
}
// note: we assume that each DU contains only one cell; otherwise, we would
// need to check every cell in the requesting DU to any existing cell.
const f1ap_served_cell_info_t *exist_info = &it->setup_req->cell[0].info;
const f1ap_served_cell_info_t *new_info = &req->cell[0].info;
if (exist_info->nr_cellid == new_info->nr_cellid || exist_info->nr_pci == new_info->nr_pci) {
LOG_E(NR_RRC,
"existing DU %s on assoc_id %d already has cellID %ld/physCellId %d, rejecting requesting gNB-DU with cellID %ld/physCellId %d\n",
it->setup_req->gNB_DU_name,
it->assoc_id,
exist_info->nr_cellid,
exist_info->nr_pci,
new_info->nr_cellid,
new_info->nr_pci);
f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
return;
}
}
// if there is no system info or no SIB1 and we run in SA mode, we cannot handle it
const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info;
if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) {
LOG_E(NR_RRC, "no system information provided by DU, rejecting\n");
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
return;
}
/* do we need the MIB? for the moment, just check it is valid, then drop it */
NR_BCCH_BCH_Message_t *mib = NULL;
asn_dec_rval_t dec_rval =
uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length);
if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib
|| mib->message.choice.messageClassExtension == NULL) {
LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib);
return;
}
NR_SIB1_t *sib1 = NULL;
if (sys_info->sib1) {
dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length);
if (dec_rval.code != RC_OK) {
LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1);
return;
}
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1);
}
LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name);
// we accept the DU
nr_rrc_du_container_t *du = calloc(1, sizeof(*du));
AssertFatal(du != NULL, "out of memory\n");
du->assoc_id = assoc_id;
/* ITTI will free the setup request message via free(). So the memory
* "inside" of the message will remain, but the "outside" container no, so
* allocate memory and copy it in */
du->setup_req = malloc(sizeof(*du->setup_req));
AssertFatal(du->setup_req != NULL, "out of memory\n");
*du->setup_req = *req;
du->mib = mib->message.choice.mib;
mib->message.choice.mib = NULL;
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib);
du->sib1 = sib1;
RB_INSERT(rrc_du_tree, &rrc->dus, du);
rrc->num_dus++;
served_cells_to_activate_t cell = {
.plmn = cell_info->plmn,
.nr_cellid = cell_info->nr_cellid,
.nrpci = cell_info->nr_pci,
.num_SI = 0,
};
f1ap_setup_resp_t resp = {.num_cells_to_activate = 1, .cells_to_activate[0] = cell};
if (rrc->node_name != NULL)
resp.gNB_CU_name = strdup(rrc->node_name);
rrc->mac_rrc.f1_setup_response(assoc_id, &resp);
/*
MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE);
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).gNB_CU_name = rrc->node_name;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mcc = rrc->configuration.mcc[0];
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc = rrc->configuration.mnc[0];
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0];
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nr_cellid = rrc->nr_cellid;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nrpci = req->cell[0].info.nr_pci;
int num_SI = 0;
if (rrc->carrier.SIB23) {
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container[2] = rrc->carrier.SIB23;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container_length[2] = rrc->carrier.sizeof_SIB23;
num_SI++;
}
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].num_SI = num_SI;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).num_cells_to_activate = 1;
// send
itti_send_msg_to_task(TASK_CU_F1, 0, msg_p2);
*/
}
static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id)
{
int count = 0;
rrc_gNB_ue_context_t *ue_context_p = NULL;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) {
uint32_t ue_id = ue_context_p->ue_context.rrc_ue_id;
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id);
if (ue_data.du_assoc_id == assoc_id) {
/* this UE belongs to the DU that disconnected, set du_assoc_id to 0,
* meaning DU is offline */
cu_remove_f1_ue_data(ue_id);
f1_ue_data_t new = {.secondary_ue = ue_data.secondary_ue, .du_assoc_id = 0 };
cu_add_f1_ue_data(ue_id, &new);
count++;
}
}
return count;
}
void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id)
{
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
(void) lc; // unused for the moment
nr_rrc_du_container_t e = {.assoc_id = assoc_id};
nr_rrc_du_container_t *du = RB_FIND(rrc_du_tree, &rrc->dus, &e);
if (du == NULL) {
LOG_W(NR_RRC, "no DU connected or not found for assoc_id %d: F1 Setup Failed?\n", assoc_id);
return;
}
f1ap_setup_req_t *req = du->setup_req;
LOG_I(RRC, "releasing DU ID %ld (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id);
ASN_STRUCT_FREE(asn_DEF_NR_MIB, du->mib);
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, du->sib1);
/* TODO: free setup request */
nr_rrc_du_container_t *removed = RB_REMOVE(rrc_du_tree, &rrc->dus, du);
DevAssert(removed != NULL);
rrc->num_dus--;
int num = invalidate_du_connections(rrc, assoc_id);
if (num > 0) {
LOG_I(NR_RRC, "%d UEs lost through DU disconnect\n", num);
}
}
nr_rrc_du_container_t *get_du_for_ue(gNB_RRC_INST *rrc, uint32_t ue_id)
{
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id);
return get_du_by_assoc_id(rrc, ue_data.du_assoc_id);
}
nr_rrc_du_container_t *get_du_by_assoc_id(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id)
{
nr_rrc_du_container_t e = {.assoc_id = assoc_id};
return RB_FIND(rrc_du_tree, &rrc->dus, &e);
}
void dump_du_info(const gNB_RRC_INST *rrc, FILE *f)
{
fprintf(f, "%ld connected DUs \n", rrc->num_dus);
int i = 1;
nr_rrc_du_container_t *du = NULL;
/* cast is necessary to eliminate warning "discards ‘const’ qualifier" */
RB_FOREACH(du, rrc_du_tree, &((gNB_RRC_INST *)rrc)->dus) {
const f1ap_setup_req_t *sr = du->setup_req;
fprintf(f, "[%d] DU ID %ld (%s) ", i++, sr->gNB_DU_id, sr->gNB_DU_name);
if (du->assoc_id == -1) {
fprintf(f, "integrated DU-CU");
} else {
fprintf(f, "assoc_id %d", du->assoc_id);
}
const f1ap_served_cell_info_t *info = &sr->cell[0].info;
fprintf(f, ": nrCellID %ld, PCI %d\n", info->nr_cellid, info->nr_pci);
}
}
+43
View File
@@ -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 RRC_GNB_DU_H_
#define RRC_GNB_DU_H_
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <stdint.h>
#include <stdio.h>
struct f1ap_setup_req_s;
struct f1ap_lost_connection_t;
struct gNB_RRC_INST_s;
struct nr_rrc_du_container_t;
void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id);
void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id);
struct nr_rrc_du_container_t *get_du_for_ue(struct gNB_RRC_INST_s *rrc, uint32_t ue_id);
struct nr_rrc_du_container_t *get_du_by_assoc_id(struct gNB_RRC_INST_s *rrc, sctp_assoc_t assoc_id);
void dump_du_info(const struct gNB_RRC_INST_s *rrc, FILE *f);
#endif /* RRC_GNB_DU_H_ */
+1 -1
View File
@@ -414,7 +414,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti); LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id);
ue_context = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); ue_context = rrc_gNB_get_ue_context_by_rnti_any_du(rrc, rnti);
if (ue_context == NULL) { if (ue_context == NULL) {
LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti); LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti);
return; return;
-21
View File
@@ -510,27 +510,6 @@ static int udpServerSocket(openAddr_s addr) {
freeaddrinfo(servinfo); // all done with this structure freeaddrinfo(servinfo); // all done with this structure
if (false) {
struct addrinfo hints;
memset(&hints,0,sizeof(hints));
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_protocol=0;
hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG;
struct addrinfo *res=0;
int err=getaddrinfo(addr.destinationHost,addr.destinationService,&hints,&res);
if (err==0) {
for(p = res; p != NULL; p = p->ai_next) {
if ((err=connect(sockfd, p->ai_addr, p->ai_addrlen))==0)
break;
}
}
if (err)
LOG_E(GTPU,"Can't filter remote host: %s, %s\n", addr.destinationHost,addr.destinationService);
}
int sendbuff = 1000*1000*10; int sendbuff = 1000*1000*10;
AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),""); AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),"");
LOG_D(GTPU,"[%d] Created listener for paquets to: %s:%s, send buffer size: %d\n", sockfd, addr.originHost, addr.originService,sendbuff); LOG_D(GTPU,"[%d] Created listener for paquets to: %s:%s, send buffer size: %d\n", sockfd, addr.originHost, addr.originService,sendbuff);
@@ -278,7 +278,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "enb"; serveraddr = "enb";
serverport = "4043"; serverport = 4043;
options = ("saviq"); options = ("saviq");
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -240,7 +240,7 @@ THREAD_STRUCT = (
#rfsimulator : #rfsimulator :
#{ #{
# serveraddr = "server"; # serveraddr = "server";
# serverport = "4043"; # serverport = 4043;
# options = ("chanmod"); # options = ("chanmod");
# modelname = "AWGN"; # modelname = "AWGN";
#}; #};
@@ -215,7 +215,7 @@ THREAD_STRUCT = (
); );
rfsimulator: { rfsimulator: {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs" IQfile = "/tmp/rfsimulator.iqs"
@@ -228,7 +228,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -236,7 +236,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -228,7 +228,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -254,7 +254,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -255,7 +255,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -255,7 +255,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -234,7 +234,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -234,7 +234,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -230,7 +230,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -230,7 +230,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -230,7 +230,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -239,7 +239,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -234,7 +234,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -232,7 +232,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -231,7 +231,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -292,7 +292,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -291,7 +291,7 @@ THREAD_STRUCT = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
@@ -33,7 +33,7 @@ RUs = (
rfsimulator : rfsimulator :
{ {
serveraddr = "server"; serveraddr = "server";
serverport = "4043"; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN"; modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";