Compare commits

...

22 Commits

Author SHA1 Message Date
Victor Souza
d2f69a57a2 Update iab_info_management.h 2024-10-28 17:24:52 +00:00
Victor Souza
6477338da3 Update iab_info_management.h 2024-10-28 17:13:30 +00:00
Victor Souza
9512843137 Update iab_info_management.h 2024-10-28 17:09:32 +00:00
Victor Souza
fbe7e6b731 backup-checkpoint 2024-07-20 13:14:33 +01:00
Victor Souza
e40b128f3f safety checkpoint 2024-07-15 14:09:40 +01:00
Victor Souza
c4d96c8bfd added more IAB information support for the CU 2024-06-24 23:48:33 +01:00
Victor Souza
8fe9df7bf3 Added IAB information to RAN CONTEXT and implemented simple BAP Address attribution for donor-du 2024-06-12 23:47:04 +01:00
Victor Souza
06dd13d348 BAP layer init and BAP entity init (needs cleaning) 2024-05-20 13:26:55 +02:00
Victor Souza
070ae03629 BAP layer initialization on DU 2024-05-18 20:40:48 +02:00
Victor Souza
f6b422989a BAPAddress being traded during F1_SETUP_REQUEST and F1_SETUP_RESPONSE 2024-05-17 20:10:27 +02:00
Victor Souza
b1bb36a340 added bap_address support for du_gnb.conf type files and added new gNB node type (ngran_gNB_DU_IAB) 2024-05-14 16:25:27 +02:00
Victor Souza
2dc0a8d75c Most important BH rlc channel setup messages implemented 2024-05-13 16:36:45 +02:00
Victor Souza
0d56b3ce43 UEContextModificationResponse code compiles but doesn't work 2024-05-07 15:40:55 +02:00
Victor Souza
1d3c539ce2 bh rlc channel development checkpoint 2024-05-06 11:09:59 +02:00
Victor Souza
bf02d4c897 Added mac_rrc_dl functions and created bap_oai_api 2024-04-30 15:33:36 +02:00
Victor Souza
6483ae6383 CU sending UE CONTEXT MODIFICATION REQUEST to DU and DU receiving it successfully and sending (old) response back 2024-04-29 15:56:45 +02:00
Victor Souza
0a22f997cb added bhinfo to uluptnlInformation_ToBeSetup_List 2024-04-26 12:11:27 +02:00
Victor Souza
8a924cd011 compiling code for cu_send_ue_context_modification_request with no errors 2024-04-25 10:37:32 +02:00
Victor Souza
3d3d403614 some corrections 2024-04-24 14:18:09 +02:00
Victor Souza
9ee12ae551 added id-BHChannels-ToBeSetupMod-List to CU_send_UE_CONTEXT_MODIFICATION_REQUEST (not tested) 2024-04-23 15:01:36 +02:00
Victor Souza
8a5f54961f new branch 2024-04-19 10:09:07 +02:00
Victor Souza
f1b0cde103 new branch 2024-04-19 10:08:09 +02:00
58 changed files with 13070 additions and 10883 deletions

View File

@@ -354,6 +354,7 @@ configmodule_interface_t *load_configmodule(int argc,
if (i == 0) {
printf("[CONFIG] config module %s loaded\n",cfgmode);
// Continue/Read from this
int idx = config_paramidx_fromname(Config_Params, sizeofArray(Config_Params), CONFIGP_DEBUGFLAGS);
Config_Params[idx].uptr = &(cfgptr->rtflags);
idx = config_paramidx_fromname(Config_Params, sizeofArray(Config_Params), CONFIGP_TMPDIR);

View File

@@ -126,6 +126,12 @@ int config_get(configmodule_interface_t *cfgif, paramdef_t *params, int numparam
if (cfgif != NULL) {
ret = cfgif->get(cfgif, params, numparams, prefix);
/* testing
printf("Num params: %d\n", numparams);
for (int i = 0; i < numparams; i++){
printf("%d, %s\n", i, params[i].optname);
}
end testing */
if (ret >= 0) {
config_process_cmdline(cfgif, params, numparams, prefix);

View File

@@ -44,14 +44,18 @@ typedef enum {
ngran_gNB_DU = 7,
ngran_eNB_MBMS_STA = 8,
ngran_gNB_CUCP = 9,
ngran_gNB_CUUP = 10
ngran_gNB_CUUP = 10,
ngran_gNB_IAB_donor_DU = 11,
ngran_gNB_IAB_node_DU = 12,
} ngran_node_t;
typedef enum { CPtype = 0, UPtype } E1_t;
#define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB || (nOdE_TyPe) == ngran_ng_eNB || (nOdE_TyPe) == ngran_gNB)
#define NODE_IS_CU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU || (nOdE_TyPe) == ngran_gNB_CUCP || (nOdE_TyPe) == ngran_gNB_CUUP)
#define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU)
#define NODE_IS_CU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU || (nOdE_TyPe) == ngran_gNB_CUCP || (nOdE_TyPe) == ngran_gNB_CUUP)
#define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU || (nOdE_TyPe) == ngran_gNB_IAB_donor_DU || (nOdE_TyPe) == ngran_gNB_IAB_node_DU)
#define NODE_IS_IAB_DONOR_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_gNB_IAB_donor_DU)
#define NODE_IS_IAB_NODE_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_gNB_IAB_node_DU)
#define NODE_IS_MBMS(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_MBMS_STA)
#define GTPV1_U_PORT_NUMBER (2152)

View File

@@ -41,6 +41,7 @@ struct PHY_VARS_gNB_s;
struct PHY_VARS_eNB_NB_IoT_s;
struct eNB_RRC_INST_s;
struct gNB_RRC_INST_s;
struct gNB_IAB_INFO_s;
struct eNB_MAC_INST_s;
struct eNB_MAC_INST_NB_IoT_s;
struct gNB_MAC_INST_s;
@@ -92,6 +93,8 @@ typedef struct {
//struct eNB_RRC_INST_NB_IoT_s **nb_iot_rrc;
/// NR RRC context variables
struct gNB_RRC_INST_s **nrrrc;
/// IAB context variables
struct gNB_IAB_INFO_s **iab;
/// MAC context variables
struct eNB_MAC_INST_s **mac;
/// NB_IoT MAC context variables

356
doc/IAB_docs/BAP_Info.md Normal file
View File

@@ -0,0 +1,356 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="../images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">BAP Documentation</font></b>
</td>
</tr>
</table>
**Table of Contents**
[[_TOC_]]
# Glossary
| Acronym | Description |
| ------- | ------------------------------ |
| BAP | Backhaul Adaptation Protocol |
| BH | Backhaul |
| CU | Centralized Unit |
| DU | Distributed Unit |
| IAB | Integrated Access and Backhaul |
| IE | Information Element |
| MT | Mobile Termination |
| RLC | Radio Link Control |
| RRC | Radio Resource Control |
# 1. Scenario
This document aims to gather all the needed requirements to implement the Backhaul Adaptation Protocol (BAP) (Based on TS 38.340-i00 (release 18)).
# 2. General
## 2.1. Entities
BAP is a layer 2 routing protocol that sits on top of the RLC layer and is responsible for routing packages through multiple node hops.
<p>
<img src="./images/BAP_layer_structure.png" width=600></br>
<em>Figure 2.1-1 - BAP layer structure view (TS 38.340)</em>
</p>
BAP works with entities:
- BAP entity at node MT;
- BAP entity at node DU;
- BAP entity at donor DU.
The transmitting part of BAP entity has a corresponding receiving part of another BAP entity.
<p>
<img src="./images/BAP_layer_functional_example.png" width=600></br>
<em>Figure 2.1-2 - Example of BAP Layer Functionality (TS 38.340)</em>
</p>
## 2.2. Services
### 2.2.1 BAP -> upper layers
(Service that needs to be performed by BAP)
- Data transfer.
### 2.2.2 Lower layer (Per RLC entity) -> BAP
(Services expected from lower levels to BAP)
- Acknowledged data transfer service;
- Unacknowledged data transfer service.
## 2.3. Functions
A BAP sublayer must support the following functions:
- Data transfer;
- Determination of BAP destination and path for packets from upper layers;
- Determination of egress BH RLC channels for packets routed to next hop;
- Routing of packets to next hop;
- BAP header rewriting;
- Differentiating traffic to be delivered to upper layers from traffic to be delivered to egress link;
- Flow control feedback and polling signalling;
- Handling of BH RLF related indications.
## 2.4. Configurations
The configuration of the BAP entity includes:
- The IAB-node's BAP address(es) via RRC;
- The IAB-donor-DU's BAP address via F1AP;
- Mapping from next hop BAP address to downstream egress link via F1AP;
- Mapping from next hop BAP address to upstream egress link via RRC;
- Mapping from upper layer traffic to BAP routing ID in BAP header via F1AP and RRC;
- The BAP routing entries via F1AP;
- Mapping to egress BH RLC channels via F1AP and RRC;
- Flow control feedback type(s) to be provided, if any, via RRC;
- Inter-donor-DU re-routing enabling/disabling via F1AP.
Configure **RLC** channels:
- Via RRC on the IAB-MT;
- via F1AP on the IAB-DU/IAB-donor-DU.
The **F1AP** configurations (Which derive from the original F1AP signaling) are:
- Uplink Traffic to Routing ID Mapping Configuration;
- Downlink Traffic to Routing ID Mapping Configuration;
- BH Routing Configuration;
- BH RLC Channel Mapping Configuration;
- Uplink Traffic to BH RLC Channel Mapping Configuration;
- Downlink Traffic to BH RLC Channel Mapping Configuration;
- Header Rewriting Configuration.
# 3. Procedures
## 3.1. BAP entity handling
### 3.1.1 Entity establishment
When upper layers request establishment of a BAP entity, the node shall:
- Establish a BAP entity;
- Follow the other procedures in this section.
### 3.1.2 Entity release
When upper layers request release of a BAP entity, the node shall:
- Release the BAP entity and the related BAP configurations.
## 3.2 Data transfer
### 3.2.1 Transmitting Operations
#### **3.2.1.1 General**
Upon **receiving a BAP SDU** from upper layers, the **transmitting part** of the BAP entity shall:
- **(Clause ####)** Select a BAP address and a BAP path identity for this BAP SDU;
- **(Clause ####)** Construct a BAP Data PDU by adding a BAP header to the BAP SDU, where:
- **DESTINATION** field is set to the selected BAP address;
- **PATH** field is set to the selected BAP path identity.
When the BAP entity has a **BAP Data PDU to transmit**, the **transmitting part** of the BAP entity shall:
- **(Clause ####)** For the boundary IAB-node, if the BAP Data PDU is received from the collocated BAP entity (in the same node), perform the BAP header rewriting operation (if configured);
- **(Clause ####)** Perform routing to determine the egress link;
- **(Clause ####)** Determine the egress BH RLC channel;
- Submit this BAP Data PDU to the selected egress BH RLC channel of the selected egress link.
#### **3.2.1.2 BAP routing ID selection**
**At IAB-node**
At an IAB-node, for a BAP SDU received from upper layers and to be transmitted in upstream direction, the BAP entity performs mapping to a BAP address and BAP path identity based on:
- Uplink Traffic to Routing ID Mapping Configuration, which is derived from F1AP on the IAB-node in TS 38.473;
- <span style="color:#33C8FF">_defaultUL-BAP-RoutingID_</span>, which is configured by RRC on the IAB-node in TS 38.331.
Each entry of the Uplink Traffic to Routing ID Mapping Configuration contains:
- A traffic type specifier, which is indicated by <span style="color:#33C8FF">_UL UP TNL Information_</span> IE for F1-U packets and <span style="color:#33C8FF">_Non-UP TrafficType_</span> IE for non-F1-U packets in TS 38.473;
- A BAP routing ID, which includes a BAP address and a BAP path identity, indicated by <span style="color:#33C8FF">_BAP Routing ID_</span> IE in <span style="color:#33C8FF">_BH Information_</span> IE in TS 38.473;
For a BAP SDU received from upper layers and to be transmitted in upstream direction, the BAP entity shall:
<pre>
<b>if</b> the Uplink Traffic to Routing ID Mapping Configuration has not
been (re)configured by the F1AP associated with the (logical) DU, where
this BAP SDU is received, after the last (re)configuration of
<span style="color:#33C8FF"><i>defaultUL-BAPRoutingID</i></span> by RRC:
<b>select</b> the BAP address and the BAP path identity as configured by
<span style="color:#33C8FF"><i>defaultUL-BAP-RoutingID</i></span> in TS 38.331 for non-F1-U packets;
<b>else</b>:
<b>for the</b> BAP SDU encapsulating an F1-U packet:
<b>select</b> an entry from the Uplink Traffic to Routing ID Mapping
Configuration with its traffic type specifier corresponds to the
destination IP address and TEID of this BAP SDU;
<b>for the</b> BAP SDU encapsulating a non-F1-U packet:
<b>select</b> an entry from the Uplink Traffic to Routing ID Mapping
Configuration with its traffic type specifier corresponds to the
traffic type of this BAP SDU;
<b>select</b> the BAP address and the BAP path identity from the BAP routing ID in the entry
selected above;
<b>if</b> the selected entry is configured with <span style="color:#33C8FF"><i>Non-F1-terminating IAB-donor Topology
Indicator</i></span> IE:
<b>consider</b> this BAP Data PDU as data to be routed to non-F1-terminating
donor topology
</pre>
**At IAB-donor-DU**
For a BAP SDU received from upper layer at the IAB-donor-DU, the BAP entity performs mapping to a BAP address and a BAP Path identity based on:
- Downlink Traffic to Routing ID Mapping Configuration, which is derived from <span style="color:#33C8FF"><i>IP-to-layer-2 traffic mapping Information List</i></span> IE configured on the IAB-donor-DU in TS 38.473.
Each entry of the Downlink Traffic to Routing ID Mapping Configuration contains:
- A destination IP address, which is indicated by <span style="color:#33C8FF"><i>Destination IAB TNL Address</i></span> IE in IP header information IE, including an IPv4 address or IPv6 address or an IPv6 address prefix;
- An IPv6 flow label, if configured, which is indicated by <span style="color:#33C8FF"><i>IPv6 Flow Label</i></span> IE in <span style="color:#33C8FF"><i>IP header information</i></span> IE;
- A DSCP, if configured, which is indicated by <span style="color:#33C8FF"><i>DSCP</i></span> IE in <span style="color:#33C8FF"><i>DS Information List</i></span> IE in <span style="color:#33C8FF"><i>IP header information</i></span> IE;
- A BAP routing ID, which is indicated by <span style="color:#33C8FF"><i>BAP Routing ID</i></span> IE in <span style="color:#33C8FF"><i>BH Information</i></span> IE in TS 38.473.
For a BAP SDU received from upper layers and to be transmitted in downstream direction, the BAP entity shall:
<pre>
<b>for the</b> BAP SDU encapsulating an IPv6 packet:
<span style="color:lightgreen"># (not very relevant) Check TS 38.340</span>
<b>for the</b> BAP SDU encapsulating an IPv4 packet:
<b>Select</b> an entry from the Downlink Traffic to Routing ID Mapping
Configuration which fulfils the following conditions:
This BAP SDU Destination IP address <span style="color:orange">==</span> Destination IP address in
this entry
<span style="color:#BB8FCE">AND</span>
This BAP SDU DSCP <span style="color:orange">==</span> DSCP in this entry (if configured)
<b>select</b> the BAP address and the BAP path identity from the BAP routing ID in
the entry selected above
</pre>
#### **3.2.1.3 Routing**
BAP entity performs routing based on the BH Routing Configuration derived from an F1AP message, as specified in TS 38.473.
Each entry of the BH Routing Configuration contains:
- <b>BAP Routing ID</b> consisting of a BAP address and a BAP path identity, which is indicated by <span style="color:#33C8FF">_BAP Routing ID_</span> IE;
- <b>Next Hop BAP Address</b> which is indicated by <span style="color:#33C8FF">_Next-Hop BAP Address_</span> IE;
- <b>Topology indicator</b>, indicating whether the entry belongs to the non-F1-terminating donor topology, which is optionally indicated by <span style="color:#33C8FF">_Non-F1-terminating IAB-donor Topology Indicator_</span> IE.
For a BAP Data PDU to be transmitted, BAP entity shall:
<pre>
<b>if</b> the BAP Data PDU corresponds to a BAP SDU received from the upper layer
<span style="color:#BB8FCE">AND</span>
<b>if</b> the BH Routing Configuration has not been (re)configured by the F1AP
associated with the (logical) DU, where this BAP SDU is received, after the
last (re)configuration of <span style="color:#33C8FF"><i>defaultUL-BH-RLC-Channel</i></span> by RRC:
<b>select</b> the egress link on which the egress BH RLC channel corresponding
to <span style="color:#33C8FF"><i>defaultUL-BH-RLC-Channel</i></span> is configured as specified in TS 38.331 for
non-F1-U packets;
<b>else if</b> there is an entry in the BH Routing Configuration whose BAP
address matches the DESTINATION field, whose BAP path identity is the
same as the PATH field, and whose egress link corresponding to the Next Hop
BAP Address is available:
<b>select</b> the egress link corresponding to the Next Hop BAP Address
of the entry;
<b>else if</b> there is at least one entry in the BH Routing Configuration whose
BAP address matches the DESTINATION field, and whose egress link corresponding
to the Next Hop BAP Address is available:
<b>select</b> an entry from the BH Routing Configuration whose BAP address
is the same as the DESTINATION field, and whose egress link corresponding
to the Next Hop BAP Address is available;
<b>select</b> the egress link corresponding to the Next Hop BAP Address of
the entry selected above;
<b>else if</b>, for the transmitting part of IAB-MT, at least one egress link is
available, and if <span style="color:#33C8FF"><i>Re-routing Enable Indicator</i></span> IE is set to true by F1AP:
<b>if</b> this egress link belongs to F1-terminating donor topology of the
boundary IAB-node or the transmitting part of IAB-MT is not at the
boundary IAB-node, and there is an entry in the BH Routing Configuration
not configured with <span style="color:#33C8FF"><i>Non-F1-terminating IAB-donor Topology Indicator</i></span> IE
whose Next Hop BAP Address corresponds to this egress link
<span style="color:#BB8FCE">OR</span>
<b>if</b> this egress link belongs to non-F1-terminating donor topology, and
there is an entry in the BH Routing Configuration configured with
<span style="color:#33C8FF"><i>Non-F1-terminating IAB-donor Topology Indicator</i></span> IE whose Next Hop BAP
Address corresponds to this egress link:
<b>select</b> the egress link;
<b>rewrite</b> the BAP header of this BAP Data PDU, where the DESTINATION
field is set to the leftmost 10 bits of BAP Routing ID of the entry in
the BH Routing Configuration (i.e. BAP address), and the PATH field is
set to the rightmost 10 bits of BAP Routing ID of the entry (i.e. BAP
path identity)
</pre>
#### **3.2.1.4 Mapping to BH RLC Channel**
**Mapping to BH RLC Channel for BAP Data Packets from collocated BAP entity at IAB-node**
Check page 14 and 15
**Mapping to BH RLC Channel for BAP SDUs from upper layers at IAB-node**
Check page 15 and 16
**Mapping to BH RLC Channel at IAB-donor-DU**
Check page 16 and 17
#### **3.2.1.4 BAP header rewriting operation**
Check page 17
### 3.2.2 Receiving Operations
Upon receiving a BAP Data PDU from lower layer (i.e. ingress BH RLC channel), the receiving part of the BAP entity shall:
<pre>
<b>if</b> DESTINATION field of this BAP Data PDU matches the BAP address, which
is configured for this IAB-node by the IAB-donor providing this ingress BH RLC
channel configuration:
<b>remove</b> the BAP header of this BAP Data PDU and deliver the BAP SDU to
upper layers;
<b>else</b>:
<b>deliver</b> the BAP Data Packet to the transmitting part of the collocated
BAP entity.
</pre>
## 3.3 Flow control
Check page 18
## 3.4 BH RLF related indications
Check page 19
## 3.5 Handling of unknown, unforeseen, and erroneous protocol data
When a BAP Data PDU contains a BAP address which is not included in the applied entries of BH Routing
Configuration during Routing operation in accordance with clause 5.2.1.3 and the BAP Data PDU contains a BAP
address which is not the BAP address of this node in accordance with clause 5.2.2 upon receiving; or
when a BAP Control PDU that contains reserved or invalid values is received the BAP entity shall:
- discard the received BAP PDU.
# 4 Protocol data units, formats, and parameters
## 4.1 Protocol data units
### 4.1.1 Data PDU
Used to convey:
- Upper layer data.
### 4.1.2 Control PDU
Used to convey:
- Flow control feedbacck per BH RLC channel;
- Flow control feedback per BAP routing ID;
- flow control polling;
- BH RLF related indication.
## 4.2 Formats and Parameters
Check pages 20 to 23

123
doc/IAB_docs/IAB_Info.md Normal file
View File

@@ -0,0 +1,123 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="../images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI IAB Documentation</font></b>
</td>
</tr>
</table>
**Table of Contents**
[[_TOC_]]
# Glossary
| Acronym | Description |
| ------- | ------------------------------ |
| BAP | Backhaul Adaptation Protocol |
| BH | Backhaul |
| CP | Control Plane |
| IAB | Integrated Access and Backhaul |
| RLC | Radio Link Control |
| RLF | Radio Link Failure |
| RRC | Radio Resource Control |
| TNL | Transport Network Layer |
| UP | User Plane |
# 1. Scenario
This document aims to gather all the needed requirements to implement a 5G SA 3GPP compliant Integrated Access and Backhaul (IAB).
# 2. Protocol Stacks
## 2.1 Protocol stack for the support of F1-U protocol
<img src="./images/Protocol_stack_F1-U.png" width=600>
## 2.2 Protocol stack for the support of F1-C protocol
<img src="./images/Protocol_stack_F1-C.png" width=600>
## 2.3 Protocol stack for the support of IAB-MT's RRC and NAS connections
<img src="./images/Protocol_stack_RRC_NAS.png" width=600>
# 3. Backhaul Adaptation Protocol (BAP) (TS 38.340)
Some info in [BAP_info](./BAP_Info.md)
# 4. F1 Mods (TS 38.470 and 38.473)
Needed functions:
- BAP mapping configuration function;
- gNB-DU resource configuration function;
- IAB TNL address configuration function;
- IAB UP configuration update function;
- Mobile IAB F1 Setup Triggering function; (Can we skip mobile IAB for now?)
- Mobile IAB F1 Setup Outcome Notification function. (Can we skip mobile IAB for now?)
# 5. RRC Mods (TS 38.331)
Some info in [RRC_IAB_info](./RRC_IAB_Info.md)
# 6. IAB-MT mandatory features (TS 38.306)
- Routing using BAP (TS 38.340-i00 (release 18), pages 11-17)
- Bearer mapping using BAP (TS 38.340-i00 (release 18), pages 11-17)
- IAB-node IP address signalling over RRC (TS 38.331-i00 (release 18), page 133)
<img src="./images/IAB-MT-Requirements.png" width=600>
# 7. IAB Resource Configuration (TS 38.300)
Check TS 38.300-i00 (release 18), pages 122 and 123.
# 8. Required signalling procedures (TS 38.300 and TS 38.401)
## 8.1 IAB-node Integration (TS 38.401-i00, page 87 and 88)
<img src="./images/IAB_node_integration.png" width=600>
## _8.2 IAB-node Migration (Mobile IAB???)_
## 8.3 Topological Management (TS 38.300-i00, page 34)
### 8.3.1 IAB Inter-donor-DU Re-routing (TS 38.401-i00, pages 105, 106)
When an IAB-donor-DU is configured to support inter-donor-DU re-routing, the IAB-donor-DU may identify a rerouted UL IP packet based on the source IP address field of the UL packet, and forwards UL IP packets, whose source IP addresses are anchored at a peer IAB-donor-DU, to this peer IAB-donor-DU via a tunnel. The IAB-donor-DU and the peer IAB-donor-DU may be controlled by the same IAB-donor-CU or by two different IAB-donor-CUs. The interdonor-DU tunnel may be a GTP-U tunnel. The configuration of the tunnel is up to implementation. At the IAB-donor-DU forwarding the UL IP packets, inter-donor-DU tunnelling may be restricted to only a subset of the IP addresses anchored at the peer IAB-donor-DU. For this purpose, the IAB-donor-CU configures the IAB-donor-DU for forwarding the UL IP packets with a list of TNL addresses and/or prefixes for which tunnelling should be permitted and TNL
address filtering should be exempted.
### 8.3.2 IAB Inter-CU topological redundancy procedure (TS 38.3401-i00, pages 106, 107 and 108)
<img src="./images/IAB_inter-CU_redundancy.png" width=600>
### 8.3.3 IAB Inter-CU topology adaptation procedure (TS 38.3401-i00, pages 108 to 111)
<img src="./images/IAB_inter-CU_topology_adaptation.png" width=600>
### 8.3.4 IAB inter-CU topology adaptation procedure with descendant IAB-node (TS 38.3401-i00, pages 111 to 113)
<img src="./images/IAB_inter-CU_topology_adaptation_descendant.png" width=600>
### 8.3.5 IAB Inter-CU Backhaul RLF recovery for single connected IAB-node (TS 38.3401-i00, pages 113 to 116)
<img src="./images/IAB_inter-CU_BH_RLF_recovery_for_single_node.png" width=600>
## 8.4 OTA timing synchronization (38.300-i00, page 34)
An IAB-DU is subject to the same downlink timing alignment of a gNB. The IAB-DU may use the received downlink
signal from a parent as a reference to control its downlink timing using TA in conjunction with an additional Tdelta
parameter received by the collocated IAB-MT from the parent via MAC-CE.
## 8.5 Inter node discovery (38.300-i00, page 35)
Inter node discovery is supported via SSB-based and/or CSI-RS-based measurements. An IAB-node can be configured
to transmit and receive off synchronization raster SSB signals to discover neighbouring IAB-nodes. The configuration
is not expected to create a conflict between IAB-DU SSB transmission and IAB-MT SSB measurement windows.

View File

@@ -0,0 +1,242 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="../images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">RRC - IAB related Documentation</font></b>
</td>
</tr>
</table>
**Table of Contents**
[[_TOC_]]
# Glossary
| Acronym | Description |
| ------- | ------------------------------ |
| BAP | Backhaul Adaptation Protocol |
| BH | Backhaul |
| DL | Downlink |
| IAB | Integrated Access and Backhaul |
| IE | Information Element |
| MCG | Master Cell Group |
| RLC | Radio Link Control |
| RRC | Radio Resource Control |
| SCG | Secondary Cell Group |
| UL | Uplink |
# 1. Scenario
This document aims to gather all the needed requirements to implement IAB in the Radio Resource Control (RRC) level (TS 38.331).
# 2. BAP configuration
The IAB-MT shall:
<pre>
<b>if</b> the <span style="color:#33C8FF"><i>bap_Config</i></span> is set to <span style="color:#33C8FF"><i>setup</i></span>:
<b>if</b> no BAP entity is established:
<b>establish</b> a BAP entity as specified in TS 38.340;
<b>if</b> <span style="color:#33C8FF"><i>bap-Address</i></span> is included:
<b>configure</b> the BAP entity to use the bap-Address as this
node's BAP address;
<b>if</b> <span style="color:#33C8FF"><i>defaultUL-BAP-RoutingID</i></span> is included:
<b>configure</b> the BAP entity to apply the default UL BAP routing ID
according to the configuration;
<b>if</b> <span style="color:#33C8FF"><i>defaultUL-BH-RLC-Channel</i></span> is included:
<b>configure</b> the BAP entity to apply the default UL BH RLC channel
according to the configuration;
<b>if</b> <span style="color:#33C8FF"><i>flowControlFeedbackType</i></span> is included:
<b>configure</b> the BAP entity to apply the flow control feedback according
to the configuration;
<b>if</b> the <span style="color:#33C8FF"><i>bap-Config</i></span> is set to release:
<b>release</b> the concerned <span style="color:#33C8FF"><i>bap-Config</i></span>;
<b>if</b> there is no other configured <span style="color:#33C8FF"><i>bap-Config</i></span> for the MCG or for the SCG
<b>release</b> the BAP entity as specified in TS 38.340.
</pre>
# 3. IAB other configuration
## 3.1 IP address release
The IAB-MT shall:
<pre>
<b>if</b> the release is triggered by reception of the <span style="color:#33C8FF"><i>iab-IP-AddressToReleaseList</i></span>:
<b>for each</b> <span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span> value included in
<span style="color:#33C8FF"><i>iab-IP-AddressToReleaseList</i></span>:
<b>release</b> the corresponding <span style="color:#33C8FF"><i>IAB-IP-AddressConfiguration</i></span>.
</pre>
## 3.2 IP address addition/modification
The IAB-MT shall:
<pre>
<b>for each</b> <span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span> value included in the <span style="color:#33C8FF"><i>iab-IP-AddressToAddModList</i></span>
that is not part of the current IAB-MT configuration:
<b>add</b> the IP address indicated in <span style="color:#33C8FF"><i>iab-IP-Address</i></span>, corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>if</b> added IP address is <span style="color:#33C8FF"><i>iPv4-Address</i></span>:
<b>if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>f1-C</i></span>:
<b>store</b> the received IPv4 address for F1-C traffic together with
the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>f1-U</i></span>:
<b>store</b> the received IPv4 address for F1-U traffic together with
the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>non-F1</i></span>:
<b>store</b> the received IPv4 address for non-F1 traffic together with
the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else</b>:
<b>store</b> the received IPv4 address for all traffic together with
the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iPv6-Address</i></span> is included:
<b>if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>f1-C</i></span>:
<b>store</b> the received IPv6 address for F1-C traffic together with
the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>f1-U</i></span>:
<b>store</b> the received IPv6 address for F1-U traffic together with
the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>non-F1</i></span>:
<b>store</b> the received IPv6 address for non-F1 traffic together with
the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else</b>:
<b>store</b> the received IPv6 address for all traffic together with the
IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iPv6-Prefix</i></span> is included in <span style="color:#33C8FF"><i>iab-IP-AddressToAddModList</i></span>:
<b>if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>f1-C</i></span>:
<b>store</b> the received IPv6 address prefix for F1-C traffic together
with the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>f1-U</i></span>:
<b>store</b> the received IPv6 address prefix for F1-U traffic together
with the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else if</b> <span style="color:#33C8FF"><i>iab-IP-Usage</i></span> is set to <span style="color:#33C8FF"><i>non-F1</i></span>:
<b>store</b> the received IPv6 address prefix for non-F1 traffic
together with the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>else</b>:
<b>store</b> the received IPv6 address prefix for all traffic together
with the IAB-donor-DU BAP address corresponding to the
<span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
<b>for each</b> <span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span> value included in the <span style="color:#33C8FF"><i>iab-IP-AddressToAddModList</i></span>
that is part of the current IA-BMT configuration:
<b>modify</b> the IP address configuration(s) in accordance with the
<span style="color:#33C8FF"><i>IAB-IP-AddressConfiguration</i></span> corresponding to the <span style="color:#33C8FF"><i>iab-IP-AddressIndex</i></span>.
</pre>
# 4 "IAB Other Information" (Procedure)
<p>
<img src="./images/IAB_other_info.png" width=600></br>
<em>Figure 4.1 - IAB Other information procedure (TS 38.331)</em>
</p>
The IAB Other Information procedure is used by IAB-MT to request the IAB-donor-CU to allocate IP address or
inform the IAB-donor-CU of the IP address for the collocated IAB-DU.
## 4.1 Initiation
Upon initiation of the procedure, the IAB-MT shall:
- initiate transmission of the <span style="color:#33C8FF"><i>IABOtherInformation</i></span> message.
## 4.2 Actions related to transmission of IABOtherInformation message
The IAB-MT shall set the contents of <span style="color:#33C8FF"><i>IABOtherInformation</i></span> message as follows:
<pre>
<b>if</b> the procedure is used to request IP addresses:
<b>if</b> IPv4 addresses are requested:
<b>set</b> the <span style="color:#33C8FF"><i>iab-IPv4-AddressNumReq</i></span> to the number of IPv4 addresses
requested per specific usage;
<b>if</b> IPv6 addresses or IPv6 address prefixes are requested:
<b>if</b> IPv6 addresses are requested:
<b>set</b> the <span style="color:#33C8FF"><i>iab-IPv6-AddressNumReq</i></span> to the number of IPv6 addresses
requested per specific usage;
<b>else if</b> IPv6 address prefixes are requested:
<b>set</b> the <span style="color:#33C8FF"><i>iab-IPv6-AddressPrefixReq</i></span> to <span style="color:orange"><i>true</i></span> per specific usage;
<b>if</b> the procedure is used to report IP addresses:
<b>if</b> IPv4 addresses are reported:
<b>include</b> <span style="color:#33C8FF"><i>iPv4-Address</i></span> in <span style="color:#33C8FF"><i>iab-IPv4-AddressReport</i></span>, and for each IP
address included:
<b>if</b> IPv4 addresses are used for F1-C traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>f1-C-Traffic-IP-Address</i></span>.
<b>if</b> IPv4 addresses are used for F1-U traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>f1-U-Traffic-IP-Address</i></span>.
<b>if</b> IPv4 address are used for non-F1 traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>non-f1-Traffic-IP-Address</i></span>.
<b>if</b> IPv4 addresses are used for all traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>all-Traffic-IAB-IP-Address</i></span>.
<b>if</b> IPv6 addresses or IPv6 address prefixes are reported:
<b>if</b> IPv6 addresses are reported:
<b>include</b> <span style="color:#33C8FF"><i>iPv6-Address</i></span> in <span style="color:#33C8FF"><i>iab-IPv6-AddressReport</i></span>.
<b>for each</b> IP address included (in previous step):
<b>if</b> IPv6 addresses are used for F1-C traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>f1-C-Traffic-IP-Address</i></span>.
<b>if</b> IPv6 addresses are used for F1-U traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>f1-U-Traffic-IP-Address</i></span>.
<b>if</b> IPv6 addresses are used for non-F1 traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>non-f1-Traffic-IP-Address</i></span>.
<b>if</b> IPv6 addresses are used for all traffic:
<b>include</b> these addresses in <span style="color:#33C8FF"><i>all-Traffic-IAB-IP-Address</i></span>.
<b>else if</b> IPv6 address prefixes are reported:
<b>include</b> these <span style="color:#33C8FF"><i>iPv6-Prefix</i></span> in <span style="color:#33C8FF"><i>iab-IPv6-PrefixReport</i></span>.
<b>for each</b> IP address prefix included (in previous step):
<b>if</b> this IPv6 address prefix is used for F1-C traffic:
<b>include</b> this prefix in <span style="color:#33C8FF"><i>f1-C-Traffic-IP-Address</i></span>.
<b>if</b> this IPv6 address prefix is used for F1-U traffic:
<b>include</b> this prefix in <span style="color:#33C8FF"><i>f1-U-Traffic-IP-Address</i></span>.
<b>if</b> this IPv6 address prefix is used for non-F1 traffic:
<b>include</b> this prefix in <span style="color:#33C8FF"><i>non-f1-Traffic-IP-Address</i></span>.
<b>if</b> this IPv6 address prefix is used for all traffic:
<b>include</b> this prefix in <span style="color:#33C8FF"><i>all-Traffic-IAB-IP-Address</i></span>.
<b>if</b> the IAB-MT is in (NG)EN-DC
<span style="color:#BB8FCE">OR</span>
<b>if</b> the IAB-MT is in NR-DC and the IAB Other Information procedure is
towards the IAB-donor-CU in the SN:
<b>if</b> SRB3 is configured:
<b>submit</b> the <span style="color:#33C8FF"><i>IABOtherInformation</i></span> message via SRB3 to lower layers
for transmission;
<b>else if</b> the IAB-MT is in (NG)EN-DC:
<b>submit</b> the <span style="color:#33C8FF"><i>IABOtherInformation</i></span> message via the E-UTRA MCG embedded
in E-UTRA RRC message <span style="color:#33C8FF"><i>ULInformationTransferMRDC</i></span> as specified in
TS 36.331;
<b>else</b>:
<b>submit</b> the <span style="color:#33C8FF"><i>IABOtherInformation</i></span> message via the NR MCG embedded
in NR RRC message <span style="color:#33C8FF"><i>ULInformationTransferMRDC</i></span>;
<b>else</b>:
<b>submit</b> the <span style="color:#33C8FF"><i>IABOtherInformation</i></span> message to lower layers for transmission.
</pre>
## 4.3 Message Definition _IABOtherInformation_
Consult pages 454 to 457 of TS 38.331-i00 (release 18 2023-12)
# 5 Information Elements (IE)
## 5.1 _IAB-IP-Adress_
Consult page 1292 of TS 38.331-i00 (release 18 2023-12)
## 5.2 _IAB-IP-AddressIndex_
Consult pages 1292 and 1293 of TS 38.331-i00 (release 18 2023-12)
## 5.3 _IAB-IP-Usage_
Consult page 1293 of TS 38.331-i00 (release 18 2023-12)

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -60,6 +60,8 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "LAYER2/BAP/bap_oai_api.h"
#include "LAYER2/BAP/iab_info_management.h"
#include "intertask_interface.h"
@@ -81,6 +83,8 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "gnb_config.h"
#include "openair2/E1AP/e1ap_common.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" // need to get info from MAC
#ifdef E2_AGENT
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h"
@@ -308,6 +312,9 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
RC.nrrrc = calloc(1, sizeof(*RC.nrrrc));
RC.nrrrc[0] = calloc(1,sizeof(gNB_RRC_INST));
RCconfig_NRRRC(RC.nrrrc[0]);
// IAB
RC.iab = calloc(1, sizeof(*RC.iab));
RC.iab[0] = calloc(1, sizeof(gNB_IAB_INFO));
}
if (RC.nb_nr_inst > 0 &&
@@ -317,7 +324,7 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
init_pdcp();
}
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(node_type)
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(node_type), or DU_IAB
LOG_I(X2AP, "X2AP enabled \n");
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
}
@@ -560,7 +567,6 @@ void init_pdcp(void) {
}
#ifdef E2_AGENT
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" // need to get info from MAC
static void initialize_agent(ngran_node_t node_type, e2_agent_args_t oai_args)
{
AssertFatal(oai_args.sm_dir != NULL , "Please, specify the directory where the SMs are located in the config file, i.e., add in config file the next line: e2_agent = {near_ric_ip_addr = \"127.0.0.1\"; sm_dir = \"/usr/local/lib/flexric/\");} ");
@@ -673,7 +679,7 @@ int main( int argc, char **argv ) {
if (RC.nb_nr_L1_inst > 0)
RCconfig_NR_L1();
if (NFAPI_MODE != NFAPI_MODE_PNF) {
int ret = create_gNB_tasks(node_type, uniqCfg);
AssertFatal(ret == 0, "cannot create ITTI tasks\n");
@@ -744,8 +750,9 @@ int main( int argc, char **argv ) {
}
// wait for F1 Setup Response before starting L1 for real
if (NODE_IS_DU(node_type) || NODE_IS_MONOLITHIC(node_type))
if (NODE_IS_DU(node_type) || NODE_IS_MONOLITHIC(node_type)){
wait_f1_setup_response();
}
if (RC.nb_RU > 0)
start_NR_RU();

View File

@@ -816,16 +816,16 @@ void *UE_thread(void *arg)
delNotifiedFIFO_elt(res);
start_rx_stream=0;
} else {
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// For IQ recorder/player we force synchronization to happen in 280 ms
while (trashed_frames != 28) {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
}
} else {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
}
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// For IQ recorder/player we force synchronization to happen in 280 ms
while (trashed_frames != 28) {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
}
} else {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
}
continue;
}
}

View File

@@ -162,6 +162,10 @@ typedef struct f1ap_setup_req_s {
f1ap_served_cell_info_t info;
f1ap_gnb_du_system_info_t *sys_info;
} cell[F1AP_MAX_NB_CELLS];
// BIT STRING (SIZE(10))
uint16_t bap_address;
} f1ap_setup_req_t;
typedef struct f1ap_du_register_req_t {
@@ -195,6 +199,8 @@ typedef struct f1ap_setup_resp_s {
/// rrc version
uint8_t rrc_ver[3];
uint16_t bap_address;
} f1ap_setup_resp_t;
typedef struct f1ap_gnb_cu_configuration_update_s {
@@ -283,10 +289,34 @@ typedef struct f1ap_ul_rrc_message_s {
int rrc_container_length;
} f1ap_ul_rrc_message_t;
/* [IAB] related structs */
typedef struct f1ap_bAPRoutingID_s{
uint16_t bAPAddress;
uint16_t bAPPathID;
}f1ap_bAPRoutingID_t;
typedef struct f1ap_EgressBHRLCCHItem_s{
uint16_t nextHopBAPAddress;
uint16_t bHRLCChannelID;
}f1ap_EgressBHRLCCHItem_t;
typedef struct f1ap_bHInfo_s{
f1ap_bAPRoutingID_t bAProutingID;
bool is_bAProutingID_set;
f1ap_EgressBHRLCCHItem_t *egressBHRLCCHList;
int egressList_length;
}f1ap_bHInfo_t;
/* [IAB] end*/
typedef struct f1ap_up_tnl_s {
in_addr_t tl_address; // currently only IPv4 supported
teid_t teid;
uint16_t port;
// [IAB] info
f1ap_bHInfo_t bh_info;
bool is_bh_info_set;
// ----------
} f1ap_up_tnl_t;
typedef enum preemption_capability_e {
@@ -356,6 +386,69 @@ typedef struct f1ap_srb_to_be_setup_s {
uint8_t lcid;
} f1ap_srb_to_be_setup_t;
/* [IAB] related structures -- */
typedef struct f1ap_iPHeaderInformation_s{
union DestinationIABTNLAddress{
in_addr_t iPv4Address;
// ipv6Address;
// ipv6Prefix;
} destinationIABTNLAddress;
enum {
ipv4Address,
ipv6Address,
ipv6Prefix
} destinationIABTNLAddress_type;
uint8_t *dsInformationList;
int infoList_length;
uint32_t iPv6FlowLabel;
}f1ap_iPHeaderInformation_t;
typedef struct f1ap_iPtolayer2TrafficMappingInfo_Item_s{
uint32_t mappingInformationIndex;
f1ap_iPHeaderInformation_t iPHeaderInformation;
f1ap_bHInfo_t bHInfo;
}f1ap_iPtolayer2TrafficMappingInfo_Item_t;
typedef struct f1ap_bAPlayerBHRLCchannelMappingInfo_Item_s{
uint32_t mappingInformationIndex;
uint16_t priorHopBAPAddress;
uint16_t ingressbHRLCChannelID;
uint16_t nextHopBAPAddress;
uint16_t egressbHRLCChannelID;
}f1ap_bAPlayerBHRLCchannelMappingInfo_Item_t;
typedef struct traffic_mapping_info_s{
union {
struct{
f1ap_iPtolayer2TrafficMappingInfo_Item_t *iPtolayer2TrafficMappingInfoToAdd;
int add_length;
uint32_t *iPtolayer2TrafficMappingInfoToRemove;
int remove_length;
}iPtolayer2TrafficMappingInfo;
struct{
f1ap_bAPlayerBHRLCchannelMappingInfo_Item_t *bAPlayerBHRLCchannelMappingInfoToAdd;
int add_length;
uint32_t *bAPlayerBHRLCchannelMappingInfoToRemove;
int remove_length;
}bAPlayerBHRLCchannelMappingInfo;
};
enum {
mapping_info_iPtolayer2TrafficMappingInfo,
mapping_info_bAPlayerBHRLCchannelMappingInfo
} type;
}traffic_mapping_info_t;
typedef struct f1ap_bhchannel_to_be_setup_s {
uint16_t bHRLCChannelID;
/* TODO: f1ap_qos_flow_level_qos_parameters_t bhch_qos; */
rlc_mode_t rlc_mode;
bool is_bap_Ctrl_PDU_Channel; // should be ENUMERATED {true, ...}
traffic_mapping_info_t trafficMappingInfo;
bool is_trafficMappingInfo_set;
} f1ap_bhchannel_to_be_setup_t;
/* -- [IAB] end of related structures */
typedef struct f1ap_rb_failed_to_be_setup_s {
long rb_id;
} f1ap_rb_failed_to_be_setup_t;
@@ -385,6 +478,7 @@ typedef struct du_to_cu_rrc_information_s {
typedef enum QoS_information_e {
NG_RAN_QoS = 0,
EUTRAN_QoS = 1,
bHRLCCH_QoS = 2,
} QoS_information_t;
typedef enum ReconfigurationCompl_e {
@@ -423,7 +517,43 @@ typedef struct f1ap_ue_context_setup_s {
ReconfigurationCompl_t ReconfigComplOutcome;
uint8_t *rrc_container;
int rrc_container_length;
} f1ap_ue_context_setup_t, f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t;
} f1ap_ue_context_setup_t;
typedef struct f1ap_ue_context_modif_req_s {
uint32_t gNB_CU_ue_id;
uint32_t gNB_DU_ue_id;
// SpCell Info
f1ap_plmn_t plmn;
uint64_t nr_cellid;
uint8_t servCellIndex;
uint8_t *cellULConfigured;
uint32_t servCellId;
cu_to_du_rrc_information_t *cu_to_du_rrc_information;
uint8_t cu_to_du_rrc_information_length;
//uint8_t *du_to_cu_rrc_information;
du_to_cu_rrc_information_t *du_to_cu_rrc_information;
uint32_t du_to_cu_rrc_information_length;
f1ap_drb_to_be_setup_t *drbs_to_be_setup;
uint8_t drbs_to_be_setup_length;
f1ap_drb_to_be_setup_t *drbs_to_be_modified;
uint8_t drbs_to_be_modified_length;
QoS_information_t QoS_information_type;
uint8_t drbs_failed_to_be_setup_length;
f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup;
f1ap_srb_to_be_setup_t *srbs_to_be_setup;
uint8_t srbs_to_be_setup_length;
uint8_t srbs_failed_to_be_setup_length;
uint8_t drbs_to_be_released_length;
f1ap_drb_to_be_released_t *drbs_to_be_released;
f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup;
ReconfigurationCompl_t ReconfigComplOutcome;
uint8_t *rrc_container;
int rrc_container_length;
// [IAB] BH RLC channels
f1ap_bhchannel_to_be_setup_t *bhchannels_to_be_setup;
uint8_t bhchannels_to_be_setup_length;
} f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t;
typedef enum F1ap_Cause_e {
F1AP_CAUSE_NOTHING, /* No components present */

File diff suppressed because it is too large Load Diff

View File

@@ -109,6 +109,12 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3
memcpy(req->gNB_DU_name, ie->value.choice.GNB_DU_Name.buf, ie->value.choice.GNB_DU_Name.size);
LOG_D(F1AP, "req->gNB_DU_name %s \n", req->gNB_DU_name);
}
/* BAPAddress*/
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_BAPAddress, false);
if(ie != NULL){
BIT_STRING_TO_NR_BAPADDRESS(&ie->value.choice.BAPAddress, req->bap_address);
LOG_D(F1AP, "req->bap_address %d \n", req->bap_address);
}
/* GNB_DU_Served_Cells_List */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List, true);
@@ -346,6 +352,16 @@ int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_set
os->buf[i] = f1ap_setup_resp->rrc_ver[i];
ie4->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p;
/* optional [IAB] */
/* c6. BAPAddress*/
if (f1ap_setup_resp->bap_address != 0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, bap_addr);
bap_addr->id = F1AP_ProtocolIE_ID_id_BAPAddress;
bap_addr->criticality = F1AP_Criticality_ignore;
bap_addr->value.present = F1AP_F1SetupResponseIEs__value_PR_BAPAddress;
NR_BAPADDRESS_TO_BIT_STRING(f1ap_setup_resp->bap_address, &bap_addr->value.choice.BAPAddress);
}
/* encode */
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 setup response\n");

View File

@@ -41,6 +41,20 @@
#include <openair3/ocp-gtpu/gtp_itf.h>
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "F1AP_BAPlayerBHRLCchannelMappingInfo.h"
#include "F1AP_BAPlayerBHRLCchannelMappingInfo-Item.h"
#include "F1AP_IPtolayer2TrafficMappingInfo.h"
#include "F1AP_IPtolayer2TrafficMappingInfoList.h"
#include "F1AP_IPtolayer2TrafficMappingInfo-Item.h"
#include "F1AP_DSCP.h"
#include "F1AP_DSInformationList.h"
#include "F1AP_EgressBHRLCCHItem.h"
#include "F1AP_EgressBHRLCCHList.h"
#include "F1AP_MappingInformationIndex.h"
#include "F1AP_MappingInformationtoRemove.h"
#include "F1AP_BAPlayerBHRLCchannelMappingInfoList.h"
#include "F1AP_ProtocolExtensionContainer.h"
static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill)
{
asn1cCalloc(*toFill, tmp);
@@ -1444,12 +1458,36 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel,
gTPTunnel);
/* 12.3.1.1.1 transportLayerAddress */
/* 12.1.3.1.1.1 transportLayerAddress */
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address,
&gTPTunnel->transportLayerAddress);
/* 12.3.1.1.2 gTP_TEID */
/* 12.1.3.1.1.2 gTP_TEID */
INT32_TO_OCTET_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid,
&gTPTunnel->gTP_TEID);
/* 12.1.3.2 BHInfo [IAB] */
if(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].is_bh_info_set){
f1ap_bHInfo_t *bh_info = &f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].bh_info;
asn1cSequenceAdd(uLUPTNLInformation_ToBeSetup_Item->iE_Extensions, F1AP_ULUPTNLInformation_ToBeSetup_ItemExtIEs_t, ulupinfo_ie);
ulupinfo_ie->id = F1AP_ProtocolIE_ID_id_BHInfo;
ulupinfo_ie->criticality = F1AP_Criticality_ignore;
ulupinfo_ie->extensionValue.present = F1AP_ULUPTNLInformation_ToBeSetup_ItemExtIEs__extensionValue_PR_BHInfo;
F1AP_BHInfo_t *Bhinfo = &ulupinfo_ie->extensionValue.choice.BHInfo;
if(bh_info->is_bAProutingID_set){
Bhinfo->bAProutingID = calloc(1, sizeof(F1AP_BAPRoutingID_t));
NR_BAPADDRESS_TO_BIT_STRING(bh_info->bAProutingID.bAPAddress, &Bhinfo->bAProutingID->bAPAddress);
NR_BAPPATHID_TO_BIT_STRING(bh_info->bAProutingID.bAPPathID, &Bhinfo->bAProutingID->bAPPathID);
}
if(bh_info->egressList_length > 0){
Bhinfo->egressBHRLCCHList = calloc(bh_info->egressList_length, sizeof(F1AP_EgressBHRLCCHItem_t));
for(int k = 0; k < bh_info->egressList_length; k++){
asn1cSequenceAdd(Bhinfo->egressBHRLCCHList->list, F1AP_EgressBHRLCCHItem_t, egressLink);
NR_BAPADDRESS_TO_BIT_STRING(bh_info->egressBHRLCCHList[k].nextHopBAPAddress, &egressLink->nextHopBAPAddress);
NR_BHRLCCHANNELID_TO_BIT_STRING(bh_info->egressBHRLCCHList[k].bHRLCChannelID, &egressLink->bHRLCChannelID);
}
}
}
}
/* 12.1.4 rLCMode */
/* TODO use rlc_mode from f1ap_drb_to_be_setup */
@@ -1575,6 +1613,198 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
}
}
/*
[IAB]
c.31 BH_RLC_ChannelToBeSetup_List
31 (31 is the position it occupies in the message TS)
*/
if (f1ap_ue_context_modification_req->bhchannels_to_be_setup_length > 0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie31);
ie31->id = F1AP_ProtocolIE_ID_id_BHChannels_ToBeSetupMod_List;
ie31->criticality = F1AP_Criticality_reject;
ie31->value.present = F1AP_UEContextModificationRequestIEs__value_PR_BHChannels_ToBeSetupMod_List;
for (int i = 0; i < f1ap_ue_context_modification_req->bhchannels_to_be_setup_length; i++) {
asn1cSequenceAdd(ie31->value.choice.BHChannels_ToBeSetupMod_List.list,
F1AP_BHChannels_ToBeSetupMod_ItemIEs_t, bhchs_toBeSetupMod_item_ies);
bhchs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_BHChannels_ToBeSetupMod_Item;
bhchs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject;
bhchs_toBeSetupMod_item_ies->value.present = F1AP_BHChannels_ToBeSetupMod_ItemIEs__value_PR_BHChannels_ToBeSetupMod_Item;
/* 31.1 BHChannels_ToBeSetupMod_Item */
F1AP_BHChannels_ToBeSetupMod_Item_t *bhchs_toBeSetupMod_item=
&bhchs_toBeSetupMod_item_ies->value.choice.BHChannels_ToBeSetupMod_Item;
/* 31.1.1 bHRLCChannelID */
NR_BHRLCCHANNELID_TO_BIT_STRING(f1ap_ue_context_modification_req->bhchannels_to_be_setup[i].bHRLCChannelID,
&bhchs_toBeSetupMod_item->bHRLCChannelID);
/* 31.1.2 bHQoSInformation CHOICE*/
if(f1ap_ue_context_modification_req->QoS_information_type == bHRLCCH_QoS){
/* bHRLCCHQoS */
/*
bhchs_toBeSetupMod_item->bHQoSInformation.present = F1AP_BHQoSInformation_PR_bHRLCCHQoS;
bhchs_toBeSetupMod_item->bHQoSInformation.choice.bHRLCCHQoS = (F1AP_QoSFlowLevelQoSParameters_t *)calloc(1, sizeof(F1AP_QoSFlowLevelQoSParameters_t));
bhchs_toBeSetupMod_item->bHQoSInformation.choice.bHRLCCHQoS->
*/
}else if (f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){
/* EUTRAN_QoS */
}else{
/* cPTrafficType */
bhchs_toBeSetupMod_item->bHQoSInformation.present = F1AP_BHQoSInformation_PR_cPTrafficType;
bhchs_toBeSetupMod_item->bHQoSInformation.choice.cPTrafficType = 1; // integer (hardcoded for now)
}
/* 31.1.3 rLCmode */
bhchs_toBeSetupMod_item->rLCmode = f1ap_ue_context_modification_req->bhchannels_to_be_setup[i].rlc_mode;
/* 31.1.4 bAPCtrlPDUChannel */
if(f1ap_ue_context_modification_req->bhchannels_to_be_setup[i].is_bap_Ctrl_PDU_Channel == true){ // 1 being true
bhchs_toBeSetupMod_item->bAPCtrlPDUChannel = calloc(1, sizeof(F1AP_BAPCtrlPDUChannel_t));
bhchs_toBeSetupMod_item->bAPCtrlPDUChannel = F1AP_BAPCtrlPDUChannel_true;
}
/* 31.1.5 trafficMappingInfo */
if(f1ap_ue_context_modification_req->bhchannels_to_be_setup[i].is_trafficMappingInfo_set){
LOG_I(F1AP, "Mapping Info triggered\n");
bhchs_toBeSetupMod_item->trafficMappingInfo = calloc(1, sizeof(F1AP_TrafficMappingInfo_t));
traffic_mapping_info_t traffic_mapping_info = f1ap_ue_context_modification_req->bhchannels_to_be_setup[i].trafficMappingInfo;
// iPtolayer2TrafficMappingInfo
if (traffic_mapping_info.type == mapping_info_iPtolayer2TrafficMappingInfo){
bhchs_toBeSetupMod_item->trafficMappingInfo->present = F1AP_TrafficMappingInfo_PR_iPtolayer2TrafficMappingInfo;
asn1cCalloc(bhchs_toBeSetupMod_item->trafficMappingInfo->choice.iPtolayer2TrafficMappingInfo, iPToL2Info);
if(traffic_mapping_info.iPtolayer2TrafficMappingInfo.add_length > 0){
// Should I use .list here?
iPToL2Info->iPtolayer2TrafficMappingInfoToAdd = calloc(1, sizeof(F1AP_IPtolayer2TrafficMappingInfoList_t));
f1ap_iPtolayer2TrafficMappingInfo_Item_t this_ip2l2_item;
for(i=0; i < traffic_mapping_info.iPtolayer2TrafficMappingInfo.add_length; i++){
this_ip2l2_item = traffic_mapping_info.iPtolayer2TrafficMappingInfo.iPtolayer2TrafficMappingInfoToAdd[i];
asn1cSequenceAdd(iPToL2Info->iPtolayer2TrafficMappingInfoToAdd->list, F1AP_IPtolayer2TrafficMappingInfo_Item_t, iPToL2Item);
// mappingInformationIndex
NR_MAPPINGINFORMATIONINDEX_TO_BIT_STRING(this_ip2l2_item.mappingInformationIndex, &iPToL2Item->mappingInformationIndex);
// iPHeaderInformation
/* Only IPv4 implemented for now,
missing IPv6 address and IPv6 prefix */
if(this_ip2l2_item.iPHeaderInformation.destinationIABTNLAddress_type == ipv4Address){
iPToL2Item->iPHeaderInformation.destinationIABTNLAddress.present = F1AP_IABTNLAddress_PR_iPv4Address;
IABTNL_ADRESS_IPv4_TO_BIT_STRING(this_ip2l2_item.iPHeaderInformation.destinationIABTNLAddress.iPv4Address,
&iPToL2Item->iPHeaderInformation.destinationIABTNLAddress.choice.iPv4Address);
}
if(this_ip2l2_item.iPHeaderInformation.infoList_length > 0){
iPToL2Item->iPHeaderInformation.dsInformationList = calloc(this_ip2l2_item.iPHeaderInformation.infoList_length, sizeof(F1AP_DSCP_t));
for(int j = 0; j < this_ip2l2_item.iPHeaderInformation.infoList_length; j++){
asn1cSequenceAdd(iPToL2Item->iPHeaderInformation.dsInformationList->list, F1AP_DSCP_t, dscp);
// Not sure if this is correct
DSCP_TO_BIT_STRING(this_ip2l2_item.iPHeaderInformation.dsInformationList[j], &(*dscp));
}
}
/*
if(this_ip2l2_item.iPHeaderInformation.iPv6FlowLabel != NULL){
// TODO
}
*/
//bhInfo
if(this_ip2l2_item.bHInfo.is_bAProutingID_set){
iPToL2Item->bHInfo.bAProutingID = calloc(1, sizeof(F1AP_BAPRoutingID_t));
NR_BAPADDRESS_TO_BIT_STRING(this_ip2l2_item.bHInfo.bAProutingID.bAPAddress, &iPToL2Item->bHInfo.bAProutingID->bAPAddress);
NR_BAPPATHID_TO_BIT_STRING(this_ip2l2_item.bHInfo.bAProutingID.bAPPathID, &iPToL2Item->bHInfo.bAProutingID->bAPPathID);
}
if(this_ip2l2_item.bHInfo.egressList_length > 0){
iPToL2Item->bHInfo.egressBHRLCCHList = calloc(this_ip2l2_item.bHInfo.egressList_length, sizeof(F1AP_EgressBHRLCCHItem_t));
for(int j = 0; j < this_ip2l2_item.bHInfo.egressList_length; j++){
asn1cSequenceAdd(iPToL2Item->bHInfo.egressBHRLCCHList->list, F1AP_EgressBHRLCCHItem_t, egressLink);
NR_BAPADDRESS_TO_BIT_STRING(this_ip2l2_item.bHInfo.egressBHRLCCHList[j].nextHopBAPAddress, &egressLink->nextHopBAPAddress);
NR_BHRLCCHANNELID_TO_BIT_STRING(this_ip2l2_item.bHInfo.egressBHRLCCHList[j].bHRLCChannelID, &egressLink->bHRLCChannelID);
}
}
}
}
if(traffic_mapping_info.iPtolayer2TrafficMappingInfo.remove_length > 0){
iPToL2Info->iPtolayer2TrafficMappingInfoToRemove = calloc(traffic_mapping_info.iPtolayer2TrafficMappingInfo.remove_length, sizeof(F1AP_MappingInformationIndex_t));
for(int i = 0; i < traffic_mapping_info.iPtolayer2TrafficMappingInfo.remove_length; i++){
asn1cSequenceAdd(iPToL2Info->iPtolayer2TrafficMappingInfoToRemove->list, F1AP_MappingInformationIndex_t, iPToL2RemoveIndex);
NR_MAPPINGINFORMATIONINDEX_TO_BIT_STRING(traffic_mapping_info.iPtolayer2TrafficMappingInfo.iPtolayer2TrafficMappingInfoToRemove[i],
&(*iPToL2RemoveIndex));
}
}
}
// bAPlayerBHRLCchannelMappingInfo
else if (traffic_mapping_info.type == mapping_info_bAPlayerBHRLCchannelMappingInfo){
bhchs_toBeSetupMod_item->trafficMappingInfo->present = F1AP_TrafficMappingInfo_PR_bAPlayerBHRLCchannelMappingInfo;
asn1cCalloc(bhchs_toBeSetupMod_item->trafficMappingInfo->choice.bAPlayerBHRLCchannelMappingInfo, bapBHInfo);
if(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.add_length > 0){
bapBHInfo->bAPlayerBHRLCchannelMappingInfoToAdd = calloc(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.add_length, sizeof(F1AP_BAPlayerBHRLCchannelMappingInfo_Item_t));
for(i=0; i < traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.add_length; i++){
asn1cSequenceAdd(bapBHInfo->bAPlayerBHRLCchannelMappingInfoToAdd->list, F1AP_BAPlayerBHRLCchannelMappingInfo_Item_t, bapBHItem);
NR_MAPPINGINFORMATIONINDEX_TO_BIT_STRING(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].mappingInformationIndex,
&bapBHItem->mappingInformationIndex );
// Won't use value 0 for IDs, meaning that 0 will be the value used for "not set"
if(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].priorHopBAPAddress == 0){
bapBHItem->priorHopBAPAddress = calloc(1, sizeof(F1AP_BAPAddress_t));
NR_BAPADDRESS_TO_BIT_STRING(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].priorHopBAPAddress,
&(*bapBHItem->priorHopBAPAddress));
}
if(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].ingressbHRLCChannelID == 0){
bapBHItem->ingressbHRLCChannelID = calloc(1, sizeof(F1AP_BHRLCChannelID_t));
NR_BHRLCCHANNELID_TO_BIT_STRING(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].ingressbHRLCChannelID,
&(*bapBHItem->ingressbHRLCChannelID));
}
if(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].nextHopBAPAddress == 0){
bapBHItem->nextHopBAPAddress = calloc(1, sizeof(F1AP_BAPAddress_t));
NR_BAPADDRESS_TO_BIT_STRING(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].nextHopBAPAddress,
&(*bapBHItem->nextHopBAPAddress));
}
if(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].egressbHRLCChannelID == 0){
bapBHItem->egressbHRLCChannelID = calloc(1, sizeof(F1AP_BHRLCChannelID_t));
NR_BHRLCCHANNELID_TO_BIT_STRING(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToAdd[i].egressbHRLCChannelID,
&(*bapBHItem->egressbHRLCChannelID));
}
}
}
if(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.remove_length > 0){
bapBHInfo->bAPlayerBHRLCchannelMappingInfoToRemove = calloc(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.remove_length, sizeof(F1AP_MappingInformationIndex_t));
for(int i = 0; i < traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.remove_length; i++){
asn1cSequenceAdd(bapBHInfo->bAPlayerBHRLCchannelMappingInfoToRemove->list, F1AP_MappingInformationIndex_t, bapBHRemoveIndex);
NR_MAPPINGINFORMATIONINDEX_TO_BIT_STRING(traffic_mapping_info.bAPlayerBHRLCchannelMappingInfo.bAPlayerBHRLCchannelMappingInfoToRemove[i],
&(*bapBHRemoveIndex));
}
}
}
/*
...
*/
}
}
}
/* [IAB] end */
/* encode */
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n");
@@ -1596,118 +1826,118 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t
container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse;
int i;
/* GNB_CU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
/* GNB_CU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
LOG_D(F1AP, "f1ap_ue_context_modif_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id);
LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id);
/* GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
f1ap_ue_context_modification_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
/* GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
f1ap_ue_context_modification_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id);
LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id);
// DUtoCURRCInformation
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1, sizeof(du_to_cu_rrc_information_t));
f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
// DUtoCURRCInformation
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1, sizeof(du_to_cu_rrc_information_t));
f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
memcpy(f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size;
memcpy(f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size);
f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size;
}
// DRBs_SetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->drbs_to_be_setup_length = ie->value.choice.DRBs_SetupMod_List.list.count;
f1ap_ue_context_modification_resp->drbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_to_be_setup_length,
sizeof(f1ap_drb_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->drbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->drbs_to_be_setup_length; ++i) {
f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_to_be_setup[i];
F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item_p;
drbs_setupmod_item_p = &((F1AP_DRBs_SetupMod_ItemIEs_t *)ie->value.choice.DRBs_SetupMod_List.list.array[i])->value.choice.DRBs_SetupMod_Item;
drb_p->drb_id = drbs_setupmod_item_p->dRBID;
// TODO in the following, assume only one UP UL TNL is present.
// this matches/assumes OAI CU/DU implementation, can be up to 2!
drb_p->up_dl_tnl_length = 1;
AssertFatal(drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.count > 0,
"no DL UP TNL Information in DRBs to be Setup list\n");
F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0];
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst,
f1ap_ue_context_modification_resp->gNB_CU_ue_id,
(ebi_t)drbs_setupmod_item_p->dRBID,
drb_p->up_dl_tnl[0].tl_address,
drb_p->up_dl_tnl[0].teid);
}
}
// SRBs_FailedToBeSetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length = ie->value.choice.SRBs_FailedToBeSetupMod_List.list.count;
f1ap_ue_context_modification_resp->srbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length,
sizeof(f1ap_rb_failed_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->srbs_failed_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length; ++i) {
f1ap_rb_failed_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_failed_to_be_setup[i];
srb_p->rb_id = ((F1AP_SRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.SRBs_FailedToBeSetupMod_List.list.array[i])->sRBID;
}
// DRBs_SetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->drbs_to_be_setup_length = ie->value.choice.DRBs_SetupMod_List.list.count;
f1ap_ue_context_modification_resp->drbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_to_be_setup_length,
sizeof(f1ap_drb_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->drbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->drbs_to_be_setup_length; ++i) {
f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_to_be_setup[i];
F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item_p;
drbs_setupmod_item_p = &((F1AP_DRBs_SetupMod_ItemIEs_t *)ie->value.choice.DRBs_SetupMod_List.list.array[i])->value.choice.DRBs_SetupMod_Item;
drb_p->drb_id = drbs_setupmod_item_p->dRBID;
// TODO in the following, assume only one UP UL TNL is present.
// this matches/assumes OAI CU/DU implementation, can be up to 2!
drb_p->up_dl_tnl_length = 1;
AssertFatal(drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.count > 0,
"no DL UP TNL Information in DRBs to be Setup list\n");
F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0];
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst,
f1ap_ue_context_modification_resp->gNB_CU_ue_id,
(ebi_t)drbs_setupmod_item_p->dRBID,
drb_p->up_dl_tnl[0].tl_address,
drb_p->up_dl_tnl[0].teid);
}
}
// DRBs_FailedToBeSetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length = ie->value.choice.DRBs_FailedToBeSetupMod_List.list.count;
f1ap_ue_context_modification_resp->drbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length,
sizeof(f1ap_rb_failed_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->drbs_failed_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length; ++i) {
f1ap_rb_failed_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_failed_to_be_setup[i];
drb_p->rb_id = ((F1AP_DRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.DRBs_FailedToBeSetupMod_List.list.array[i])->dRBID;
}
// SRBs_FailedToBeSetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length = ie->value.choice.SRBs_FailedToBeSetupMod_List.list.count;
f1ap_ue_context_modification_resp->srbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length,
sizeof(f1ap_rb_failed_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->srbs_failed_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length; ++i) {
f1ap_rb_failed_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_failed_to_be_setup[i];
srb_p->rb_id = ((F1AP_SRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.SRBs_FailedToBeSetupMod_List.list.array[i])->sRBID;
}
}
}
// DRBs_FailedToBeSetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length = ie->value.choice.DRBs_FailedToBeSetupMod_List.list.count;
f1ap_ue_context_modification_resp->drbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length,
sizeof(f1ap_rb_failed_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->drbs_failed_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length; ++i) {
f1ap_rb_failed_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_failed_to_be_setup[i];
drb_p->rb_id = ((F1AP_DRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.DRBs_FailedToBeSetupMod_List.list.array[i])->dRBID;
}
}
// SCell_FailedtoSetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List, false);
if(ie!=NULL){
LOG_E (F1AP, "Not supporting handling of SCell_FailedtoSetupMod_List \n");
}
// SCell_FailedtoSetupMod_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List, false);
if(ie!=NULL){
LOG_E (F1AP, "Not supporting handling of SCell_FailedtoSetupMod_List \n");
// SRBs_Setup_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->srbs_to_be_setup_length = ie->value.choice.SRBs_SetupMod_List.list.count;
f1ap_ue_context_modification_resp->srbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_to_be_setup_length,
sizeof(f1ap_srb_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->srbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->srbs_to_be_setup_length; ++i) {
f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_to_be_setup[i];
F1AP_SRBs_SetupMod_Item_t *srbs_setup_item_p;
srbs_setup_item_p = &((F1AP_SRBs_SetupMod_ItemIEs_t *)ie->value.choice.SRBs_SetupMod_List.list.array[i])->value.choice.SRBs_SetupMod_Item;
srb_p->srb_id = srbs_setup_item_p->sRBID;
srb_p->lcid = srbs_setup_item_p->lCID;
}
}
// SRBs_Setup_List
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List, false);
if(ie!=NULL){
f1ap_ue_context_modification_resp->srbs_to_be_setup_length = ie->value.choice.SRBs_SetupMod_List.list.count;
f1ap_ue_context_modification_resp->srbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_to_be_setup_length,
sizeof(f1ap_srb_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_resp->srbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n");
for (i = 0; i < f1ap_ue_context_modification_resp->srbs_to_be_setup_length; ++i) {
f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_to_be_setup[i];
F1AP_SRBs_SetupMod_Item_t *srbs_setup_item_p;
srbs_setup_item_p = &((F1AP_SRBs_SetupMod_ItemIEs_t *)ie->value.choice.SRBs_SetupMod_List.list.array[i])->value.choice.SRBs_SetupMod_Item;
srb_p->srb_id = srbs_setup_item_p->sRBID;
srb_p->lcid = srbs_setup_item_p->lCID;
}
}
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
return 0;
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
return 0;
}
int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)

View File

@@ -36,6 +36,7 @@
#include "f1ap_du_interface_management.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
#include "assertions.h"
#include "openair2/LAYER2/BAP/bap_oai_api.h"
#include "GNB_APP/gnb_paramdef.h"
@@ -316,6 +317,16 @@ int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req)
for (int i = 0; i < 3; ++i)
os->buf[i] = setup_req->rrc_ver[i];
ie2->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)p;
/* optional */
/* c6. BAPAddress*/
if (setup_req->bap_address != 0) {
asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, bap_addr);
bap_addr->id = F1AP_ProtocolIE_ID_id_BAPAddress;
bap_addr->criticality = F1AP_Criticality_ignore;
bap_addr->value.present = F1AP_F1SetupRequestIEs__value_PR_BAPAddress;
NR_BAPADDRESS_TO_BIT_STRING(setup_req->bap_address, &bap_addr->value.choice.BAPAddress);
}
/* encode */
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
@@ -370,6 +381,16 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint
LOG_D(F1AP, "F1AP: F1Setup-Resp: gNB_CU_name %s\n", resp.gNB_CU_name);
break;
case F1AP_ProtocolIE_ID_id_BAPAddress:
AssertFatal(ie->criticality == F1AP_Criticality_ignore,
"ie->criticality != F1AP_Criticality_ignore\n");
AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_BAPAddress,
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_BAPAddress\n");
BIT_STRING_TO_NR_BAPADDRESS(&ie->value.choice.BAPAddress, resp.bap_address);
LOG_D(F1AP, "F1AP: F1Setup-Resp: BAPAddress %d\n", resp.bap_address);
init_bap_entity(resp.bap_address, true);
break;
case F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version:
AssertFatal(ie->criticality == F1AP_Criticality_reject,
"ie->criticality != F1AP_Criticality_reject\n");

View File

@@ -102,6 +102,7 @@ void *F1AP_DU_task(void *arg) {
instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg);
sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->du.assoc_id : 0;
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);
LOG_D(F1AP, "Current Received message %d\n", msg->ittiMsgHeader.messageId);
switch (ITTI_MSG_ID(msg)) {
case F1AP_SETUP_REQ:
AssertFatal(false, "the F1AP_SETUP_REQ should not be received; use the F1AP_DU_REGISTER_REQ instead\n");

View File

@@ -1074,6 +1074,50 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
}
}
/* [IAB] related params */
F1AP_UEContextModificationRequestIEs_t *ieBhrlc;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieBhrlc, container,
F1AP_ProtocolIE_ID_id_BHChannels_ToBeSetupMod_List, false);
if(ieBhrlc != NULL){
f1ap_ue_context_modification_req->bhchannels_to_be_setup_length = ieBhrlc->value.choice.BHChannels_ToBeSetupMod_List.list.count;
f1ap_ue_context_modification_req->bhchannels_to_be_setup = calloc(f1ap_ue_context_modification_req->bhchannels_to_be_setup_length,
sizeof(f1ap_bhchannel_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_req->bhchannels_to_be_setup,
"could not allocate memory for f1ap_ue_context_modification_req->bhchannels_to_be_setup\n");
for(i = 0; i < f1ap_ue_context_modification_req->bhchannels_to_be_setup_length; i++){
f1ap_bhchannel_to_be_setup_t *bhrlc_p = &f1ap_ue_context_modification_req->bhchannels_to_be_setup[i];
F1AP_BHChannels_ToBeSetupMod_Item_t *bhrlc_tobesetupmod_item_p =
&((F1AP_BHChannels_ToBeSetupMod_ItemIEs_t *)ieBhrlc->value.choice.BHChannels_ToBeSetupMod_List.list.array[i])->value.choice.BHChannels_ToBeSetupMod_Item;
BIT_STRING_TO_NR_BHRLCCHANNELID(&bhrlc_tobesetupmod_item_p->bHRLCChannelID, bhrlc_p->bHRLCChannelID);
switch (bhrlc_tobesetupmod_item_p->rLCmode) {
case F1AP_RLCMode_rlc_am:
bhrlc_p->rlc_mode = RLC_MODE_AM;
break;
/*
case F1AP_RLCMode_rlc_um:
bhrlc_p->rlc_mode = RLC_MODE_UM;
*/
default:
bhrlc_p->rlc_mode = RLC_MODE_TM;
break;
}
if(bhrlc_tobesetupmod_item_p->bAPCtrlPDUChannel == F1AP_BAPCtrlPDUChannel_true){
bhrlc_p->is_bap_Ctrl_PDU_Channel = true;
}
if(bhrlc_tobesetupmod_item_p->trafficMappingInfo != NULL){
bhrlc_p->is_trafficMappingInfo_set = true;
// TODO: Traffic mapping info configurations
}else{
bhrlc_p->is_trafficMappingInfo_set = false;
}
}
}
/* [IAB] end */
ue_context_modification_request(f1ap_ue_context_modification_req);
return 0;
}

View File

@@ -91,6 +91,7 @@
#include "RRC/NR/nr_rrc_extern.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/LAYER2/BAP/bap_oai_api.h"
extern uint16_t sf_ahead;
@@ -707,7 +708,9 @@ void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type)
verify_section_notset(cfg, GNB_CONFIG_STRING_GNB_LIST ".", GNB_CONFIG_STRING_AMF_IP_ADDRESS);
verify_section_notset(cfg, NULL, CONFIG_STRING_SECURITY);
} // else nothing to be checked
} // Maybe add new things for Node_DU and Donor_DU in the future
// else nothing to be checked
/* other possible verifications: PNF, VNF, CU-CP, CU-UP, ...? */
}
@@ -1035,6 +1038,7 @@ static NR_ServingCellConfig_t *get_scd_config(configmodule_interface_t *cfg)
static int read_du_cell_info(configmodule_interface_t *cfg,
bool separate_du,
/*bool separate_iab_du,*/
uint32_t *gnb_id,
uint64_t *gnb_du_id,
char **name,
@@ -1078,7 +1082,13 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
if (separate_du) {
AssertFatal(config_isparamset(GNBParamList.paramarray[0], GNB_GNB_DU_ID_IDX), "%s is not defined in configuration file\n", GNB_CONFIG_STRING_GNB_DU_ID);
*gnb_du_id = *GNBParamList.paramarray[0][GNB_GNB_DU_ID_IDX].u64ptr;
} else {
}
/*else if (separate_iab_du) {
AssertFatal(config_isparamset(GNBParamList.paramarray[0], GNB_GNB_DU_ID_IDX), "%s is not defined in configuration file\n", GNB_CONFIG_STRING_GNB_DU_ID);
*gnb_du_id = *GNBParamList.paramarray[0][GNB_GNB_DU_ID_IDX].u64ptr;
*bap_address = *GNBParamList.paramarray[0][GNB_BAP_ADDRESS_IDX].u16ptr;
}*/ else {
AssertFatal(!config_isparamset(GNBParamList.paramarray[0], GNB_GNB_DU_ID_IDX),
"%s should not be defined in configuration file for monolithic gNB\n",
GNB_CONFIG_STRING_GNB_DU_ID);
@@ -1103,8 +1113,10 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
return 1;
}
static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
static f1ap_setup_req_t *RC_read_F1Setup(/*bool is_iab_du,*/
uint64_t id,
const char *name,
/*uint16_t bap_address,*/
const f1ap_served_cell_info_t *info,
const NR_ServingCellConfigCommon_t *scc,
NR_BCCH_BCH_Message_t *mib,
@@ -1114,18 +1126,39 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
AssertFatal(req != NULL, "out of memory\n");
req->gNB_DU_id = id;
req->gNB_DU_name = strdup(name);
/*if(is_iab_du){
req->bap_address = bap_address;
}*/
req->num_cells_available = 1;
req->cell[0].info = *info;
LOG_I(GNB_APP,
"F1AP: gNB idx %d gNB_DU_id %ld, gNB_DU_name %s, TAC %d MCC/MNC/length %d/%d/%d cellID %ld\n",
/*if (is_iab_du){
LOG_I(GNB_APP,
"F1AP: gNB idx %d gNB_DU_id %ld, gNB_DU_name %s, bap_address %d, TAC %d MCC/MNC/length %d/%d/%d cellID %ld\n",
0,
req->gNB_DU_id,
req->gNB_DU_name,
req->bap_address,
*req->cell[0].info.tac,
req->cell[0].info.plmn.mcc,
req->cell[0].info.plmn.mnc,
req->cell[0].info.plmn.mnc_digit_length,
req->cell[0].info.nr_cellid);
LOG_I(GNB_APP, "F1AP: Initializing BAP layer\n");
bool is_du = true;
nr_bap_layer_init(is_du);
*/
LOG_I(GNB_APP,
"F1AP: gNB idx %d gNB_DU_id %ld, gNB_DU_name %s, TAC %d MCC/MNC/length %d/%d/%d cellID %ld\n",
0,
req->gNB_DU_id,
req->gNB_DU_name,
*req->cell[0].info.tac,
req->cell[0].info.plmn.mcc,
req->cell[0].info.plmn.mnc,
req->cell[0].info.plmn.mnc_digit_length,
req->cell[0].info.nr_cellid);
req->cell[0].info.nr_pci = *scc->physCellId;
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
@@ -1327,7 +1360,9 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
uint64_t gnb_du_id = 0;
uint32_t gnb_id = 0;
char *name = NULL;
// uint16_t bap_address = 0;
f1ap_served_cell_info_t info;
// read_du_cell_info(cfg, NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &bap_address, &info, 1);
read_du_cell_info(cfg, NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1);
if (get_softmodem_params()->sa)
@@ -1337,6 +1372,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
// and store it at MAC for sending later
NR_BCCH_BCH_Message_t *mib = RC.nrmac[0]->common_channels[0].mib;
const NR_BCCH_DL_SCH_Message_t *sib1 = RC.nrmac[0]->common_channels[0].sib1;
//f1ap_setup_req_t *req = RC_read_F1Setup(NODE_IS_DU_IAB(node_type), gnb_du_id, name, bap_address, &info, scc, mib, sib1);
f1ap_setup_req_t *req = RC_read_F1Setup(gnb_du_id, name, &info, scc, mib, sib1);
AssertFatal(req != NULL, "could not read F1 Setup information\n");
RC.nrmac[0]->f1_config.setup_req = req;
@@ -2254,7 +2290,13 @@ ngran_node_t get_node_type(void)
RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt;
for (int j = 0; j < RC.nb_nr_macrlc_inst; j++) {
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
return ngran_gNB_DU; // MACRLCs present in config: it must be a DU
if (strstr(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr), "Node") != NULL){
return ngran_gNB_IAB_node_DU;
} else if (strstr(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr), "Donor") != NULL){
return ngran_gNB_IAB_donor_DU;
}else{
return ngran_gNB_DU;
}
}
}
}

View File

@@ -103,6 +103,7 @@ typedef enum {
#define GNB_CONFIG_STRING_GNB_ID "gNB_ID"
#define GNB_CONFIG_STRING_CELL_TYPE "cell_type"
#define GNB_CONFIG_STRING_GNB_NAME "gNB_name"
#define GNB_CONFIG_STRING_BAP_ADDRESS "bap_address"
#define GNB_CONFIG_STRING_TRACKING_AREA_CODE "tracking_area_code"
#define GNB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD "mobile_country_code"
#define GNB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD "mobile_network_code"
@@ -173,6 +174,7 @@ typedef enum {
{GNB_CONFIG_STRING_DRBS, GNB_CONFIG_HLP_STRING_DRBS, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_GNB_DU_ID, GNB_CONFIG_HLP_GNB_DU_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \
{GNB_CONFIG_STRING_GNB_CU_UP_ID, GNB_CONFIG_HLP_GNB_CU_UP_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \
{GNB_CONFIG_STRING_BAP_ADDRESS, NULL, 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \
}
// clang-format on
@@ -205,8 +207,10 @@ typedef enum {
#define GNB_FORCE256QAMOFF_IDX 25
#define GNB_ENABLE_SDAP_IDX 26
#define GNB_DRBS 27
#define GNB_GNB_DU_ID_IDX 28
#define GNB_GNB_CU_UP_ID_IDX 29
#define GNB_GNB_DU_ID_IDX 28
#define GNB_GNB_CU_UP_ID_IDX 29
// [IAB] bap_address
#define GNB_BAP_ADDRESS_IDX 30
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define GNBPARAMS_CHECK { \

View File

@@ -0,0 +1,17 @@
#include "bap_entity.h"
bap_entity_t *new_bap_entity(uint16_t bap_address, bool is_du){
bap_entity_t *ret;
ret = calloc(1, sizeof(bap_entity_t));
if (ret == NULL) {
// Change to BAP log
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (pthread_mutex_init(&ret->lock, NULL)) abort();
ret->is_du = is_du;
ret->bap_address = bap_address;
return (bap_entity_t *)ret;
}

View File

@@ -0,0 +1,34 @@
#include <stdint.h>
#include <pthread.h>
typedef struct{
uint16_t bap_address;
uint16_t bap_path_id;
}bap_routing_id_t;
typedef struct{
uint16_t priorHop_bap_address;
uint16_t ingress_bhch_ID;
uint16_t nextHop_bap_address;
uint16_t egress_bhch_ID;
} bap_bhch_mapping_info_t;
typedef struct bap_entity_t{
pthread_mutex_t lock;
bool is_du; // true if DU, false if MT
uint16_t bap_address;
bap_routing_id_t defaultUL_bap_routing_id;
uint16_t befaultUL_bh_rlc_channel_id;
enum{
PER_BH_RLC_Channel,
PER_ROUTING_ID,
BOTH
}flow_control_feedback_type;
// From BAPlayerBHRLCchannelMappingInfo
// Use mappingInformationIndex to navigate the list
bap_bhch_mapping_info_t *bhch_mapping_info_list;
}bap_entity_t;
bap_entity_t *new_bap_entity(uint16_t bap_address, bool is_du);

View File

@@ -0,0 +1,223 @@
/* from openair */
#include "rlc.h"
/* from nr rlc module */
#include "openair2/LAYER2/nr_rlc/nr_rlc_asn1_utils.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "NR_RLC-BearerConfig.h"
#include "NR_DRB-ToAddMod.h"
#include "NR_DRB-ToAddModList.h"
#include "NR_SRB-ToAddModList.h"
#include "NR_DRB-ToReleaseList.h"
#include "NR_CellGroupConfig.h"
#include "NR_RLC-Config.h"
#include "common/ran_context.h"
#include "NR_UL-CCCH-Message.h"
#include "conversions.h"
#include "bap_oai_api.h"
// Having trouble changing this to .h
#include "bap_entity.c"
extern RAN_CONTEXT_t RC;
#include <executables/softmodem-common.h>
static bap_entity_t *bap_entity;
// Same as RLC?
static void deliver_bap_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
{
// TODO
}
static void successful_bap_delivery(void *_ue, nr_rlc_entity_t *entity, int sdu_id)
{
// TODO
}
static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity){
// TODO
}
static void add_bhch_um(int rnti, int bhch_id, const NR_BH_RLC_ChannelConfig_r16_t *rlc_bhchConfig)
{
struct NR_RLC_Config *r = rlc_bhchConfig->rlc_Config_r16;
int sn_field_length;
int t_reassembly;
AssertFatal(bhch_id > 0 && bhch_id <= 32,
"Invalid bhch ID %d\n", bhch_id);
switch (r->present) {
case NR_RLC_Config_PR_um_Bi_Directional: {
struct NR_RLC_Config__um_Bi_Directional *um;
um = r->choice.um_Bi_Directional;
t_reassembly = decode_t_reassembly(um->dl_UM_RLC.t_Reassembly);
if (*um->dl_UM_RLC.sn_FieldLength != *um->ul_UM_RLC.sn_FieldLength) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
sn_field_length = decode_sn_field_length_um(*um->dl_UM_RLC.sn_FieldLength);
break;
}
default:
LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
// Remember that an IAB-MT is an UE
nr_rlc_ue_manager_t* nr_rlc_ue_manager = get_rlc_ue_manager();
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
/*AssertFatal(rlc_bhchConfig->bh_LogicalChannelIdentity_r16->choice.bh_LogicalChannelIdentity_r16 != NULL,
"Didn't pass Logical Channel ID during BH-RLC-Channel_config");
AssertFatal(rlc_bhchConfig->bh_LogicalChannelIdentity_r16->present == NR_BH_LogicalChannelIdentity_r16_PR_bh_LogicalChannelIdentity_r16,
"Given LogicalChannelIdentity isn't supported");
*/
int local_id = rlc_bhchConfig->bh_LogicalChannelIdentity_r16->choice.bh_LogicalChannelIdentity_r16 - 1;
BIT_STRING_TO_NR_BHRLCCHANNELID(&rlc_bhchConfig->bh_RLC_ChannelID_r16, ue->lcid2bhch[local_id]);
if (ue->bhch[bhch_id-1] != NULL) {
LOG_E(RLC, "%s:%d:%s: BH Channel %d already exists for IAB-MT with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, bhch_id, rnti);
} else {
nr_rlc_entity_t *nr_rlc_um = new_nr_rlc_entity_um(RLC_RX_MAXSIZE,
RLC_TX_MAXSIZE,
deliver_bap_sdu, ue,
t_reassembly,
sn_field_length);
nr_rlc_ue_add_bhch_rlc_entity(ue, bhch_id, nr_rlc_um);
LOG_D(RLC, "%s:%d:%s: added BH RLC Channel %d to IAB-MT with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, bhch_id, rnti);
}
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
static void add_bhch_am(int rnti, int bhch_id, const NR_BH_RLC_ChannelConfig_r16_t *rlc_bhchConfig)
{
struct NR_RLC_Config *r = rlc_bhchConfig->rlc_Config_r16;
int t_status_prohibit;
int t_poll_retransmit;
int poll_pdu;
int poll_byte;
int max_retx_threshold;
int t_reassembly;
int sn_field_length;
AssertFatal(bhch_id > 0 && bhch_id <= 32,
"Invalid BH RLC Channel ID %d\n", bhch_id);
switch (r->present) {
case NR_RLC_Config_PR_am: {
struct NR_RLC_Config__am *am;
am = r->choice.am;
t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly);
t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte);
max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold);
if (*am->dl_AM_RLC.sn_FieldLength != *am->ul_AM_RLC.sn_FieldLength) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength);
break;
}
default:
LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
// Remember that an IAB-MT is an UE
nr_rlc_ue_manager_t* nr_rlc_ue_manager = get_rlc_ue_manager();
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
/*AssertFatal(rlc_bhchConfig->bh_LogicalChannelIdentity_r16->choice.bh_LogicalChannelIdentity_r16 != NULL,
"Didn't pass Logical Channel ID during BH-RLC-Channel_config");
AssertFatal(rlc_bhchConfig->bh_LogicalChannelIdentity_r16->present == NR_rlc_bhchConfig__bh_LogicalChannelIdentity_r16_PR_bh_LogicalChannelIdentity_r16,
"Given LogicalChannelIdentity isn't supported");
*/
int local_id = rlc_bhchConfig->bh_LogicalChannelIdentity_r16->choice.bh_LogicalChannelIdentity_r16 - 1;
BIT_STRING_TO_NR_BHRLCCHANNELID(&rlc_bhchConfig->bh_RLC_ChannelID_r16, ue->lcid2bhch[local_id]);
if (ue->bhch[bhch_id-1] != NULL) {
LOG_E(RLC, "%s:%d:%s: BH Channel %d already exists for IAB-MT with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, bhch_id, rnti);
} else {
nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
RLC_TX_MAXSIZE,
deliver_bap_sdu, ue,
successful_bap_delivery, ue,
max_retx_reached, ue,
t_poll_retransmit,
t_reassembly, t_status_prohibit,
poll_pdu, poll_byte, max_retx_threshold,
sn_field_length);
nr_rlc_ue_add_bhch_rlc_entity(ue, bhch_id, nr_rlc_am);
LOG_I(RLC, "%s:%d:%s: added BH RLC Channel %d to IAB-MT with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, bhch_id, rnti);
}
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
void bap_add_bhch(int rnti, int bhch_id, const NR_BH_RLC_ChannelConfig_r16_t *rlc_bhchConfig){
switch (rlc_bhchConfig->rlc_Config_r16->present) {
case NR_RLC_Config_PR_am:
add_bhch_am(rnti, bhch_id, rlc_bhchConfig);
break;
case NR_RLC_Config_PR_um_Bi_Directional:
add_bhch_um(rnti, bhch_id, rlc_bhchConfig);
break;
default:
LOG_E(RLC, "%s:%d:%s: fatal: unhandled BH Channel type\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
LOG_I(RLC, "%s:%s:%d: added BH RLC Channel to IAB-MT with RNTI 0x%x\n", __FILE__, __FUNCTION__, __LINE__, rnti);
}
void nr_bap_layer_init(bool is_du)
{
/* hack: be sure to initialize only once */
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static int inited_DU = 0;
static int inited_MT = 0;
if (pthread_mutex_lock(&m) != 0) abort();
if (is_du && inited_DU) {
// Change LOG to BAP
LOG_E(RLC, "%s:%d:%s: fatal, inited_du already 1\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (!is_du && inited_MT) {
// Change LOG to BAP
LOG_E(RLC, "%s:%d:%s: fatal, inited_mt already 1\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (is_du) inited_DU = 1;
if (!is_du) inited_MT = 1;
// nr_rlc_ue_manager = new_nr_rlc_ue_manager(enb_flag);
if (pthread_mutex_unlock(&m)) abort();
}
void init_bap_entity(uint16_t bap_addr, bool is_du){
bap_entity = new_bap_entity(bap_addr, is_du);
if (is_du)
printf("[BAP] BAP entity initialized as IAB-DU with BAPAddress = %d\n", bap_entity->bap_address);
else
printf("[BAP] BAP entity initialized as IAB-MT with BAPAddress = %d\n", bap_entity->bap_address);
}

View File

@@ -0,0 +1,5 @@
#include <stdint.h>
void bap_add_bhch(int rnti, int bhch_id, const NR_BH_RLC_ChannelConfig_r16_t *rlc_bhchConfig);
void nr_bap_layer_init(bool is_du);
void init_bap_entity(uint16_t bap_addr, bool is_du);

View File

@@ -0,0 +1,4 @@
#include <pthread.h>
#include "common/utils/hashtable/hashtable.h"
#include "common/utils/assertions.h"

View File

@@ -0,0 +1,65 @@
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/sctp.h>
#ifndef BAP_INFO_H_
#define BAP_INFO_H_
typedef struct bhch_t{
uint16_t bhch_id;
nr_rlc_mode_t rlc_mode;
long lcid;
long priority;
uint16_t donor_bap_address;
uint16_t node_bap_address[30];
uint32_t number_of_nodes;
}bhch_t;
typedef struct iab_donor_du_t {
uint64_t du_id;
uint16_t bap_address;
} iab_donor_du_t;
typedef struct iab_node_du_t {
uint64_t du_id;
} iab_node_du_t;
typedef struct iab_mt_t {
uint64_t mt_id; // Don't know if this will useful
uint32_t rrc_ue_id;
} iab_mt_t;
typedef struct iab_node_t {
uint16_t bap_address;
iab_node_du_t iab_node_du;
iab_mt_t iab_mt;
uint16_t donor_bap_address;
} iab_node_t;
typedef struct iab_cu_t {
// Max 10 for now
iab_donor_du_t iab_donor_du[10];
int number_of_iab_donor_dus;
// max 30 for now
iab_node_t iab_node[30];
int number_of_iab_nodes;
uint16_t last_given_bap_address;
bhch_t *bhch_list;
int number_of_bhchs;
} iab_cu_t;
typedef struct gNB_IAB_INFO_s {
union {
iab_cu_t iab_cu;
iab_donor_du_t iab_donor_du;
iab_node_du_t iab_node_du;
iab_mt_t iab_mt;
};
} gNB_IAB_INFO;
#endif // BAP_INFO_H_

View File

@@ -0,0 +1,19 @@
#include <stdbool.h>
#include <stdint.h>
typedef struct bap_routingId_s{
uint16_t bap_address;
uint16_t bap_pathId;
} bap_routingId_t;
typedef struct bap_config_s{
uint16_t bap_address;
bap_routingId_t defaultUL_bap_routingID;
uint16_t defaultUL_bhch;
enum{
perBH_RLC_Channel,
perRoutingID,
both,
}flowControlFeedbackType;
} bap_config_t;

View File

@@ -112,8 +112,7 @@ int rlcmac_init_global_param_ue(void) {
return 0;
}
int
l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
int l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
uint8_t HO_active) {
LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n");
// NB_NODE=2;

View File

@@ -25,6 +25,7 @@
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "F1AP_CauseRadioNetwork.h"
#include "openair2/LAYER2/BAP/bap_oai_api.c"
#include "uper_decoder.h"
#include "uper_encoder.h"
@@ -39,6 +40,13 @@ static long get_lcid_from_drbid(int drb_id)
return drb_id + 3; /* LCID is DRB + 3 */
}
/* [IAB] related */
static long get_lcid_from_bhchid(uint16_t bhch_id)
{
return 33 - bhch_id; // Temporary solution to prevent conflicts
}
/* [IAB] end */
static long get_lcid_from_srbid(int srb_id)
{
return srb_id;
@@ -189,6 +197,46 @@ static int handle_ue_context_drbs_release(int rnti,
return drbs_len;
}
/* [IAB] related function for BH RLC Channel */
NR_BH_RLC_ChannelConfig_r16_t *get_bhchConfig(const f1ap_bhchannel_to_be_setup_t *bhch){
const NR_RLC_Config_PR rlc_conf = bhch->rlc_mode == RLC_MODE_UM ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am;
long lcid = get_lcid_from_bhchid(bhch->bHRLCChannelID);
long priority = 13; // hardcoded for the moment
return get_BH_RLC_ChannelConfig(lcid, bhch->bHRLCChannelID, rlc_conf, priority);
}
static int handle_ue_context_bhchannels_setup(int rnti,
int bhchs_len,
const f1ap_bhchannel_to_be_setup_t *req_bhchs,
f1ap_bhchannel_to_be_setup_t **resp_bhchs,
NR_CellGroupConfig_t *cellGroupConfig)
{
DevAssert(req_bhchs != NULL && resp_bhchs != NULL && cellGroupConfig != NULL);
/* Note: the actual GTP tunnels are created in the F1AP breanch of
* ue_context_*_response() */
*resp_bhchs = calloc(bhchs_len, sizeof(**resp_bhchs));
AssertFatal(*resp_bhchs != NULL, "out of memory\n");
cellGroupConfig->ext2 = calloc(1, sizeof(*cellGroupConfig->ext2));
cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 = calloc(bhchs_len, sizeof(NR_BH_RLC_ChannelConfig_r16_t));
for(int i=0; i<bhchs_len; i++){
const f1ap_bhchannel_to_be_setup_t *bhch = &req_bhchs[i];
NR_BH_RLC_ChannelConfig_r16_t *rlc_bhchConfig = get_bhchConfig(bhch);
bap_add_bhch(rnti, bhch->bHRLCChannelID, rlc_bhchConfig);
(*resp_bhchs)[i] = *bhch;
int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16->list, rlc_bhchConfig);
DevAssert(ret == 0);
}
return bhchs_len;
}
/* [IAB] end */
static NR_UE_NR_Capability_t *get_ue_nr_cap(int rnti, uint8_t *buf, uint32_t len)
{
if (buf == NULL || len == 0)
@@ -253,7 +301,7 @@ static void set_QoSConfig(const f1ap_ue_context_modif_req_t *req, NR_UE_sched_ct
AssertFatal(req != NULL, "f1ap_ue_context_modif_req is NULL\n");
uint8_t drb_count = req->drbs_to_be_setup_length;
uint8_t srb_count = req->srbs_to_be_setup_length;
LOG_I(NR_MAC, "Number of DRBs = %d and SRBs = %d\n", drb_count, srb_count);
LOG_I(NR_MAC, "QoSConfig: Number of DRBs = %d and SRBs = %d\n", drb_count, srb_count);
/* DRBs*/
for (int i = 0; i < drb_count; i++) {
@@ -402,6 +450,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
}
NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup);
// new_CellGroup comes with rlc-bearerToAddModList... (is it supposed to though?)
if (req->srbs_to_be_setup_length > 0) {
resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id,
@@ -419,6 +468,16 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
new_CellGroup);
}
/* [IAB] related configs */
if (req->bhchannels_to_be_setup_length > 0){
resp.bhchannels_to_be_setup_length = handle_ue_context_bhchannels_setup(req->gNB_DU_ue_id,
req->bhchannels_to_be_setup_length,
req->bhchannels_to_be_setup,
&resp.bhchannels_to_be_setup,
new_CellGroup);
}
/* [IAB] end */
if (req->drbs_to_be_released_length > 0) {
resp.drbs_to_be_released_length =
handle_ue_context_drbs_release(req->gNB_DU_ue_id, req->drbs_to_be_released_length, req->drbs_to_be_released, new_CellGroup);
@@ -442,7 +501,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
}
if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0 || req->drbs_to_be_released_length > 0
|| ue_cap != NULL) {
|| req->bhchannels_to_be_setup_length > 0 || ue_cap != NULL) {
resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t));
AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n");
resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1, 1024);
@@ -477,6 +536,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
/* free the memory we allocated above */
free(resp.srbs_to_be_setup);
free(resp.drbs_to_be_setup);
free(resp.bhchannels_to_be_setup);
if (resp.du_to_cu_rrc_information != NULL) {
free(resp.du_to_cu_rrc_information->cellGroupConfig);
free(resp.du_to_cu_rrc_information);

View File

@@ -64,6 +64,9 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
f1ap_setup->gNB_DU_id = req->gNB_DU_id;
f1ap_setup->gNB_DU_name = strdup(req->gNB_DU_name);
f1ap_setup->num_cells_available = req->num_cells_available;
if(req->bap_address != 0){
f1ap_setup->bap_address = req->bap_address;
}
for (int n = 0; n < req->num_cells_available; ++n) {
f1ap_setup->cell[n].info = req->cell[n].info; // copy most fields
if (req->cell[n].info.tac) {

View File

@@ -194,6 +194,12 @@ static void mac_rrc_init(gNB_MAC_INST *mac, ngran_node_t node_type)
case ngran_gNB_DU:
mac_rrc_ul_f1ap_init(&mac->mac_rrc);
break;
case ngran_gNB_IAB_donor_DU:
mac_rrc_ul_f1ap_init(&mac->mac_rrc);
break;
case ngran_gNB_IAB_node_DU:
mac_rrc_ul_f1ap_init(&mac->mac_rrc);
break;
case ngran_gNB:
mac_rrc_ul_direct_init(&mac->mac_rrc);
break;

View File

@@ -54,6 +54,12 @@ static uint64_t nr_rlc_current_time;
static int nr_rlc_current_time_last_frame;
static int nr_rlc_current_time_last_subframe;
/* [IAB] BAP dependence */
nr_rlc_ue_manager_t* get_rlc_ue_manager(){
return nr_rlc_ue_manager;
}
/**/
static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id)
{
AssertFatal(channel_id != 0, "LCID = 0 shouldn't be handled here\n");
@@ -468,31 +474,31 @@ rb_found:
if (NODE_IS_DU(type)) {
if(is_srb) {
MessageDef *msg;
msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size);
memcpy (message_buffer, buf, size);
MessageDef *msg;
msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size);
memcpy (message_buffer, buf, size);
F1AP_UL_RRC_MESSAGE(msg).gNB_CU_ue_id = ctx.rntiMaybeUEid;
F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->rnti;
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer;
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
return;
F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->rnti;
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer;
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
return;
} else {
MessageDef *msg = itti_alloc_new_message_sized(TASK_RLC_ENB, 0, GTPV1U_TUNNEL_DATA_REQ,
sizeof(gtpv1u_tunnel_data_req_t) + size);
gtpv1u_tunnel_data_req_t *req=&GTPV1U_TUNNEL_DATA_REQ(msg);
req->buffer=(uint8_t*)(req+1);
memcpy(req->buffer,buf,size);
req->length=size;
req->offset=0;
req->ue_id=ue->rnti; // use RNTI here, which GTP will use to look up TEID
req->bearer_id=rb_id;
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
extern instance_t DUuniqInstance;
itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg);
return;
MessageDef *msg = itti_alloc_new_message_sized(TASK_RLC_ENB, 0, GTPV1U_TUNNEL_DATA_REQ,
sizeof(gtpv1u_tunnel_data_req_t) + size);
gtpv1u_tunnel_data_req_t *req=&GTPV1U_TUNNEL_DATA_REQ(msg);
req->buffer=(uint8_t*)(req+1);
memcpy(req->buffer,buf,size);
req->length=size;
req->offset=0;
req->ue_id=ue->rnti; // use RNTI here, which GTP will use to look up TEID
req->bearer_id=rb_id;
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
extern instance_t DUuniqInstance;
itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg);
return;
}
}
}

View File

@@ -41,6 +41,8 @@
struct NR_RLC_Config;
struct NR_LogicalChannelConfig;
nr_rlc_ue_manager_t* get_rlc_ue_manager();
void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);

View File

@@ -206,3 +206,22 @@ void nr_rlc_ue_add_drb_rlc_entity(nr_rlc_ue_t *ue, int drb_id, nr_rlc_entity_t *
ue->drb[drb_id] = entity;
}
/* [IAB] related config */
void nr_rlc_ue_add_bhch_rlc_entity(nr_rlc_ue_t *ue, int bhch_id, nr_rlc_entity_t *entity)
{
if (bhch_id < 1 || bhch_id > 32) {
LOG_E(RLC, "%s:%d:%s: fatal, bad drb id\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
bhch_id--;
if (ue->bhch[bhch_id] != NULL) {
LOG_E(RLC, "%s:%d:%s: fatal, BH Channel already present\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ue->bhch[bhch_id] = entity;
}

View File

@@ -43,7 +43,9 @@ typedef struct nr_rlc_ue_t {
nr_rlc_entity_t *srb0;
nr_rlc_entity_t *srb[3];
nr_rlc_entity_t *drb[MAX_DRBS_PER_UE];
nr_rlc_entity_t *bhch[32];
nr_rlc_rb_t lcid2rb[32];
uint16_t lcid2bhch[32];
} nr_rlc_ue_t;
/***********************************************************************/
@@ -66,5 +68,6 @@ void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *m, int rnti);
void nr_rlc_ue_add_srb_rlc_entity(nr_rlc_ue_t *ue, int srb_id, nr_rlc_entity_t *entity);
void nr_rlc_ue_add_drb_rlc_entity(nr_rlc_ue_t *ue, int drb_id, nr_rlc_entity_t *entity);
void nr_rlc_ue_add_bhch_rlc_entity(nr_rlc_ue_t *ue, int bhch_id, nr_rlc_entity_t *entity);
#endif /* _NR_RLC_UE_MANAGER_H_ */

View File

@@ -1 +1 @@
add_subdirectory(MESSAGES)
add_subdirectory(MESSAGES)

View File

@@ -393,6 +393,55 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR
return rlc_BearerConfig;
}
/* [IAB] BH rlc channel config */
NR_BH_RLC_ChannelConfig_r16_t *get_BH_RLC_ChannelConfig(long lcChannelId, long bhch_id, NR_RLC_Config_PR rlc_conf, long priority){
printf("[ASN1] bhchid = %ld\n", bhch_id);
printf("[ASN1] lcChannelId = %ld\n", lcChannelId);
NR_BH_RLC_ChannelConfig_r16_t *rlc_bhConfig = calloc(1, sizeof(NR_BH_RLC_ChannelConfig_r16_t));
// Using only the old 0 to 32 lcid
rlc_bhConfig->bh_LogicalChannelIdentity_r16 = calloc(1, sizeof(NR_BH_LogicalChannelIdentity_r16_t));
rlc_bhConfig->bh_LogicalChannelIdentity_r16->present = NR_BH_LogicalChannelIdentity_r16_PR_bh_LogicalChannelIdentity_r16;
rlc_bhConfig->bh_LogicalChannelIdentity_r16->choice.bh_LogicalChannelIdentity_r16 = lcChannelId;
NR_BHRLCCHANNELID_TO_BIT_STRING(bhch_id, &rlc_bhConfig->bh_RLC_ChannelID_r16);
rlc_bhConfig->reestablishRLC_r16 = calloc(1, sizeof(e_NR_BH_RLC_ChannelConfig_r16__reestablishRLC_r16));
rlc_bhConfig->reestablishRLC_r16 = NULL;
NR_RLC_Config_t *rlc_Config = calloc(1, sizeof(NR_RLC_Config_t));
// For now, re-use drb config
nr_drb_config(rlc_Config, rlc_conf);
rlc_bhConfig->rlc_Config_r16 = rlc_Config;
NR_LogicalChannelConfig_t *logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t));
logicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters));
logicalChannelConfig->ul_SpecificParameters->priority = priority;
logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100;
long *logicalChannelGroupIAB = CALLOC(1, sizeof(long));
/* Set LCG = 1 for BH rlc channels
* Since we are using this channel for IAB purposes, we can use the
* logicalChannelGroupIAB-Ext-r17, which is inside the range (0 to 255)
*/
*logicalChannelGroupIAB = 1;
logicalChannelConfig->ul_SpecificParameters->ext2 = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->ext2));
logicalChannelConfig->ul_SpecificParameters->ext2->logicalChannelGroupIAB_Ext_r17 = CALLOC(1,sizeof(int));
logicalChannelConfig->ul_SpecificParameters->ext2->logicalChannelGroupIAB_Ext_r17 = logicalChannelGroupIAB;
logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
// Will choose 7 (maximum number) to avoid possible conflicts
*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 7;
logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0;
logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
rlc_bhConfig->mac_LogicalChannelConfig_r16 = logicalChannelConfig;
return rlc_bhConfig;
}
/* returns a default radio bearer config suitable for NSA etc */
NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id,
int rb_id,
@@ -926,6 +975,66 @@ uint8_t do_RRCSetupComplete(uint8_t *buffer,
return((enc_rval.encoded+7)/8);
}
uint8_t do_RRCSetupComplete_IAB(uint8_t *buffer,
size_t buffer_size,
const uint8_t Transaction_id,
uint8_t sel_plmn_id,
const int dedicatedInfoNASLength,
const char *dedicatedInfoNAS)
{
NR_UL_DCCH_Message_t ul_dcch_msg = {0};
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete;
ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_t));
NR_RRCSetupComplete_t *RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete;
RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id;
RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_IEs_t));
NR_RRCSetupComplete_IEs_t *ies = RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete;
ies->selectedPLMN_Identity = sel_plmn_id;
ies->registeredAMF = NULL;
ies->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value));
ies->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI;
NR_NG_5G_S_TMSI_t *stmsi = &ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI;
stmsi->size = 6;
stmsi->buf = calloc(stmsi->size, sizeof(*stmsi->buf));
AssertFatal(stmsi->buf != NULL, "out of memory\n");
stmsi->buf[0] = 0x12;
stmsi->buf[1] = 0x34;
stmsi->buf[2] = 0x56;
stmsi->buf[3] = 0x78;
stmsi->buf[4] = 0x9A;
stmsi->buf[5] = 0xBC;
memset(&ies->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(&ies->dedicatedNAS_Message, dedicatedInfoNAS, dedicatedInfoNASLength);
// ----IAB related params----
ies->nonCriticalExtension = CALLOC(1, sizeof(NR_RRCSetupComplete_v1610_IEs_t));
NR_RRCSetupComplete_v1610_IEs_t *v1610_ies = ies->nonCriticalExtension;
v1610_ies->iab_NodeIndication_r16 = CALLOC(1, sizeof(long));
*v1610_ies->iab_NodeIndication_r16 = NR_RRCSetupComplete_v1610_IEs__iab_NodeIndication_r16_true;
// --------------------------
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
}
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
NULL,
(void *)&ul_dcch_msg,
buffer,
buffer_size);
AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name,enc_rval.encoded);
LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg);
return((enc_rval.encoded+7)/8);
}
uint8_t do_NR_DLInformationTransfer(uint8_t *buffer,
size_t buffer_len,
uint8_t transaction_id,

View File

@@ -70,6 +70,8 @@ NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id,
e_NR_CipheringAlgorithm ciphering_algorithm,
e_NR_SecurityConfig__keyToUse key_to_use);
NR_BH_RLC_ChannelConfig_r16_t *get_BH_RLC_ChannelConfig(long lcChannelId, long bhch_id, NR_RLC_Config_PR rlc_conf, long priority);
void fill_nr_noS1_bearer_config(NR_RadioBearerConfig_t **rbconfig,
NR_RLC_BearerConfig_t **rlc_rbconfig);
void free_nr_noS1_bearer_config(NR_RadioBearerConfig_t **rbconfig,
@@ -115,6 +117,13 @@ uint8_t do_RRCSetupComplete(uint8_t *buffer,
const int dedicatedInfoNASLength,
const char *dedicatedInfoNAS);
uint8_t do_RRCSetupComplete_IAB(uint8_t *buffer,
size_t buffer_size,
const uint8_t Transaction_id,
uint8_t sel_plmn_id,
const int dedicatedInfoNASLength,
const char *dedicatedInfoNAS);
int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv);
uint8_t do_NR_RRCReconfigurationComplete_for_nsa(uint8_t *buffer, size_t buffer_size, NR_RRC_TransactionIdentifier_t Transaction_id);

View File

@@ -32,6 +32,9 @@ static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_
*f1ap_msg = *resp;
if (resp->gNB_CU_name != NULL)
f1ap_msg->gNB_CU_name = strdup(resp->gNB_CU_name);
if (resp->bap_address != 0){
f1ap_msg->bap_address = resp->bap_address;
}
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
}
@@ -123,6 +126,8 @@ static void ue_context_modification_request_f1ap(sctp_assoc_t assoc_id, const f1
f1ap_msg->rrc_container_length = req->rrc_container_length;
memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length);
}
// Why is it sending to the CU??
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
}

View File

@@ -243,6 +243,7 @@ typedef enum {
RRC_REESTABLISH_COMPLETE,
RRC_DEFAULT_RECONF,
RRC_DEDICATED_RECONF,
RRC_IAB_RECONF,
RRC_PDUSESSION_ESTABLISH,
RRC_PDUSESSION_MODIFY,
RRC_PDUSESSION_RELEASE,
@@ -323,6 +324,12 @@ typedef struct gNB_RRC_UE_s {
/* hack, see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() for more info */
int max_delays_pdu_session;
/*[IAB] params*/
bool is_iab_mt;
/* For now, only used to check if already has bap address
* Further IAB information is located at ran_context through gNB_IAB_INFO_s **iab
*/
uint16_t bap_address;
} gNB_RRC_UE_t;
typedef struct rrc_gNB_ue_context_s {
@@ -380,6 +387,8 @@ typedef struct nr_rrc_du_container_t {
f1ap_setup_req_t *setup_req;
NR_MIB_t *mib;
NR_SIB1_t *sib1;
uint16_t bap_address;
} nr_rrc_du_container_t;
typedef struct nr_rrc_cuup_container_t {

View File

@@ -57,6 +57,11 @@
#include "NR_RejectWaitTime.h"
#include "NR_RRCSetup.h"
//[IAB] includes
#include "NR_RRCReconfiguration-v1610-IEs.h"
#include "NR_SetupRelease.h"
#include "NR_BAP-Config-r16.h"
#include "NR_CellGroupConfig.h"
#include "NR_MeasResults.h"
#include "NR_UL-CCCH-Message.h"
@@ -90,6 +95,7 @@
#include "executables/softmodem-common.h"
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
#include <openair2/LAYER2/BAP/iab_info_management.h>
#include <openair2/X2AP/x2ap_eNB.h>
#include <openair3/SECU/key_nas_deriver.h>
#include <openair3/ocp-gtpu/gtp_itf.h>
@@ -99,6 +105,7 @@
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
#include "openair2/E1AP/e1ap.h"
#include "cucp_cuup_if.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h"
#include "BIT_STRING.h"
#include "assertions.h"
@@ -145,6 +152,7 @@ typedef struct deliver_dl_rrc_message_data_s {
f1ap_dl_rrc_message_t *dl_rrc;
sctp_assoc_t assoc_id;
} deliver_dl_rrc_message_data_t;
static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id)
{
DevAssert(deliver_pdu_data != NULL);
@@ -307,6 +315,10 @@ static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc)
* soon as this is not the case anymore, we can add the AssertFatal() */
//AssertFatal(1==0,"nothing to do for DU\n");
break;
case ngran_gNB_IAB_donor_DU:
break;
case ngran_gNB_IAB_node_DU:
break;
default:
AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type);
break;
@@ -600,6 +612,7 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
measconfig,
dedicatedNAS_MessageList,
ue_p->masterCellGroup);
AssertFatal(size > 0, "cannot encode RRCReconfiguration in %s()\n", __func__);
free_defaultMeasConfig(measconfig);
freeSRBlist(SRBs);
@@ -715,6 +728,86 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
}
//-----[IAB] Specific RRCReconfig to setup BH RLC Channels and BAP config------
void rrc_gNB_generate_IAB_RRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
//-----------------------------------------------------------------------------
{
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
gNB_IAB_INFO *iab = RC.iab[0];
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
ue_p->xids[xid] = RRC_IAB_RECONF;
struct NR_RRCReconfiguration_v1610_IEs *reconf_v1610 = CALLOC(1, sizeof(*reconf_v1610));
reconf_v1610->bap_Config_r16->present = NR_SetupRelease_BAP_Config_r16_PR_setup;
reconf_v1610->bap_Config_r16->choice.setup = CALLOC(1, sizeof(reconf_v1610->bap_Config_r16->choice.setup));
NR_BAP_Config_r16_t *bap_config = reconf_v1610->bap_Config_r16->choice.setup;
NR_BAPADDRESS_TO_BIT_STRING(ue_p->bap_address, bap_config->bap_Address_r16);
// --- Set cellGroupConfig with bap_address and bhch info ---
NR_CellGroupConfig_t *cellGroupConfig = CALLOC(1, sizeof(*cellGroupConfig));
cellGroupConfig->cellGroupId = ue_p->masterCellGroup->cellGroupId;
NR_BAPADDRESS_TO_BIT_STRING(ue_p->bap_address, cellGroupConfig->ext2->bap_Address_r16);
const nr_rrc_du_container_t *donor_du = get_du_for_ue(rrc, ue_p->rrc_ue_id);
uint64_t donor_du_id = donor_du->setup_req->gNB_DU_id;
uint16_t donor_bap_address = 0;
for (int i = 0; i < iab->iab_cu.number_of_iab_donor_dus; i++){
if(iab->iab_cu.iab_donor_du[i].du_id == donor_du_id){
donor_bap_address = iab->iab_cu.iab_donor_du[i].bap_address;
break;
}
}
cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 = CALLOC(1, sizeof(cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16));
struct NR_CellGroupConfig__ext2__bh_RLC_ChannelToAddModList_r16 *bhch_list = cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16;
for (int i = 0; i < iab->iab_cu.number_of_bhchs; i++){
if (iab->iab_cu.bhch_list[i].donor_bap_address == donor_bap_address){
asn1cSequenceAdd(bhch_list->list, NR_BH_RLC_ChannelConfig_r16_t, bhch);
int bhch_id = iab->iab_cu.bhch_list[i].bhch_id;
long lcid = iab->iab_cu.bhch_list[i].lcid;
const NR_RLC_Config_PR rlc_conf = iab->iab_cu.bhch_list[i].rlc_mode == RLC_MODE_UM ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am;
long priority = iab->iab_cu.bhch_list[i].priority;
bhch = get_BH_RLC_ChannelConfig(lcid, bhch_id, rlc_conf, priority);
}
}
// ----------------------------------------------------------
//uint8_t buffer[RRC_BUF_SIZE] = {0};
/*int size = do_RRCReconfiguration_IAB( ue_p,
buffer,
RRC_BUF_SIZE,
xid,
cellGroupConfig);
*/
/*
int size = do_RRCReconfiguration(ue_p,
buffer,
RRC_BUF_SIZE,
xid,
SRBs,
DRBs,
ue_p->DRB_ReleaseList,
NULL,
NULL,
dedicatedNAS_MessageList,
cellGroupConfig);
LOG_I(NR_RRC, "UE %d: Generate RRCReconfiguration (bytes %d, xid %d)\n", ue_p->rrc_ue_id, size, xid);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
*/
}
//-----------------------------------------------------------------------------
void
rrc_gNB_modify_dedicatedRRCReconfiguration(
@@ -1539,11 +1632,107 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
}
}
// [IAB] related configs
if (setup_complete_ies->nonCriticalExtension != NULL){
if (*setup_complete_ies->nonCriticalExtension->iab_NodeIndication_r16 == NR_RRCSetupComplete_v1610_IEs__iab_NodeIndication_r16_true){
LOG_I(NR_RRC, "IAB Node Indication received and set to true\n");
UE->is_iab_mt = true;
/* if we did not receive any UE Capabilities, let's do that now. It should
* only happen on the first time a reconfiguration arrives. Afterwards, we
* should have them. If the UE does not give us anything, we will re-request
* the capabilities after each reconfiguration, which is a finite number
if (UE->ue_cap_buffer.len == 0) {
rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
}
*/
} else{
UE->is_iab_mt = false; // not used
}
}
// -------------------
rrc_gNB_process_RRCSetupComplete(ctxt_pP, ue_context_p, setup_complete->criticalExtensions.choice.rrcSetupComplete);
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " UE State = NR_RRC_CONNECTED \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
return 0;
}
static void engage_BH_RLC_Channel_establishment_procedure(rrc_gNB_ue_context_t *ue_context_p){
/* Adds new IAB-node (with the IAB-MT).
* Node DU is added later during F1 SETUP Procedure
*/
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
gNB_IAB_INFO *iab = RC.iab[0];
int *number_of_nodes = &iab->iab_cu.number_of_iab_nodes;
iab->iab_cu.iab_node[*number_of_nodes].iab_mt.rrc_ue_id = UE->rrc_ue_id;
iab->iab_cu.last_given_bap_address += 1;
int new_bap_address = iab->iab_cu.last_given_bap_address;
iab->iab_cu.iab_node[*number_of_nodes].bap_address = new_bap_address;
*number_of_nodes += 1;
// Call UE Context modification request.
gNB_RRC_INST *rrc = RC.nrrrc[0];
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data);
f1ap_bhchannel_to_be_setup_t bhch_buf[1];
bhch_buf[0].bHRLCChannelID = 1;
bhch_buf[0].rlc_mode = NR_RLC_AM;
bhch_buf[0].is_trafficMappingInfo_set = false;
f1ap_bhchannel_to_be_setup_t *bh_rlc_channels = bhch_buf;
f1ap_ue_context_modif_req_t ue_context_modif_req = {
.gNB_CU_ue_id = UE->rrc_ue_id,
.gNB_DU_ue_id = ue_data.secondary_ue,
.plmn.mcc = rrc->configuration.mcc[0],
.plmn.mnc = rrc->configuration.mnc[0],
.plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
.nr_cellid = rrc->nr_cellid,
.servCellId = 0, /* TODO: correct value? */
.bhchannels_to_be_setup = bh_rlc_channels,
.bhchannels_to_be_setup_length = 1
};
/* Register BH RLC Channel information in the CU
*/
// Get associated donor_du information
const nr_rrc_du_container_t *donor_du = get_du_for_ue(rrc, UE->rrc_ue_id);
uint64_t donor_du_id = donor_du->setup_req->gNB_DU_id;
uint16_t donor_bap_address = 0;
for(int i=0; i<iab->iab_cu.number_of_iab_donor_dus; i++){
if(iab->iab_cu.iab_donor_du[i].du_id == donor_du_id){
donor_bap_address = iab->iab_cu.iab_donor_du[i].bap_address;
break;
}
}
uint32_t *bhch_number_of_nodes = &iab->iab_cu.bhch_list[iab->iab_cu.number_of_bhchs].number_of_nodes;
LOG_I(NR_RRC, "Got to this point: number of bhch = %d\n", bhch_buf[0].bHRLCChannelID);
// Insert bhch info in IAB information
iab->iab_cu.bhch_list[iab->iab_cu.number_of_bhchs].bhch_id = bhch_buf[0].bHRLCChannelID;
LOG_I(NR_RRC, "Got to this point 1\n");
iab->iab_cu.bhch_list[iab->iab_cu.number_of_bhchs].rlc_mode = bhch_buf[0].rlc_mode;
LOG_I(NR_RRC, "Got to this point 2\n");
iab->iab_cu.bhch_list[iab->iab_cu.number_of_bhchs].lcid = 33 - bhch_buf[0].bHRLCChannelID;
LOG_I(NR_RRC, "Got to this point 3\n");
iab->iab_cu.bhch_list[iab->iab_cu.number_of_bhchs].priority = 13;
LOG_I(NR_RRC, "Got to this point 4\n");
iab->iab_cu.bhch_list[iab->iab_cu.number_of_bhchs].node_bap_address[*bhch_number_of_nodes] = new_bap_address;
LOG_I(NR_RRC, "Got to this point 5\n");
iab->iab_cu.bhch_list[iab->iab_cu.number_of_bhchs].donor_bap_address = donor_bap_address;
LOG_I(NR_RRC, "Got to this point 6\n");
iab->iab_cu.number_of_bhchs += 1;
LOG_I(NR_RRC, "Got to this point 7\n");
*bhch_number_of_nodes += 1;
LOG_I(NR_RRC, "Got to this point 8\n");
rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req);
}
static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_p,
const NR_RRCReconfigurationComplete_t *reconfig_complete)
@@ -1572,6 +1761,9 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
break;
case RRC_DEFAULT_RECONF:
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
if(UE->is_iab_mt){
engage_BH_RLC_Channel_establishment_procedure(ue_context_p);
}
break;
case RRC_REESTABLISH_COMPLETE:
case RRC_DEDICATED_RECONF:
@@ -1581,6 +1773,9 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
LOG_E(RRC, "UE %d: Received RRC Reconfiguration Complete with xid %d while no transaction is ongoing\n", UE->rrc_ue_id, xid);
successful_reconfig = false;
break;
case RRC_IAB_RECONF:
/* do nothing */
break;
default:
LOG_E(RRC, "UE %d: Received unexpected transaction type %d for xid %d\n", UE->rrc_ue_id, UE->xids[xid], xid);
successful_reconfig = false;
@@ -1606,7 +1801,10 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
.servCellId = 0, /* TODO: correct value? */
.ReconfigComplOutcome = successful_reconfig ? RRCreconf_success : RRCreconf_failure,
};
rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req);
// [IAB] IAB-MT troubleshoot (it shouldn't send modification request again)
if(UE->is_iab_mt == false){
rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req);
}
/* if we did not receive any UE Capabilities, let's do that now. It should
* only happen on the first time a reconfiguration arrives. Afterwards, we
@@ -2000,7 +2198,23 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i
}
UE->masterCellGroup = cellGroupConfig;
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
/* [IAB] */
if(UE->is_iab_mt){
// If BAP Address isn't set yet (Configuring new IAB-MT)
if(UE->bap_address == 0){
gNB_IAB_INFO *iab = RC.iab[0];
for (int i=0; i<iab->iab_cu.number_of_iab_nodes; i++){
if(iab->iab_cu.iab_node[i].iab_mt.rrc_ue_id == UE->rrc_ue_id){
UE->bap_address = iab->iab_cu.iab_node[i].bap_address;
}
}
rrc_gNB_generate_IAB_RRCReconfiguration(&ctxt, ue_context_p);
} else {
// Future use (modifying an IAB-MT that is already configured)
}
}else{
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
}
}
}

View File

@@ -19,9 +19,11 @@
* contact@openairinterface.org
*/
#include <string.h>
#include "rrc_gNB_du.h"
#include "common/ran_context.h"
#include "nr_rrc_defs.h"
#include "openair2/LAYER2/BAP/iab_info_management.h"
#include "rrc_gNB_UE_context.h"
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/F1AP/f1ap_ids.h"
@@ -54,12 +56,15 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
gNB_RRC_INST *rrc = RC.nrrrc[0];
DevAssert(rrc);
gNB_IAB_INFO *iab = RC.iab[0];
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
// - no previous DU with the same BAP Address
// 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);
@@ -91,6 +96,16 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
return;
}
if (it->setup_req->bap_address == req->bap_address && req->bap_address != 0){
LOG_E(NR_RRC,
"BAPAddress: existing DU %s on assoc_id %d already has BAPAddress %d, rejecting requesting gNB-DU\n",
it->setup_req->gNB_DU_name,
it->assoc_id,
it->setup_req->bap_address);
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;
@@ -160,8 +175,6 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
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,
@@ -175,8 +188,37 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
.cells_to_activate[0] = cell};
int num = read_version(TO_STRING(NR_RRC_VERSION), &resp.rrc_ver[0], &resp.rrc_ver[1], &resp.rrc_ver[2]);
AssertFatal(num == 3, "could not read RRC version string %s\n", TO_STRING(NR_RRC_VERSION));
if (rrc->node_name != NULL)
if (rrc->node_name != NULL){
resp.gNB_CU_name = strdup(rrc->node_name);
}
/* [IAB]
*/
if(strstr(req->gNB_DU_name, "Donor") != NULL){
iab->iab_cu.last_given_bap_address += 1;
int new_bap_address = iab->iab_cu.last_given_bap_address;
printf("Giving BAP Address = %d\n", new_bap_address);
resp.bap_address = new_bap_address;
iab_donor_du_t *iab_donor_du = &iab->iab_cu.iab_donor_du[iab->iab_cu.number_of_iab_donor_dus];
iab_donor_du->du_id = req->gNB_DU_id;
iab_donor_du->bap_address = new_bap_address;
iab->iab_cu.number_of_iab_donor_dus += 1;
// Adding BAP Address here to make search easier
du->bap_address = new_bap_address;
} else if (strstr(req->gNB_DU_name, "Node") != NULL) {
printf("Receiving BAP Address = %d\n", req->bap_address);
du->bap_address = req->bap_address;
for (int i = 0; i < iab->iab_cu.number_of_iab_nodes; i++){
if (iab->iab_cu.iab_node[i].bap_address == req->bap_address){
iab->iab_cu.iab_node[i].iab_node_du.du_id = req->gNB_DU_id;
break;
}
}
}
RB_INSERT(rrc_du_tree, &rrc->dus, du);
rrc->num_dus++;
rrc->mac_rrc.f1_setup_response(assoc_id, &resp);
/*

View File

@@ -30,6 +30,7 @@
struct f1ap_setup_req_s;
struct f1ap_lost_connection_t;
struct gNB_RRC_INST_s;
struct gNB_IAB_INFO_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);

View File

@@ -834,7 +834,8 @@ static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const
nas_msg_length = sizeof(nr_nas_attach_req_imsi_dummy_NSA_case);
}
size = do_RRCSetupComplete(buffer, sizeof(buffer), Transaction_id, rrc->selected_plmn_identity, nas_msg_length, nas_msg);
//size = do_RRCSetupComplete(buffer, sizeof(buffer), Transaction_id, rrc->selected_plmn_identity, nas_msg_length, nas_msg);
size = do_RRCSetupComplete_IAB(buffer, sizeof(buffer), Transaction_id, rrc->selected_plmn_identity, nas_msg_length, nas_msg);
LOG_I(NR_RRC, "[UE %ld][RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d)\n", rrc->ue_id, size);
int srb_id = 1; // RRC setup complete on SRB1
LOG_D(NR_RRC, "[RRC_UE %ld] PDCP_DATA_REQ/%d Bytes RRCSetupComplete ---> %d\n", rrc->ue_id, size, srb_id);

View File

@@ -248,6 +248,9 @@ typedef struct ngap_gNB_instance_s {
/* Tracking area code */
uint32_t tac;
/* [IAB] donor-DU bap address */
uint16_t bap_address;
/* gNB NGAP IP address */
net_ip_address_t gNB_ng_ip;

View File

@@ -455,6 +455,105 @@ do { \
(bITsTRING)->bits_unused = 4; \
} while(0)
// [IAB] Related macros
/* TS 38.331 BH-RLC-ChannelID
* uint16_t to BIT STRING (SIZE(16))
*/
#define NR_BHRLCCHANNELID_TO_BIT_STRING(mACRO, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(2, sizeof(uint8_t)); \
(bITsTRING)->buf[0] = ((mACRO) >> 8) & 0xff; \
(bITsTRING)->buf[1] = (mACRO) & 0xff; \
(bITsTRING)->size = 2; \
(bITsTRING)->bits_unused = 0; \
} while(0)
/* MappingInformationIndex
* uint32_t to BIT STRING (SIZE(26))
*/
#define NR_MAPPINGINFORMATIONINDEX_TO_BIT_STRING(mACRO, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \
(bITsTRING)->buf[0] = ((mACRO) >> 18) & 0xff; \
(bITsTRING)->buf[1] = ((mACRO) >> 10) & 0xff; \
(bITsTRING)->buf[2] = ((mACRO) >> 2) & 0xff; \
(bITsTRING)->buf[3] = ((mACRO) & 0x03) << 6; \
(bITsTRING)->size = 4; \
(bITsTRING)->bits_unused = 6; \
} while(0)
#define IABTNL_ADRESS_IPv4_TO_BIT_STRING(mACRO, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \
(bITsTRING)->buf[3] = (mACRO) >> 24 & 0xFF; \
(bITsTRING)->buf[2] = (mACRO) >> 16 & 0xFF; \
(bITsTRING)->buf[1] = (mACRO) >> 8 & 0xFF; \
(bITsTRING)->buf[0] = (mACRO) & 0xFF; \
(bITsTRING)->size = 4; \
(bITsTRING)->bits_unused = 0; \
} while(0)
/* DSCP
* uint8_t to BIT STRING (SIZE(6))
*/
#define DSCP_TO_BIT_STRING(mACRO, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(1, sizeof(uint8_t)); \
(bITsTRING)->buf[0] = ((mACRO) & 0x3f) << 2; \
(bITsTRING)->size = 1; \
(bITsTRING)->bits_unused = 2; \
} while(0)
/* BAPAddress
* uint16_t to BIT STRING (SIZE(10))
*/
#define NR_BAPADDRESS_TO_BIT_STRING(mACRO, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(2, sizeof(uint8_t)); \
(bITsTRING)->buf[0] = ((mACRO) >> 2) & 0xff; \
(bITsTRING)->buf[1] = ((mACRO) & 0xff) << 6; \
(bITsTRING)->size = 2; \
(bITsTRING)->bits_unused = 6; \
} while(0)
/* BAPPathID
* uint16_t to BIT STRING (SIZE(10))
*/
#define NR_BAPPATHID_TO_BIT_STRING(mACRO, bITsTRING) \
do { \
(bITsTRING)->buf = calloc(2, sizeof(uint8_t)); \
(bITsTRING)->buf[0] = ((mACRO) >> 2) & 0xff; \
(bITsTRING)->buf[1] = ((mACRO) & 0xff) << 6; \
(bITsTRING)->size = 2; \
(bITsTRING)->bits_unused = 6; \
} while(0)
/*
* BIT STRING (SIZE(16)) to uint16_t
*/
#define BIT_STRING_TO_NR_BHRLCCHANNELID(bITsTRING, mACRO) \
do { \
DevCheck((bITsTRING)->size == 2, (bITsTRING)->size, 2, 0); \
DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \
mACRO = (((uint16_t) (bITsTRING)->buf[0]) << 8) + \
((uint16_t) (bITsTRING)->buf[1]); \
} while (0)
/*
* BIT STRING (SIZE(10)) to uint16_t
*/
#define BIT_STRING_TO_NR_BAPADDRESS(bITsTRING, mACRO) \
do{ \
DevCheck((bITsTRING)->size == 2, (bITsTRING)->size, 2, 0); \
DevCheck((bITsTRING)->bits_unused == 6, (bITsTRING)->bits_unused, 6, 0); \
mACRO = (((uint16_t) (bITsTRING)->buf[0]) << 2) + \
((uint16_t) (bITsTRING)->buf[1] >> 6); \
} while(0)
// [IAB] End related macros
/*
#define INT16_TO_3_BYTE_BUFFER(x, buf) \
do { \