Compare commits
22 Commits
develop
...
IAB-Eureco
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2f69a57a2 | ||
|
|
6477338da3 | ||
|
|
9512843137 | ||
|
|
fbe7e6b731 | ||
|
|
e40b128f3f | ||
|
|
c4d96c8bfd | ||
|
|
8fe9df7bf3 | ||
|
|
06dd13d348 | ||
|
|
070ae03629 | ||
|
|
f6b422989a | ||
|
|
b1bb36a340 | ||
|
|
2dc0a8d75c | ||
|
|
0d56b3ce43 | ||
|
|
1d3c539ce2 | ||
|
|
bf02d4c897 | ||
|
|
6483ae6383 | ||
|
|
0a22f997cb | ||
|
|
8a924cd011 | ||
|
|
3d3d403614 | ||
|
|
9ee12ae551 | ||
|
|
8a5f54961f | ||
|
|
f1b0cde103 |
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
242
doc/IAB_docs/RRC_IAB_Info.md
Normal 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)
|
||||
BIN
doc/IAB_docs/images/BAP_layer_functional_example.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
doc/IAB_docs/images/BAP_layer_structure.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
doc/IAB_docs/images/IAB-MT-Requirements.png
Normal file
|
After Width: | Height: | Size: 305 KiB |
BIN
doc/IAB_docs/images/IAB_high_level.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 218 KiB |
BIN
doc/IAB_docs/images/IAB_inter-CU_redundancy.png
Normal file
|
After Width: | Height: | Size: 243 KiB |
BIN
doc/IAB_docs/images/IAB_inter-CU_topology_adaptation.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 275 KiB |
BIN
doc/IAB_docs/images/IAB_node_integration.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
doc/IAB_docs/images/IAB_node_relation.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
doc/IAB_docs/images/IAB_other_info.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
doc/IAB_docs/images/Protocol_stack_F1-C.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
doc/IAB_docs/images/Protocol_stack_F1-U.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
doc/IAB_docs/images/Protocol_stack_RRC_NAS.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
@@ -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();
|
||||
|
||||
@@ -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, ×tamp, true);
|
||||
trashed_frames+=2;
|
||||
}
|
||||
} else {
|
||||
readFrame(UE, ×tamp, 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, ×tamp, true);
|
||||
trashed_frames+=2;
|
||||
}
|
||||
} else {
|
||||
readFrame(UE, ×tamp, true);
|
||||
trashed_frames+=2;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
17
openair2/LAYER2/BAP/bap_entity.c
Normal 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;
|
||||
}
|
||||
34
openair2/LAYER2/BAP/bap_entity.h
Normal 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);
|
||||
223
openair2/LAYER2/BAP/bap_oai_api.c
Normal 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);
|
||||
}
|
||||
5
openair2/LAYER2/BAP/bap_oai_api.h
Normal 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);
|
||||
4
openair2/LAYER2/BAP/iab_info_management.c
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
#include <pthread.h>
|
||||
#include "common/utils/hashtable/hashtable.h"
|
||||
#include "common/utils/assertions.h"
|
||||
65
openair2/LAYER2/BAP/iab_info_management.h
Normal 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_
|
||||
|
||||
19
openair2/LAYER2/BAP/iab_rrc_info.h
Normal 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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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=>PV1U_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=>PV1U_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -1 +1 @@
|
||||
add_subdirectory(MESSAGES)
|
||||
add_subdirectory(MESSAGES)
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 { \
|
||||
|
||||