Merge remote-tracking branch 'origin/f1-multiple-du' into integration_2023_w44
This commit is contained in:
@@ -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>'
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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.
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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_ */
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
Reference in New Issue
Block a user