Merge remote-tracking branch 'origin/f1-handover-procedures' into integration_2024_w43 (!2786)

Add F1 Handover procedures

- Clean up at RRC and MAC
- Add DU handover procedures, completely handle CellGroupConfig at DU
- Add CU handover procedures
- Maintain reestablishment working between/after handover
- Changes at UE to resync on different frequency DUs

Instructions: see doc/handover-tutorial.md

Things not implemented/open/missing: see #855
This commit is contained in:
Robert Schmidt
2024-10-25 20:22:01 +02:00
46 changed files with 3043 additions and 308 deletions
+1 -1
View File
@@ -59,8 +59,8 @@ This is the current status:
* SA
* Single cell per DU
* Multiple DUs connected to one CU (both CP and UP)
* Mobility between DUs connected to a single CU
- Not supported:
* Mobility
* NSA
## F1-C
+2
View File
@@ -137,6 +137,7 @@ These modes of operation are supported:
- evaluation of CQI report
- MAC scheduling of SR reception
- Support of up to 16 UEs (can be increased to 32)
- Intra-frequency handover
## gNB RLC
@@ -221,6 +222,7 @@ These modes of operation are supported:
- Interface with RRC
- Interface with GTP-u (tunnel creation/handling for F1-U interface)
- One CU(-CP) can handle multiple DUs
- Support for intra-CU mobility (across DUs)
## gNB E1AP
+5 -2
View File
@@ -143,10 +143,13 @@ In the last lines:
# Configuration of the MAC
## Split-related options
## Split-related options (running in a DU)
See [nFAPI documentation](../L2NFAPI.md) or [Aerial
tutorial](../Aerial_FAPI_Split_Tutorial.md).
tutorial](../Aerial_FAPI_Split_Tutorial.md) for information about the FAPI
split.
See [F1 documentation](../F1-design.md) for information about the F1 split.
## MAC scheduler-related configuration options
+1
View File
@@ -53,6 +53,7 @@ There is some general information in the [OpenAirInterface Gitlab Wiki](https://
- [How to run with E2 agent](../openair2/E2AP/README.md)
- [How to run the physical simulators](./physical-simulators.md)
- [How to setup OAI with Nvidia Aerial and Foxconn](./Aerial_FAPI_Split_Tutorial.md)
- [How to do a handover](./handover-tutorial.md)
Legacy unmaintained files:
- [`L2NFAPI_NOS1.md`](./L2NFAPI_NOS1.md), [`L2NFAPI_S1.md`](./L2NFAPI_S1.md):
+9
View File
@@ -0,0 +1,9 @@
block-beta
columns 5
space space DU0 space UE
CU space space space space
space space DU1 space pos["new pos"]
CU<-- "F1" -->DU0
CU<-- "F1" -->DU1
DU0-- "Uu" -->UE
UE-- "move" -->pos
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

+318
View File
@@ -0,0 +1,318 @@
This document contains documentation for the 5G RRC layer, destined towards
developers. It explains the basic working of the RRC, and various UE procedure
schemes (connection, reestablishment, handover) including their interworking
with other layers.
User documentation, such as general configuration options, are described in [a
separate page](./rrc-usage.md).
[[_TOC_]]
# General
5G RRC is basically an ITTI message queue with associated handlers. It
sequentially reads received ITTI messages and handles them through the function
`rrc_gnb_task()` (constituing the thread entry point function). In this
function, one can see three main groups of messages in a big switch statement:
- NGAP (messages starting with `NGAP_`)
- F1AP (messages starting with `F1AP_`)
- E1AP (messages starting with `E1AP_`)
For each message, a corresponding handler is called. The messages are roughly
named according to the 3GPP specification messages, so it should already be
possible to find the message in the switch based on a message name in the spec.
Note that RRC is inherently single-threaded, and processes messages in a FIFO
order.
# Sequence Diagrams of UE procedures
The following section presents a number of common UE procedures for connection
establishment&control, bearer establishment, etc. The intention is to help
developers find specific functions within RRC in the context of these
procedures. For more information on message handlers at F1 and E1 layers,
please refer to the respective [F1 documentation](../F1AP/F1-design.md) and [E1
documentation](../E1AP/E1-design.md).
For more information on these procedures, please also refer to 3GPP TS 38.401
(NG-RAN Architecture Description) and O-RAN.WG5.C.1-v11 (NR C-plane profile).
A lot of the following diagrams would show an exchange between CU-CP, DU, and
UE, in which the CU-CP forwards an "RRC Message" to the UE via an F1AP DL RRC
Message Transfer through the DU, and correspondingly receives the "RRC Message
Answer", as follows:
```mermaid
sequenceDiagram
participant ue as UE
participant du as DU
participant cucp as CU-CP
cucp->>du: F1AP DL RRC Msg Transfer (RRC Message)
du->>ue: RRC Message
ue->>du: RRC Message Answer
du->>cucp: F1AP UL RRC Msg Transfer (RRC Message Answer)
```
To better utilize horizontal space, these exchanges have been collapsed as
follows, but should be read as the above exchange:
```mermaid
sequenceDiagram
participant ue as UE
participant du as DU
participant cucp as CU-CP
cucp->>ue: F1AP DL RRC Msg Transfer (RRC Message)
ue->>cucp: F1AP UL RRC Msg Transfer (RRC Message Answer)
```
## Initial connection setup/Registration
This sequence diagram shows the principal steps for an initial UE connection.
This can either happen through a _Registration Request_ (e.g., UE connects
"from flight mode"), or a _Service Request_ (i.e., UE connects after leaving
coverage). Both requests are handled similarly by the gNB, and basically
distinguish themselves, from the point of view of the gNB, by having PDU
sessions in the NGAP Initial Context Setup Request present (Service Request) or
not (Registration Request, with following PDU Session Resource Setup Request
procedure).
```mermaid
sequenceDiagram
participant ue as UE
participant du as DU
participant cucp as CU-CP
participant cuup as CU-UP
participant amf as AMF
ue->>du: Msg1/Preamble
du->>ue: Msg2/RAR
ue->>cucp: F1AP Initial UL RRC Msg Tr (RRC Setup Req, in Msg3)
Note over cucp: rrc_handle_RRCSetupRequest()
cucp->>ue: F1AP DL RRC Msg Transfer (RRC Setup, in Msg4)
ue->>cucp: F1AP UL RRC Msg Transfer (RRC Setup Complete)
Note over cucp: rrc_handle_RRCSetupComplete()
%% TODO: when is RRC connected?
cucp->>amf: NGAP Initial UE Message (NAS Registration/Service Req)
Note over amf,ue: NAS Authentication Procedure (see 24.501)
Note over amf,ue: NAS Security Procedure (see 24.501)
amf->>cucp: NGAP Initial Context Setup Req
Note over cucp: rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ()
Note over cucp: rrc_gNB_generate_SecurityModeCommand()
cucp->>ue: F1AP DL RRC Msg Transfer (RRC Security Mode Command)
ue->>cucp: F1AP UL RRC Msg Transfer (RRC Security Mode Complete)
Note over cucp: rrc_gNB_decode_dcch() (inline)
opt No UE Capabilities present
Note over cucp: rrc_gNB_generate_UECapabilityEnquiry()
cucp->>ue: F1AP DL RRC Msg Transfer (RRC UE Capability Enquiry)
ue->>cucp: F1AP UL RRC Msg Transfer (RRC UE Capability Information)
Note over cucp: handle_ueCapabilityInformation()
end
opt PDU Sessions in NGAP Initial Context Setup Req present
Note over cucp: trigger_bearer_setup()
cucp->>cuup: E1AP Bearer Context Setup Req
cuup->>cucp: E1AP Bearer Context Setup Resp
Note over cucp: rrc_gNB_process_e1_bearer_context_setup_resp()
cucp->>du: F1AP UE Context Setup Req
du->>cucp: F1AP UE Context Setup Resp
Note over cucp: rrc_CU_process_ue_context_setup_response()
Note over cucp: e1_send_bearer_updates()
cucp->>cuup: E1AP Bearer Context Modification Req
cucp->>ue: F1AP DL RRC Msg Transfer (RRC Reconfiguration)
cuup->>cucp: E1AP Bearer Context Modification Resp
ue->>cucp: F1AP UL RRC Msg Transfer (RRC Reconfiguration Complete)
Note over cucp: handle_rrcReconfigurationComplete()
end
Note over cucp: rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP()
cucp->>amf: NGAP Initial Context Setup Resp (NAS Registration/Service Complete)
```
Note that if no PDU session is present in the NGAP Initial UE Context Setup
Req, no F1AP UE Context Setup will be observed during this initial phase.
If there is no PDU session set up during NGAP Initial Context Setup Req, the UE
typically requests a PDU session(s) through a NAS procedure, which is basically
the same code paths as the above optional PDU Session setup during an NGAP
Initial Context Setup procedure:
```mermaid
sequenceDiagram
participant ue as UE
participant du as DU
participant cucp as CU-CP
participant cuup as CU-UP
participant amf as AMF
ue->>cucp: F1AP UL RRC Msg Transfer (RRC UL Information Transfer)
cucp->>amf: NGAP UL NAS Transport (NAS PDU Session Establishment Req)
amf->>cucp: NGAP PDU Session Resource Setup Req (NAS PDU Session Establishment Accept)
Note over cucp: rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ()
Note over cucp: trigger_bearer_setup()
cucp->>cuup: E1AP Bearer Context Setup Req
cuup->>cucp: E1AP Bearer Context Setup Resp
Note over cucp: rrc_gNB_process_e1_bearer_context_setup_resp()
cucp->>du: F1AP UE Context Setup Req
du->>cucp: F1AP UE Context Setup Resp
Note over cucp: rrc_CU_process_ue_context_setup_response()
Note over cucp: e1_send_bearer_updates()
cucp->>cuup: E1AP Bearer Context Modification Req
cucp->>ue: F1AP DL RRC Msg Transfer (RRC Reconfiguration + NAS PDU Session Establishment Accept)
cuup->>cucp: E1AP Bearer Context Modification Resp
ue->>cucp: F1AP UL RRC Msg Transfer (RRC Reconfiguration Complete)
Note over cucp: handle_rrcReconfigurationComplete()
Note over cucp: rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP()
cucp->>amf: NGAP PDU Session Resource Setup Resp
```
## Reestablishment
The following sequence diagram shows the principal steps during a
reestablishment request. When handling the RRC Reestablishment Request at the
CU-CP, it notably checks if this UE is already known, if the UE is still at the
same DU as it used to be previously (might change because of, or despite
handover), and other validation checks. If all checks pass, the CU-CP continues
with the reestablishment procedure; if any check fails, the CU-CP tries to
release the old UE at the AMF, and continues with the "normal" connection setup
(registration/service request) described above.
```mermaid
sequenceDiagram
participant ue as UE
participant du as DU
participant cucp as CU-CP
participant cuup as CU-UP
participant amf as AMF
ue->>du: Msg1/Preamble
du->>ue: Msg2/RAR
ue->>du: Msg3 w/ RRC Reestabishment Request (old C-RNTI/PCI)
Note over du: DU creates UE context for new RNTI
du->>cucp: F1AP Initial UL RRC Msg Tr (RRC Reestab Req, in Msg3)
Note over cucp: rrc_handle_RRCReestablishmentRequest()
alt UE known and at the original DU
Note over cucp: rrc_gNB_generate_RRCReestablishment()<br />SRB1 PDCP reestablishment
cucp->>du: F1AP DL RRC Msg Tr (old gNB-DU-UE ID)
Note over du: Reuse configuration of and delete old UE<br />(in dl_rrc_message_transfer())
du->>ue: RRC Reestablishment
ue->>du: RRC Reestablishment Complete
du->>cucp: F1AP UL RRC Msg Tr (RRC Reestab Complete)
Note over cucp: handle_rrcReestablishmentComplete()
Note over cucp: cuup_notify_reestablishment()
cucp->>cuup: E1AP Bearer Context Modification Req
cucp->>ue: F1AP DL RRC Msg Transfer (RRC Reconfiguration)
cuup->>cucp: E1AP Bearer Context Modification Resp
ue->>cucp: F1AP UL RRC Msg Transfer (RRC Reconfiguration Complete)
Note over cucp: handle_rrcReestablishmentComplete()
else Fallback*
cucp->>amf: NGAP UE Context Release Request
Note over cucp: rrc_gNB_generate_RRCSetup()
Note over ue,amf: Continue with connection setup (registration/service request)
end
```
## Handover
The basic handover (HO) structure is as follows. In order to support various
handover "message passing implementation" (F1AP, NGAP, XnAP), RRC employs
callbacks to signal HO Accept (`ho_req_ack()`), HO Success (`ho_success()`),
and HO Cancel (`ho_cancel()`). These can be used to trigger the corresponding
functionality based on mentioned "message passing implementation".
The following sequence diagram shows the basic functional execution of a
successful handover in the case of an F1 handover. Note the callbacks as
mentioned above:
```mermaid
sequenceDiagram
participant ue as UE
participant sdu as source DU
participant tdu as target DU
participant cucp as CU-CP
participant cuup as CU-UP
Note over ue,sdu: UE active on source DU
alt HO triggered through A3 event
ue->>sdu: RRC Measurement Report
sdu->>cucp: F1AP UL RRC Msg Transfer (RRC Measurement Report)
Note over cucp: Handover decision (A3 event trigger)
else Manual Trigger
Note over cucp: Handover decision (e.g., telnet)
end
Note over cucp: nr_rrc_trigger_f1_ho() ("on source CU")
Note over cucp: nr_initiate_handover() ("on target CU")
cucp->>tdu: F1AP UE Context Setup Req
Note over tdu: Create UE context
tdu->>cucp: F1AP UE Context Setup Resp (incl. CellGroupConfig)
Note over cucp: rrc_CU_process_ue_context_setup_response() ("on target CU")
Note over cucp: cuup_notify_reestablishment()
cucp->>cuup: E1AP Bearer Context Modification Req
cucp-->>cucp: callback: ho_req_ack()
Note over cucp: nr_rrc_f1_ho_acknowledge() ("on source CU")
cucp->>sdu: F1AP Context Modification Req (RRC Reconfiguration)
cuup->>cucp: E1AP Bearer Context Modification Resp
sdu->>ue: RRC Reconfiguration
sdu->>cucp: F1AP Context Modification Resp
Note over sdu: Stop scheduling UE
Note over ue: Resync
Note over ue,tdu: RA (Msg1 + Msg2)
ue->>tdu: RRC Reconfiguration Complete
tdu->>cucp: F1AP UL RRC Msg Transfer (RRC Reconfiguration Complete)
Note over cucp: handle_rrcReconfigurationComplete() ("on target CU")
cucp-->>cucp: callback: ho_success()
Note over cucp: nr_rrc_f1_ho_complete() ("on source CU")
cucp->>sdu: F1AP UE Context Release Command
sdu->>cucp: F1AP UE Context Release Complete
Note over ue,tdu: UE active on target DU
```
# Structures
## Cells
OAI 5G RRC does not actually handle multiple cells as of now, but multiple DUs,
each being limited to one cell.
Cell-related data is stored in `nr_rrc_du_container_t`, and kept in a tree
indexed by the SCTP association ID.
## CU-UPs
CU-UP information is stored in `nr_rrc_cuup_container_t`, and kept in a tree
indexed by the SCTP association ID.
## Transactions
The RRC keeps track of ongoing transaction (RRC procedures) through a per-UE
array `xids`, which is indexed with a transaction ID `xid` in `[0,3]` to keep
track of ongoing transactions. Upon RRC Reconfiguration Complete, these IDs are
deleted.
Note that while 38.331 requires only one RRC transaction to happen at a time,
the 5G RRC does not actually ensure this; it only tries to prevent it by
chaining of transactions and some checks. For instance, the Security Mode
procedure is followed by a UE capability procedure, and some procedures are not
executed if others are ongoing (ex.: handover if there is reconfiguratio).
However, it might be possible to trigger a procedure while another is ongoing.
As of now, no queueing mechanims exists to ensure only one operation is
ongoing, which would likely also simplify the code.
## Handover
Handover-related data is stored in a per-UE structure of type
`nr_handover_context_t`. It is a pointer and only set during handover
operation. This data structure has in turn two pointers, one to the source CU
(`nr_ho_source_cu_t`), and one to the target CU (`nr_ho_target_cu_t`). In F1,
both are present. In N2 and Xn, only one pointer is supposed to be set a the
corresponding CU.
`nr_ho_source_cu_t` contains notably a function pointer `ho_cancel` for
handover cancel. `nr_ho_target_cu_t` contains function pointers `ho_req_ack`
for handover request acknowledge and `ho_success` for handover success. As can
be seen in the sequence diagram above, either the "target CU" or "source CU"
needs to do an operation, and a "switch" from target to source CU is done using
these function pointers. For instance, in F1, the handover request acknowledge
function pointers merely calls another (RRC) function which triggers a
reconfiguration. In the case of N2, the handover request acknowledge function
pointer should trigger the NGAP Handover Request Acknowledge, and the handover
success function pointer should trigger the NGAP Handover Success message.
+99
View File
@@ -0,0 +1,99 @@
This document describes the basic functioning of the 5G RRC layer, describes
the periodic output, and explains the various configuration options that
influence its behavior.
Developer documentation, such as UE connection control flow, reestablishment, or handover, are described in [a separate page](./rrc-dev.md).
[[_TOC_]]
# General
The RRC layer controls the basic connection setup of UEs as well as additional
procedures. It is the fundamental building block of OAI's CU-CP, and interacts
with lower layers (DU, basically MAC and RLC) through F1AP messages, and with
the CU-UP through E1AP messages. More information can be found in the
respective [F1AP page](../F1-design.md) and [E1AP page](../E1AP/E1-design.md).
# Periodic output and interpretation
Similarly to the scheduler, the RRC periodically prints information about
connected UEs and DUs into file `nrRRC_stats.log` in the current working
directory of the executable running the RRC (typically, `nr-softmodem`). The
output lists first all UEs that are currently connected, and then all DUs, in
order.
For each UE, it prints:
```
UE 0 CU UE ID 1 DU UE ID 40352 RNTI 9da0 random identity c0f1ac9824000000:
last RRC activity: 5 seconds ago
PDU session 0 ID 10 status established
associated DU: DU assoc ID 8
```
where `UE 0` is the UE index, CU UE ID and DU UE IDs are the IDs used to
exchange over F1 (cf. scheduler logs). Further, it shows RNTI, when the last
RRC activity happened, the status of PDU sessions and which DU is associated
(through the SCTP association ID).
For each DU, it prints:
```
1 connected DUs
[1] DU ID 3584 (gNB-OAI-DU) assoc_id 8: nrCellID 12345678, PCI 0, SSB ARFCN 641280
TDD: band 78 ARFCN 640008 SCS 30 (kHz) PRB 106
```
i.e., an index (`[1]`), the DU ID and it's name, the SCTP association ID
(`assoc_id 8`, cf. UE information), and DU specific information for the cell
(cell ID, physical cell identity/PCI, the SSB frequency in ARFCN notation, the
band and Point A ARFCN, subcarrier spacing/SCS, and the number of resource
blocks/PRB). Only one cell per DU is supported.
As of now, it does not print information about connected CU-UPs or AMFs.
# Configuration of the RRC
## Split-related options (when running in a CU or CU-CP)
See [F1 documentation](../F1-design.md) for information about the F1 split.
See [E1 documentation](../E1AP/E1-design.md) for information about the E1 split.
## RRC-specific configuration options
In the `gNBs` section of the gNB/CU/CU-CP configuration file is the
RRC-specific configuration
### cell-specific options
- `gNB_ID` and `gNB_name`: ID and name of the gNB
- `tracking_area_code`: the current tracking area code in the range `[0x0001,
0xfffd]`
- `plmn`: the PLMN, which is a list of entries consisting of:
- `mcc`: mobile country code
- `mnc`: mobile network code
- `mnc_length`: length of mobile network code, allowed values: 2, 3
- `snssaiList`: list of NSSAI (network selection slice assistence
information, "slice ID"), which itself consists in
- `sst`: slice service type, in `[1,255]`
- `sd` (default `0xffffff`): slice differentiator, in `[0,0xffffff]`,
`0xffffff` is a reserved value and means "no SD"
Note that: SST=1, no SD is "eMBB"; SST=2, no SD is "URLLC"; SST=3, no SD
is "mMTC"
- `enable_sdap` (default: false): enable the use of the SDAP layer. If
deactivated, a transparent SDAP header is prepended to packets, but no
further processing is being done.
### UE-specific configuration
- `um_on_default_drb` (default: false): use RLC UM instead of RLC AM on default
bearers
- `drbs` (default: 0): the number of DRBs to allocate for a UE, only useful for
do-ra or phy-test testing
### Neighbor-gNB configuration
TBD
Refer to the [handover tutorial](../handover-tutorial.md) for more information.
+329
View File
@@ -0,0 +1,329 @@
This tutorial explains how to perform handovers. For the moment, only F1
handovers are supported.
[[_TOC_]]
# Considered setup for F1 handover
We consider one CU and two DUs, connected over F1. The UE is initially
connected over the radio interface ("Uu") to DU0. Via movement to a new
position ("new pos"), it will trigger an event such that the CU triggers a
handover of the UE from DU0 to DU1. Alternatively, a manual trigger can do the
same.
![F1 Handover setup](./RRC/ho.png)
# Steps to run F1 handover with OAI UE
Measurement reporting and processing of RRC Reconfiguration for Mobility are
not completed at the UE. Nevertheless, it is possible to make simple handover
tests without any radio setup, on a single PC, with the OAI UE, in RFsimulator.
## Build with telnet support
Since the UE does not support any measurement reporting, it cannot trigger a
handover on its own; it has to be triggered manually through telnet. Thus,
build both gNB and UE as well as activate the build of telnet to that purpose:
./build_oai --ninja --nrUE --gNB --build-lib telnetsrv
## Run the setup
This tutorial assumes you have a core network running; [refer to the
corresponding tutorial](./NR_SA_Tutorial_OAI_CN5G.md) if this is not the case
yet.
We will use the TDD configuration files in the repository for the
[CU](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-cu.sa.f1.conf) as well for
[DU0](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band78.106prb.rfsim.pci0.conf)
and
[DU1](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band78.106prb.rfsim.pci1.conf).
Note how the DUs differ in their DU ID (for identification at the CU), nr
cellid (global identification), physical cell ID (identification through UE),
frequency (limitation at OAI UE), and IP address.
Make sure that using RFsimulator and the CU and each DU, you can achieve a full
connection of the UE (independently, i.e., running one DU a time). Once this is
done, follow below steps to trigger a handover:
Start the CU including telnet support:
sudo ./nr-softmodem --sa -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-cu.sa.f1.conf --telnetsrv --telnetsrv.shrmod ci
Start DU0:
sudo ./nr-softmodem --sa --rfsim -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band78.106prb.rfsim.pci0.conf --rfsimulator.serveraddr 127.0.0.1
Start the UE, and let it connect completely:
sudo ./nr-uesoftmodem --sa -C 3450720000 -r 106 --numerology 1 --ssb 516 -O <config> --rfsim --rfsimulator.serveraddr server
Note how the RFsimulator roles have been switched, and RFsim server is at the
UE side; _this is important_. Replace `<config>` with the UE configuration
matching your core. If you followed the CN and oaiUE tutorials, you can remove
`-O <config>` and replace it with `--uicc0.imsi 001010000000001`.
Once the UE is connected, start DU1:
sudo ./nr-softmodem --sa --rfsim -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band78.106prb.rfsim.pci1.conf --rfsimulator.serveraddr 127.0.0.1
Once DU1 is online, you can trigger a handover by issuing this command
echo ci trigger_f1_ho | nc 127.0.0.1 9090 && echo
You should see how the UE switches from one DU to another. See additional
information further below.
A number of remarks:
1. It is important that you start DU0, UE, DU1 in order, and having UE connect
to DU0 before starting DU1. This is because we don't employ any channel
emulation, and the UE could not decode the SIB1 of DU0 to connect.
1. The RFsimulator roles are switched. Typically, the gNB RFsim acts as the
server and the UE as a client. However, RFsim is limited to one server with
multiple clients. Since the UE should be able to connect to both DUs, it has
to act as the server, and both DUs are a client.
1. If you see errors `could not open a socket` and/or `Could not start the RF
device`, this means that RFsim could not be started. Handover will not work;
please refer to the preceding point to fix this (i.e., run the UE as the
RFsim server).
1. In some cases, if the RFsim server is at the UE, the whole system can block;
in this case, stop UE and all DUs and restart (the CU can keep running).
## Additional information to the manual HO trigger
You can trigger the handover manually by logging in through telnet:
telnet 127.0.0.1 9090
and then manually typing `ci trigger_f1_ho`.
The command using `nc` (`netcat`) above triggers handovers directly from bash.
It does the same as logging in through telnet otherwise, and is a shorthand.
The full command is
ci trigger_f1_ho [cu-ue-id]
`cu-ue-id` is optional. If only one UE context is present in the RRC, it will
trigger the handover for this UE in a round-robin fashion across all DUs. If
there is only one DU, the handover request will be rejected. Similarly, if
there are multiple UE contexts present at RRC, the handover will be rejected,
and you have to manually type the CU UE ID. You can see a list of all UEs in
the file `nrRRC_stats.log` that is printed periodically in the working
directory of the CU.
# Steps to run F1 handover with COTS UE
You can do handover across DUs with a COTS UE. Note that these DUs should be
separated by at least multiple meters to ensure that the UE will receive
different signal strengths when moving between cells.
We only support intra-frequency handovers yet. We have verified with USRPs
only, although other radios should work as well.
For UEs, we verified Quectel modules and iPhones. Note, though, that not all
phones might work; for instance, we did not achieve handovers with a OnePlus
Nord, yet.
## Steps
First, make sure that you can run both DUs with the CU independently. Use the
same radio hardware for both radios to ensure that both cells can be received
equally good by the UE.
In order to enable handovers (triggered by the UE), you have to configure the
neighbour relation of the DUs at the CU. To do so, proceed as follows:
1. To simplify filling the right values in the neighbour configuration, you can
rely on the information the CU has about both DUs. Start the CU and both
DUs. Navigate to the directory from which you started the CU, and print RRC
statistics:
```
cat nrRRC_stats.log
```
1. Fill in the `neighbour-config.conf` configuration file as shown below, and
`@include` it in the CU file.
1. Start the CU and both DUs.
1. Bring the phone close to one cell, and leave flight mode. It should connect
to the DU to which it is closer.
1. Move the UE towards the other DU; it should trigger an "A3 event" (Neighbour
Becomes Better than Serving), and the CU will trigger the handover to the
other DU.
The output on the terminal should be the same as with RFsim. If no handover is
triggered:
- Make sure that both DUs use the same hardware.
- Make sure that the UE sees both cells. For instance, you can switch to flight
mode, go closer to the other DU, and switch off flight mode -- the UE should
connect to that second UE.
- We did not manage handover with every phone yet -- make sure you use one of
the list provided above.
You can also force a handover through telnet as described above. (In fact, the
decision about a handover is always at the network-side, the UE only "assists"
through measurements telling the CU that one DU is stronger than others.
Hence, "forcing" a handover just means that you manually trigger the handover,
instead of waiting for UE measurement report.)
## Example neighbour configuration
Below is an example neighbour configuration. It is based on this DU information
gathered from `nrRRC_stats.log` at the CU:
```
[1] DU ID 3585 (gNB-in-docker) assoc_id 4161: nrCellID 11111111, PCI 1, SSB ARFCN 643296
TDD: band 78 ARFCN 642024 SCS 30 (kHz) PRB 106
[2] DU ID 3584 (gNB-in-docker) assoc_id 4163: nrCellID 12345678, PCI 0, SSB ARFCN 643296
TDD: band 78 ARFCN 642024 SCS 30 (kHz) PRB 106
```
Note how both DUs have one cell on the same frequency and the same radio
configuration. From this, fill the neighbour list as shown below.
Concretely, the first cell is `12345678` (on DU `[2]`), and it has `11111111`
(on DU `[1]`) as its neighbour; hence in the first block, you fill
`physical_cellId` and other values for DU `[1]`, and vice versa.
The below configuration further enables periodic measurements, A2 event
("Serving becomes worse than threshold"), and A3 events ("Neighbour Becomes
Better than Serving"). The A2 event can be disabled by setting `enable = 0`. A3
events cannot be disabled as of now. Further, the A3 events can be made
specific to cells; `cell_id = -1` means "any cell".
```
neighbour_list = (
{
nr_cellid = 12345678;
neighbour_cell_configuration = (
{
gNB_ID = 0xe01;
nr_cellid = 11111111;
physical_cellId = 1;
absoluteFrequencySSB = 643296;
subcarrierSpacing = 1; #30 KHz
plmn = { mcc = 001; mnc = 01; mnc_length = 2};
tracking_area_code = 1;
}
)
},
{
nr_cellid = 11111111;
neighbour_cell_configuration = (
{
gNB_ID = 0xe00;
nr_cellid = 12345678;
physical_cellId = 0;
absoluteFrequencySSB = 643296;
subcarrierSpacing = 1; #30 KHz
plmn = { mcc = 001; mnc = 01; mnc_length = 2};
tracking_area_code = 1;
}
)
}
);
nr_measurement_configuration = {
Periodical = {
enable = 1;
includeBeamMeasurements = 1;
maxNrofRS_IndexesToReport = 4;
};
A2 = {
enable = 1;
threshold = 60;
timeToTrigger = 1;
};
A3 = ({
cell_id = -1; #Default
offset = 10;
hysteresis = 0;
timeToTrigger = 1
})
};
```
# Handovers triggers and NTN
Typically, in terrestrial networks, channel measurements as well as criteria
such as load in base stations, is used to determine when and where to handover
a UE.
## NTN
Doppler spreading and time selectivity of the channel are already a challenge
for conventional terrestrial networks. However, in the context of
non-terrestrial networks (NTN), and low-earth orbit (LEO) systems, the
satellites can have speeds up 7.56 km/s, which is much faster than 0.14 km/s of
a high-speed train in terrestrial networks. Also, the delays in LEO are more varied
and longer, and the path loss is larger, because the communication distances is up
to 10 times longer than in terrestrial networks. Moreover, downlink in LEO
presents a high interference from adjacent satellite beams, and all these
features contribute to reduced received signal strength variation in these
networks compared to terrestrial networks. Typically, the criteria used in
algorithms presented in conventional terrestrial networks to trigger a handover
from a gNB to another one is based on signal strength measurements (cf., A3
event above). However, the reduced received signal strength variation in NTNs
make these algorithms inefficient for LEO systems. Therefore, algorithms with
criteria for handover triggering that address the specifics of LEO systems are
crucial for an efficient handover processing that ensures a robust
communication with low dropping probability. Some criteria for handovers in NTN
are as follows:
- **Measurement-based triggering**: This method is based on signal strength
measurement, and as stated above, it may not be efficient. The triggering
thresholds and which measurement events to use as triggers, as reference
signal received power (RSRP), reference signal received quality (RSRQ), or
received signal strength indicator (RSSI), should be configured. This method
relies on UE estimates and established channel estimation techniques, however
it would require neighbouring cell lists which can be hard because the
fast-moving of satellites leads to a fast cell coverage deviation.
- **Location-based triggering**: This method is based on UE and satellite
location, which can be applied jointly (or not) with another trigger as the
measurement-based trigger. For instance, for a deterministic satellite
movement, it is possible to predict the configure triggering condition, and
the initial association of the UE can be performed based on the distance with
the nearest satellite, because we can know the location of the UE and NTN
satellite to compute the distance.
- **Elevation angles of source and target cells based triggering**: This method
is similar to the previous one, but it is based on the largest elevation
angle.
- **Time/timer-based triggering**: This method uses triggering conditions based
on UTC time or a timer-based solution, which can also be applied jointly (or
not) with another trigger as the measurement-based trigger. The timer-based
handover trigger considers the deterministic satellite movement to predict
the time duration for which the satellite’s footprint covers a certain zone.
- **Timing advance value-based triggering**: This method uses the timing
advance value (independently or jointly with another trigger) to trigger a
handover to the target cell. It is appropriate to overcome the Random-Access
preamble reception issue, where the UE needs to pre-compensate the instant
which sends the preamble. However, UEs with GNSS support are required to
perform this method.
## Simple location/time-based trigger
A location-based handover trigger, somewhat aligned with 3GPP Rel.17, taking
advantage of deterministic satellite movement, can be implemented whereby it is
assumed that the locations of the UE and the NTN satellite are known. From a
practical point of view, this means that we know how long it takes to perform
the handover, and therefore we only need to implement a timer.
It is possible to modify the source code to trigger a time-based handover, or
combine with other methods. If all what is required is a trigger every 15
seconds, you can also resort to the telnet-based handover trigger above, and
run in a terminal:
```bash
while true; do
echo ci trigger_f1_ho | nc -N 127.0.0.1 9090 && echo
sleep 15
done
```