A UE is receiving data from one cell and then appears on another. What moved: the beam, the serving cell, the gNB, or even the core-network path? Those cases can produce similar radio logs but very different messages on Xn, NG and F1. This note follows the decision from measurements to target access and then to data-path cleanup. It starts with NR standalone (SA) in RRC_CONNECTED. NSA and inter-system mobility are separated later so that an SgNB change is not mistaken for a 5GC handover.
- What counts as mobility in NR ?
- What causes a handover decision ?
- How Xn-based handover works ?
- How N2-based handover works ?
- What if both cells belong to one gNB ?
- What does the UE receive ?
- How does user data survive ?
- How conditional handover works ?
- How DAPS handover works ?
- How L1/L2 triggered mobility differs ?
- What about NSA and inter-system mobility ?
- What happens when handover fails ?
- How to read a handover trace ?
- Key ASN.1 structures
- Examples
- Reference
What counts as mobility in NR ?
The word mobility covers several different changes. A beam switch can keep the same serving cell. A cell handover changes the UE's serving PCell. A gNB change adds context transfer between nodes, and perhaps a new route from the UPF. Before reading any message name, locate the boundary that the UE crossed.
Cell mobility and beam mobility
TS 38.300 separates cell-level mobility from beam-level mobility for an RRC_CONNECTED UE. A beam change can be controlled at PHY/MAC while the cell and RRC connection remain in place. Inter-cell beam management may even use a TRP with another PCI for UE-dedicated transmission; that alone does not prove that the PCell changed.
A cell-level handover normally applies a target-cell RRC configuration and changes the serving PCell. The UE may use a new C-RNTI, synchronize with a new cell and perform random access. The source and target may still be inside one gNB. If so, the UE performs a radio handover but no inter-gNB XnAP HANDOVER REQUEST appears. L1/L2 Triggered Mobility (LTM) is a distinct MAC-triggered cell-switch mechanism, described later, so a PCell change does not always begin with an immediate RRC handover command.
Which handover path applies ?
For a planned cell change in NR SA, first determine who controls the source and target cells. Then look for the interface that prepares the target. A link shown in a topology drawing does not prove that a particular UE used that link for its handover.
Case | Preparation | Core completion |
|---|---|---|
Intra-gNB | Internal gNB control; F1AP if source and target DUs differ | No inter-gNB Xn or N2 handover; an NG-U endpoint update depends on implementation and architecture |
Inter-gNB, Xn-based | Source and target exchange XnAP HANDOVER REQUEST / ACKNOWLEDGE | Target sends NGAP PATH SWITCH REQUEST to AMF after UE arrival |
Inter-gNB, N2-based | Source sends NGAP HANDOVER REQUIRED to AMF; AMF requests target resources | Target sends NGAP HANDOVER NOTIFY; no Xn-style path-switch step |
There is no rule that every NR SA handover uses Xn. Xn-based and N2-based are alternatives for inter-gNB preparation, not two mandatory legs of one procedure. Also, an intra-gNB handover is not synonymous with an inter-DU move: both cells can reside in one DU, or in different DUs under the same gNB-CU.
Cell change is not necessarily node change : inspect the gNB-CU boundary.Beam change is not necessarily handover : verify a PCell change and its trigger.Xn and N2 are alternatives : identify where target preparation occurred.
What causes a handover decision ?
The UE does not normally choose a target gNB for an immediate network-controlled handover. It measures, sends the configured reports, and follows the command from the network. The source gNB combines those measurements with policy, load, coverage, restrictions and target availability before it prepares a move.
Measurements and events
NR RRC MeasConfig connects a measurement object to a reporting configuration and a measurement identity. The object says which frequency and cells to measure. The report configuration defines an event or periodic reporting rule. For example, an A3 event can report a neighbour that becomes better than the serving cell by an offset. An A5 event can require the serving cell to fall below one threshold and the neighbour to rise above another.
The UE may report cell-level and beam-level quantities based on SSB or CSI-RS, such as RSRP, RSRQ or SINR. One report is evidence for the source gNB, not a command to move. Filtering, hysteresis and time-to-trigger can delay a report, while the gNB's own RRM decision can consider information that is not visible in the UE log.
The source gNB decision
The source checks whether the target can serve the UE's PDU sessions, slices and QoS flows. It may also consider UE capabilities, mobility restrictions, target-cell load and the availability of an Xn relation. The target makes its own admission decision during preparation; a good radio measurement does not guarantee admission.
This distinction is useful when debugging a trace. A MeasurementReport with a strong neighbour may be followed by no handover because the source does not select it. An XnAP HANDOVER REQUEST can fail because the target rejects resources. A prepared target can still never receive the UE because radio execution fails. Those are three different failure points and they need different evidence.
Measurement is input : the gNB decides whether to start preparation.Admission is another decision : the target can decline a requested PDU session or the whole handover.Execution is separate : preparation success does not prove that the UE reached the target.
How Xn-based handover works ?
Consider a UE moving between two gNBs that can communicate directly over Xn. The gNBs prepare the UE without involving the 5GC in the preparation and radio execution phases. The target contacts the AMF only after the UE has arrived, to move the core-network user-plane route.
Figure 1 keeps Xn-C, NR Uu, Xn-U and NG-C separate. The arrows show the principal successful path, not every optional forwarding or security message. Read the vertical order as preparation, execution and completion.
Figure 1. The target prepares the radio move over Xn, then asks the 5GC to redirect downlink traffic after the UE arrives.
The following steps use one synthetic UE: PLMN 001-01, source UE XnAP ID 12001, target UE XnAP ID 54002, PDU session 10 and DRB 1. Each JER block is a selected-IE excerpt of a decoded message, not a complete on-the-wire PDU. Encapsulated RRC and transfer containers remain hex OCTET STRINGs at the outer protocol layer.
Step 1. Source requests target admission
The source sends XnAP HANDOVER REQUEST for target NR cell 0x123456789. IE 73 ties the request to the source UE context; IE 78 identifies the target cell; IE 83 carries the UE context, including the requested PDU session.
XnAP HandoverRequest, selected-IE JER; synthetic values.
{ "initiatingMessage": { "procedureCode": 0, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 73, "criticality": "reject", "value": 12001 },
{ "id": 7, "criticality": "reject", "value": { "radioNetwork": "handover-desirable-for-radio-reasons" } },
{ "id": 78, "criticality": "reject", "value": { "nr": { "plmn-id": "00f110", "nr-CI": "1234567890" } } },
{ "id": 83, "criticality": "reject", "value": { "ng-c-UE-reference": 1870000001,
"pduSessionResourcesToBeSetup-List": [ { "pduSessionId": 10, "s-NSSAI": { "sst": "01" } } ] } }
] } } }
Step 2. Target returns an admitted configuration
The target allocates UE XnAP ID 54002 and admits session 10. XnAP HANDOVER REQUEST ACKNOWLEDGE carries its target-to-source transparent container as encoded bytes; the source later extracts the UE-facing radio command from that container.
XnAP HandoverRequestAcknowledge, selected-IE JER; synthetic values.
{ "successfulOutcome": { "procedureCode": 0, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 73, "criticality": "ignore", "value": 12001 },
{ "id": 79, "criticality": "ignore", "value": 54002 },
{ "id": 42, "criticality": "ignore", "value": [ { "pduSessionId": 10,
"pduSessionResourceAdmittedInfo": { "qosFlowsAdmitted-List": [ { "qfi": 9 } ] } } ] },
{ "id": 77, "criticality": "ignore", "value": "0140a8804a21c801" }
] } } }
Step 3. Source commands the UE and transfers status
The source sends RRCReconfiguration on Uu. The UE sees target C-RNTI 0x4A21 and T304 = 100 ms in the separately decoded masterCellGroup. For a bearer requiring PDCP continuity, the source also sends XnAP SN STATUS TRANSFER; optional Xn-U packet forwarding is GTP-U, not ASN.1.
NR RRCReconfiguration and decoded CellGroupConfig, then XnAP SNStatusTransfer; selected-IE JER.
{ "rrc-TransactionIdentifier": 1, "criticalExtensions": { "rrcReconfiguration": {
"nonCriticalExtension": { "masterCellGroup": "0408094424" } } } }
{ "cellGroupId": 0, "spCellConfig": { "reconfigurationWithSync": {
"newUE-Identity": 18977, "t304": "ms100" } } }
{ "initiatingMessage": { "procedureCode": 1, "criticality": "ignore", "value": { "protocolIEs": [
{ "id": 73, "criticality": "reject", "value": 12001 },
{ "id": 79, "criticality": "reject", "value": 54002 },
{ "id": 12, "criticality": "ignore", "value": [ { "drbID": 1,
"pdcpStatusTransfer-DL": { "pdcp-sn-18bits": { "cOUNTValue": {
"pdcp-SN18": 104, "hfn-PDCP-SN18": 0 } } } } ] }
] } } }
Step 4. UE accesses the target
The UE synchronizes and completes any required random access, then sends RRCReconfigurationComplete to the target. PRACH itself is a physical-layer procedure with no ASN.1 JER. The completion repeats transaction identifier 1 and confirms radio execution.
NR RRCReconfigurationComplete JER; synthetic values.
{ "rrc-TransactionIdentifier": 1,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
Step 5. Target switches the core path
The target sends NGAP PATH SWITCH REQUEST for the newly served UE and session 10. The AMF and 5GC update the downlink route, then return PATH SWITCH REQUEST ACKNOWLEDGE. A successful acknowledgement is the checkpoint before the target orders source release.
NGAP PathSwitchRequest and PathSwitchRequestAcknowledge, selected-IE JER.
{ "initiatingMessage": { "procedureCode": 25, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 85, "criticality": "reject", "value": 54002 },
{ "id": 100, "criticality": "reject", "value": 1870000001 },
{ "id": 76, "criticality": "reject", "value": [ { "pDUSessionID": 10,
"pathSwitchRequestTransfer": "00010a0a02141234abcd" } ] }
] } } }
{ "successfulOutcome": { "procedureCode": 25, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 10, "criticality": "ignore", "value": 1870000001 },
{ "id": 85, "criticality": "ignore", "value": 54002 },
{ "id": 77, "criticality": "ignore", "value": [ { "pDUSessionID": 10,
"pathSwitchRequestAcknowledgeTransfer": "00010a0a640a00ab1201" } ] }
] } } }
Step 6. Target releases the source context
The target sends XnAP UE CONTEXT RELEASE with both UE XnAP IDs. Those IDs identify the prepared source context to remove; releasing the UE context does not tear down the gNB-to-gNB Xn association.
XnAP UEContextRelease, selected-IE JER.
{ "initiatingMessage": { "procedureCode": 6, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 73, "criticality": "reject", "value": 12001 },
{ "id": 79, "criticality": "reject", "value": 54002 }
] } } }
Preparation between gNBs
The source sends XnAP HANDOVER REQUEST with the target cell global ID, a cause, the serving AMF identity and UE context. The context includes AS security information, PDU session resources, QoS flow information and a transparent RRC context. The target performs admission control and answers with HANDOVER REQUEST ACKNOWLEDGE. Its response includes admitted PDU sessions, a target-side XnAP UE ID and the target-to-source transparent container holding the UE's handover command.
If the target cannot accept the handover, it returns HANDOVER PREPARATION FAILURE with a cause. The source must not treat a request sent on Xn as proof that target radio resources were reserved. It also must distinguish rejected individual PDU sessions from rejection of the complete UE move.
UE execution and status transfer
The source forwards the target-generated RRCReconfiguration over NR Uu. The UE applies the target configuration, synchronizes and accesses the target cell. On success it sends RRCReconfigurationComplete to the target. For an ordinary handover, the source may forward buffered downlink data over Xn-U and sends XnAP SN STATUS TRANSFER where PDCP status preservation applies.
The status message is not the handover command. It tells the target which PDCP COUNT values and receive state belong to the transferred DRBs. The forwarding tunnel is not an XnAP message either. In a trace, separate the Xn-C SCTP association from Xn-U GTP-U packets before reasoning about packet loss.
5GC path switch and source release
After target access, the target sends NGAP PATH SWITCH REQUEST on NG-C. The AMF coordinates the 5GC user-plane change; the UPF starts sending new downlink packets toward the target. NGAP PATH SWITCH REQUEST ACKNOWLEDGE confirms the switch. The target then sends XnAP UE CONTEXT RELEASE to the source so the old UE radio and control-plane context can be freed.
The Xn peer relation itself stays available. Also, forwarded packets can still arrive after the path switch while end markers and old tunnels are being drained. Do not equate the first packet at the target with completion of the whole handover. In TS 38.300 clause 9.2.3.2.1, the release follows the path-switch acknowledgement.
Xn prepares : the source and target exchange the UE context directly.NR Uu executes : the UE receives RRCReconfiguration and accesses the target.NG completes : the target requests path switch before source context release.
How N2-based handover works ?
An inter-gNB handover can use the 5GC to prepare the target instead of using Xn between the gNBs. This is called N2-based or NG-based handover. It is relevant when direct Xn preparation is unavailable or unsuitable, and it can support a core-network control-plane change. The exact core-internal sequence depends on whether AMF or UPF relocation is needed.
Figure 2 shows a same-AMF example. It deliberately shows the AMF between the gNBs: the source does not send an XnAP HANDOVER REQUEST to the target in this path.
Figure 2. N2 preparation routes through the AMF, so successful target arrival is reported with HANDOVER NOTIFY rather than an Xn-style path-switch request.
These N2 examples reuse AMF UE ID 1870000001 and PDU session 10 but show a separate, core-assisted path. The JER excerpts select the fields that explain each arrow; a production PDU contains additional mandatory context and transfer details. At NGAP level, transparent containers are encoded OCTET STRINGs.
Step 1. Source asks the AMF to initiate handover
NGAP HANDOVER REQUIRED identifies the UE, the target gNB and the affected session. The source-to-target container passes encoded radio context through the AMF; this is not an XnAP exchange.
NGAP HandoverRequired, selected-IE JER; synthetic values.
{ "initiatingMessage": { "procedureCode": 12, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 10, "criticality": "reject", "value": 1870000001 },
{ "id": 85, "criticality": "reject", "value": 12001 },
{ "id": 29, "criticality": "reject", "value": "intra5gs" },
{ "id": 105, "criticality": "reject", "value": { "targetRANNodeID": {
"globalRANNodeID": { "globalGNB-ID": { "pLMNIdentity": "00f110",
"gNB-ID": { "gNB-ID": { "length": 24, "value": "000023" } } } },
"selectedTAI": { "pLMNIdentity": "00f110", "tAC": "000102" } } } },
{ "id": 61, "criticality": "reject", "value": [ { "pDUSessionID": 10,
"handoverRequiredTransfer": "00" } ] },
{ "id": 101, "criticality": "reject", "value": "0102a03b5c90" }
] } } }
Step 2. AMF requests target admission
The AMF sends NGAP HANDOVER REQUEST to the target. Its session list requests PDU session 10 and slice SST 1; the target uses the transferred context to allocate radio resources and a target-side UE association.
NGAP HandoverRequest, selected-IE JER.
{ "initiatingMessage": { "procedureCode": 13, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 10, "criticality": "reject", "value": 1870000001 },
{ "id": 29, "criticality": "reject", "value": "intra5gs" },
{ "id": 73, "criticality": "reject", "value": [ { "pDUSessionID": 10,
"s-NSSAI": { "sST": "01", "sD": "010203" },
"handoverRequestTransfer": "00010a0a640a00ab1201" } ] },
{ "id": 101, "criticality": "reject", "value": "0102a03b5c90" }
] } } }
Step 3. Target admits the UE
NGAP HANDOVER REQUEST ACKNOWLEDGE returns target RAN UE ID 54002, the admitted session and a target-to-source transparent container. The AMF relays that radio container to the source in the next step.
NGAP HandoverRequestAcknowledge, selected-IE JER.
{ "successfulOutcome": { "procedureCode": 13, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 10, "criticality": "ignore", "value": 1870000001 },
{ "id": 85, "criticality": "ignore", "value": 54002 },
{ "id": 53, "criticality": "ignore", "value": [ { "pDUSessionID": 10,
"handoverRequestAcknowledgeTransfer": "00010a0a02141234abcd" } ] },
{ "id": 106, "criticality": "reject", "value": "0140a8804a21c801" }
] } } }
Step 4. AMF commands the source; source commands the UE
NGAP HANDOVER COMMAND returns the accepted session and target radio container to the source. The source sends its extracted RRCReconfiguration on Uu. The outer RRC JER shows the encoded masterCellGroup; the separate CellGroupConfig decoding identifies the target C-RNTI and T304.
NGAP HandoverCommand, selected-IE JER.
{ "successfulOutcome": { "procedureCode": 12, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 10, "criticality": "reject", "value": 1870000001 },
{ "id": 85, "criticality": "reject", "value": 12001 },
{ "id": 59, "criticality": "ignore", "value": [ { "pDUSessionID": 10,
"handoverCommandTransfer": "00010a0a0214" } ] },
{ "id": 106, "criticality": "reject", "value": "0140a8804a21c801" }
] } } }
{ "rrc-TransactionIdentifier": 1, "criticalExtensions": { "rrcReconfiguration": {
"nonCriticalExtension": { "masterCellGroup": "0408094424" } } } }
{ "cellGroupId": 0, "spCellConfig": { "reconfigurationWithSync": {
"newUE-Identity": 18977, "t304": "ms100" } } }
Step 5. UE arrives and target notifies the AMF
The UE performs target access and sends RRCReconfigurationComplete with transaction 1. The target then reports its new UE association and target NR location in NGAP HANDOVER NOTIFY. Physical random access has no ASN.1 JER message.
NR RRCReconfigurationComplete and NGAP HandoverNotify, selected-IE JER.
{ "rrc-TransactionIdentifier": 1,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
{ "initiatingMessage": { "procedureCode": 11, "criticality": "ignore", "value": { "protocolIEs": [
{ "id": 10, "criticality": "reject", "value": 1870000001 },
{ "id": 85, "criticality": "reject", "value": 54002 },
{ "id": 121, "criticality": "ignore", "value": { "userLocationInformationNR": {
"nR-CGI": { "pLMNIdentity": "00f110", "nRCellIdentity": "1234567890" },
"tAI": { "pLMNIdentity": "00f110", "tAC": "000102" } } } }
] } } }
Step 6. AMF orders old context release
After core path handling, the AMF sends NGAP UE CONTEXT RELEASE COMMAND to the source. It identifies the source-side NGAP UE association and gives a handover-related cause. Unlike Xn handover, this is an N2 command, not XnAP UE CONTEXT RELEASE.
NGAP UEContextReleaseCommand, selected-IE JER.
{ "initiatingMessage": { "procedureCode": 41, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 114, "criticality": "reject", "value": { "uE-NGAP-ID-pair": {
"aMF-UE-NGAP-ID": 1870000001, "rAN-UE-NGAP-ID": 12001 } } },
{ "id": 15, "criticality": "ignore", "value": {
"radioNetworkCause": "successful-handover" } }
] } } }
The AMF prepares the target
The source sends NGAP HANDOVER REQUIRED with the UE's AMF and RAN NGAP IDs, target ID, cause, PDU session resource information and a source-to-target transparent container. The AMF selects or reaches the target and sends NGAP HANDOVER REQUEST. The target receives security context, allowed slice information and the PDU sessions to establish. It admits resources and returns NGAP HANDOVER REQUEST ACKNOWLEDGE with the admitted list and a target-to-source transparent container.
The AMF sends NGAP HANDOVER COMMAND to the source. Its transparent container carries the radio command generated for the target. If preparation fails, a HANDOVER PREPARATION FAILURE or HANDOVER FAILURE appears on the relevant N2 leg instead of a usable command. The two messages named HANDOVER REQUEST on Xn and NG are different protocol messages; always read their interface and sender.
The UE moves to the target
The source transmits the NR RRCReconfiguration handover command. The UE synchronizes to the target cell, obtains uplink timing if required and sends RRCReconfigurationComplete to the target. An N2-based handover can use direct or indirect data forwarding when arranged by the network, but that forwarding is a user-plane path, not an XnAP preparation transaction.
The target-generated RRC configuration reaches the UE through two control-plane relays: target to AMF, then AMF to source. The UE does not see this distinction on Uu. That is why an isolated RRC trace cannot tell whether target preparation used Xn or N2; a gNB or AMF trace is needed.
Completion is not an Xn path switch
After the UE arrives, the target sends NGAP HANDOVER NOTIFY to the AMF. The 5GC completes the session and user-plane update, including any needed SMF and UPF actions. The AMF later orders the old source context to be released with NGAP UE CONTEXT RELEASE COMMAND. An XnAP UE CONTEXT RELEASE is not expected, because XnAP did not prepare this handover.
Do not look for NGAP PATH SWITCH REQUEST as the mandatory completion message here. That request belongs to the Xn-prepared path, where the core first learns that the UE moved after target access. In N2 handover, the AMF participated from the beginning. The distinction is especially useful when a trace starts only at the completion phase.
HANDOVER REQUIRED identifies N2 preparation : it runs from source to AMF.HANDOVER NOTIFY identifies arrival : it runs from target to AMF.No XnAP request is required : do not infer one from the RRC handover command.
What if both cells belong to one gNB ?
A gNB can implement multiple cells. It can also split its control plane into a gNB-CU and one or more gNB-DUs. Thus, intra-gNB handover means that the source and target cells remain under one logical gNB; it does not necessarily mean one DU or one physical box. The UE still sees a target-cell radio change.
Figure 3 distinguishes two useful cases. The same-DU move is largely local inside the gNB. An inter-DU move needs F1 control and user-plane updates, even though it does not become an inter-gNB Xn or N2 handover.
Figure 3. The CU boundary, not the number of cells or DUs, decides whether a move is still intra-gNB.
Figure 3 is an architecture view rather than a message timeline. Read it as two preparation choices followed by the same UE-facing switch. The compact JER examples below show the target-cell radio command; only the inter-DU branch needs F1AP between the CU and a different target DU.
Step 1. Prepare the target cell
For a same-DU move, the gNB prepares Cell B locally. For an inter-DU move, the CU can request target UE context setup on the target DU. The F1AP IDs identify the CU and target DU context; SpCell ID identifies the target NR cell. This is not XnAP preparation.
Inter-DU F1AP UEContextSetupRequest, selected-IE JER; synthetic values.
{ "initiatingMessage": { "procedureCode": 5, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 40, "criticality": "reject", "value": 3001 },
{ "id": 63, "criticality": "reject", "value": {
"pLMN-Identity": "00f110", "nRCellIdentity": "1234567890" } }
] } } }
The target DU responds with its DU UE F1AP ID when it has reserved radio resources. Subsequent F1-U routing is internal to the gNB; it does not imply a core-network path switch.
Inter-DU F1AP UEContextSetupResponse, selected-IE JER.
{ "successfulOutcome": { "procedureCode": 5, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 40, "criticality": "reject", "value": 3001 },
{ "id": 41, "criticality": "reject", "value": 7201 }
] } } }
Step 2. Send and complete the cell-change command
The CU sends the UE an RRCReconfiguration for Cell B. Its masterCellGroup OCTET STRING decodes to a CellGroupConfig with the new target C-RNTI and T304. After target access, the UE sends RRCReconfigurationComplete with the same transaction identifier.
NR RRC command, decoded target configuration and completion JER.
{ "rrc-TransactionIdentifier": 2, "criticalExtensions": { "rrcReconfiguration": {
"nonCriticalExtension": { "masterCellGroup": "0408094424" } } } }
{ "cellGroupId": 0, "spCellConfig": { "reconfigurationWithSync": {
"newUE-Identity": 18977, "t304": "ms100" } } }
{ "rrc-TransactionIdentifier": 2,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
Same gNB-DU
When the source and target cells belong to one DU, the gNB can prepare the change locally. The CU may still manage the UE's RRC and bearer configuration over F1, but there is no target peer gNB to receive XnAP HANDOVER REQUEST. The UE receives a target-cell RRCReconfiguration and performs the indicated synchronization or access procedure.
Do not confuse a PCell handover with an SCell activation. Carrier aggregation can add or activate a secondary cell while the PCell stays where it is. A true handover changes the serving PCell context. Conversely, a beam or TRP switch can change the radio transmission point without changing the PCell at all.
Different gNB-DUs under one CU
If the target cell belongs to another DU under the same CU, the CU prepares resources on that target DU. F1AP UE CONTEXT SETUP or modification and F1-U tunnel changes may appear; the CU then sends the handover command to the UE and releases the old DU context after success. The exact F1 sequence depends on deployment and procedure variant.
This is the distinction a DU trace makes visible. There may be F1AP signalling even though there is no XnAP inter-gNB handover. If the source and target also share a CU-UP, the NG-U endpoint toward the UPF may remain stable while internal F1-U routing changes. Do not assert that every intra-gNB move needs an NGAP path switch.
Intra-gNB is a logical boundary : multiple DUs and cells may sit beneath one CU.F1 is not Xn : an inter-DU move can be visible on F1 without any inter-gNB XnAP request.
What does the UE receive ?
Whether the target was prepared internally, over Xn or through the AMF, the UE needs a radio command it can apply. For an ordinary NR RRC handover, that command is an RRCReconfiguration with target-cell configuration. The UE's response is RRCReconfigurationComplete after it has reached the target.
The target-generated RRC command
The RRCReconfiguration can carry a CellGroupConfig in its masterCellGroup container. Inside the SpCell configuration, reconfigurationWithSync gives the UE information for the target PCell: a new UE identity (C-RNTI), timer T304 and optionally dedicated RACH configuration. The target also provides the radio configuration needed to access without first reading the full target broadcast configuration.
For inter-gNB handover, the target creates the target-side configuration and passes it back in a transparent container. The source delivers it on Uu. The same RRC message name can therefore appear in both Xn and N2 handovers. Its presence does not identify the network-side preparation path. The source/target cell identities, the reconfigurationWithSync content and the matching XnAP or NGAP exchange provide that distinction.
Target access and random access
The UE synchronizes to the target's downlink and obtains an uplink opportunity. The command can provide dedicated contention-free RACH resources associated with SSB or CSI-RS beams. Otherwise the UE may use common RACH resources. Successful random access establishes target timing; the UE then sends RRCReconfigurationComplete to the target gNB.
Some configured cases avoid random access, such as supported RACH-less handover or RACH-less LTM. Do not treat the absence of a PRACH transmission as proof that no cell switch occurred. Conversely, a PRACH alone does not prove handover: initial access, beam recovery and other procedures use PRACH too. In a radio trace, correlate PRACH with the preceding RRC or MAC trigger and the later completion message.
The target configuration is the key : look forreconfigurationWithSync, target cell and new UE identity.RACH is conditional : check the particular handover or LTM variant.RRC alone does not name Xn or N2 : pair it with network-interface messages.
How does user data survive ?
Radio handover can succeed while user data is lost, duplicated or delivered out of order. The network therefore separates three jobs: forwarding packets already on the old path, preserving PDCP sequence state where needed, and changing the UPF's downlink destination. These jobs occur at different times and on different interfaces.
Forwarding is not path switch
The source may send buffered or newly arriving downlink data to the target while the UPF still routes packets to the source. In Xn-based handover, this can use Xn-U GTP-U tunnels. In N2-based handover, direct or indirect forwarding depends on the available paths. Forwarding protects an interval of data; it does not itself change the core-network route.
A forwarding endpoint is signalled in the admission outcome for the relevant PDU session, QoS flow or DRB. A tunnel may carry packets before the UE reaches the target and may continue briefly afterward. Read its TEID and destination separately from the normal NG-U tunnel toward the UPF.
PDCP status and sequence numbers
For bearers requiring status preservation, the source sends SN STATUS TRANSFER so the target knows the next downlink PDCP COUNT and the missing uplink PDCP SDUs. COUNT combines the PDCP sequence number with the hyper-frame number. The target uses this information to avoid repeating already delivered data or skipping outstanding packets.
The rule varies with RLC mode, PDCP re-establishment, security change and special handover modes. In ordinary Xn handover, the status transfer is an XnAP message. In DAPS or conditional handover, its timing can differ because the source may continue serving or forwarding longer. A trace reader should not assume that every bearer has an identical status item.
The new NG-U route
After an Xn-prepared UE arrives, NGAP PATH SWITCH REQUEST makes the target the new downlink endpoint. The 5GC updates the UPF path and acknowledges the request. The UPF may send end markers on the old tunnel to help the RAN distinguish packets that belonged to the old route. Only then does the target release the old source UE context.
For N2 handover, the AMF and session-management functions arrange the path as part of the core-assisted procedure, and target arrival is reported by HANDOVER NOTIFY. For intra-gNB moves, internal F1-U or CU-UP routing may change without a new inter-gNB path switch. Always identify which endpoint actually changes before looking for a particular NGAP message.
Forwarding covers in-flight packets : it is temporary and may use Xn-U.Status protects sequence continuity : it is control information, not user data.Path switch changes the core route : its message depends on the handover path.
How conditional handover works ?
In an ordinary handover, the network prepares one target and then sends a command for immediate execution. A fast-changing radio link can fail before the command reaches the UE. Conditional Handover (CHO) moves target preparation earlier and lets the UE execute a stored target configuration when its configured condition becomes true. This changes the timing of execution, not the need for target admission.
Figure 4 shows the important gap between configuration and execution. During that gap the UE remains connected to the source while it evaluates the candidate conditions.
Figure 4. CHO separates early network preparation from the later UE-triggered radio execution.
The CHO example uses candidate ID 3 and a configured measurement ID 5. JER snippets show the control messages relevant to the timing in Figure 4. The target's RRC command is nested as encoded bytes inside the conditional configuration, so it is decoded separately below.
Step 1. Prepare candidate resources over Xn
The source sends XnAP HANDOVER REQUEST for the candidate cell before the UE's execution condition becomes true. The target returns HANDOVER REQUEST ACKNOWLEDGE with its allocated UE ID and a candidate radio container. Preparation alone does not switch the UE.
XnAP preparation request and acknowledgement, selected-IE JER.
{ "initiatingMessage": { "procedureCode": 0, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 73, "criticality": "reject", "value": 12001 },
{ "id": 78, "criticality": "reject", "value": { "nr": {
"plmn-id": "00f110", "nr-CI": "1234567890" } } },
{ "id": 158, "criticality": "reject", "value": {
"cho-trigger": "cho-initiation" } }
] } } }
{ "successfulOutcome": { "procedureCode": 0, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 73, "criticality": "ignore", "value": 12001 },
{ "id": 79, "criticality": "ignore", "value": 54002 },
{ "id": 77, "criticality": "ignore", "value": "0140a8804a21c801" },
{ "id": 159, "criticality": "reject", "value": {
"requestedTargetCellGlobalID": { "nr": {
"plmn-id": "00f110", "nr-CI": "1234567890" } } } }
] } } }
Step 2. Source installs the condition at the UE
The source sends RRCReconfiguration containing conditionalReconfiguration. Candidate ID 3 binds measurement ID 5 to a stored RRC command. The source-side RRCReconfigurationComplete only acknowledges storage; it is not evidence of target access.
NR RRC conditional configuration and source-side completion, selected-field JER.
{ "rrc-TransactionIdentifier": 2, "criticalExtensions": { "rrcReconfiguration": {
"nonCriticalExtension": { "nonCriticalExtension": { "nonCriticalExtension": {
"nonCriticalExtension": { "conditionalReconfiguration-r16": {
"condReconfigToAddModList-r16": [ { "condReconfigId-r16": 3,
"condExecutionCond-r16": [ 5 ],
"condRRCReconfig-r16": "0140a8804a21c801" } ] } } } } } } } }
{ "rrc-TransactionIdentifier": 2,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
Step 3. UE executes the stored command
When measurement condition 5 is satisfied, the UE applies candidate 3's stored command and accesses its target cell. The nested command includes target C-RNTI 0x4A21 and T304 = 100 ms. The UE's later completion is sent to the target, not back to the source.
Separately decoded candidate CellGroupConfig and target-side completion JER.
{ "cellGroupId": 0, "spCellConfig": { "reconfigurationWithSync": {
"newUE-Identity": 18977, "t304": "ms100" } } }
{ "rrc-TransactionIdentifier": 1,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
Prepare candidates before the condition
The source may prepare one or more candidate cells, possibly at different gNBs. Each candidate target returns its own configuration. The source sends the UE an RRCReconfiguration containing candidate configurations and execution conditions. The UE acknowledges this configuration to the source but does not move yet.
TS 38.300 permits CHO conditions built from A3 or A5 events. A candidate can have one or two trigger conditions; the source determines the conditions while the candidate target determines its radio configuration. An XnAP HANDOVER REQUEST for CHO carries CHO-specific information. CHO is not supported for NG-C-based handover in Release 19, and a CHO candidate configuration cannot contain DAPS handover configuration.
The UE selects the moment to execute
The UE stays on the source while checking the configured conditions. Once a candidate condition is satisfied, the UE applies that stored target configuration, leaves the source and sends RRCReconfigurationComplete to the selected target. The target can inform the source of success. The source can then cancel unused candidate preparations and complete status transfer or forwarding for the chosen target.
Two traces can therefore show different times for the same handover: the Xn preparation may be much earlier than the UE's target access. If the UE never satisfies the condition, a prepared candidate may never become the serving cell. Do not count a CHO preparation message alone as a successful handover.
Prepared is not executed : the UE remains on the source until its condition is met.Several candidates may exist : only the selected target gets the UE.CHO is not DAPS : their candidate configurations cannot be combined.
How DAPS handover works ?
An ordinary break-before-make handover can interrupt user data while the UE leaves the source and accesses the target. Dual Active Protocol Stack (DAPS) handover reduces that interruption for configured DRBs. The UE keeps a source-side user-plane stack during target access, then releases it only after target success. DAPS is not simply a second normal handover running in parallel.
Figure 5 highlights the overlap interval. Control-plane signalling moves to the target, but source user-plane reception or transmission can continue under the DAPS rules until the target link is ready.
Figure 5. DAPS keeps selected source DRBs active until target success and an explicit source release.
Figure 5 is a timeline, so the steps below identify the messages at its three control checkpoints. The example uses DRB 1 for DAPS; other DRBs need not be DAPS bearers. The JER blocks select the DAPS-related fields and UE identifiers rather than attempting to show a complete bearer configuration.
Step 1. Prepare DAPS and command the UE
The source requests DAPS for DRB 1 in XnAP HANDOVER REQUEST. The target accepts that DRB in HANDOVER REQUEST ACKNOWLEDGE. The UE-facing RRCReconfiguration carries a radio bearer configuration whose decoded DRB item has daps-Config-r16 set to true.
XnAP DAPS preparation, selected-IE JER; synthetic values. DAPS request is nested under session forwarding information.
{ "initiatingMessage": { "procedureCode": 0, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 73, "criticality": "reject", "value": 12001 },
{ "id": 83, "criticality": "reject", "value": {
"pduSessionResourcesToBeSetup-List": [ { "pduSessionId": 10,
"dataforwardinginfofromSource": { "qosFlowsToBeForwarded": [
{ "qosFlowIdentifier": 9, "dl-dataforwarding": "dl-forwarding-proposed",
"ul-dataforwarding": "ul-forwarding-proposed" } ],
"sourceDRBtoQoSFlowMapping": [ { "drb-ID": 1,
"qosFlows-List": [ { "qfi": 9 } ],
"iE-Extension": [ { "id": 163, "criticality": "ignore",
"value": { "dapsIndicator": "daps-HO-required" } } ] } ] } } ] } }
] } } }
{ "successfulOutcome": { "procedureCode": 0, "criticality": "reject", "value": { "protocolIEs": [
{ "id": 73, "criticality": "ignore", "value": 12001 },
{ "id": 79, "criticality": "ignore", "value": 54002 },
{ "id": 164, "criticality": "reject", "value": [ { "drbID": 1,
"dapsResponseIndicator": "daps-HO-accepted" } ] }
] } } }
Separately decoded NR RadioBearerConfig excerpt for the UE.
{ "drb-ToAddModList": [ { "drb-Identity": 1,
"daps-Config-r16": "true" } ] }
Step 2. UE keeps source data while accessing target
The UE retains source-side user-plane reception while it establishes the target link. After target access it sends RRCReconfigurationComplete. The target sends XnAP HANDOVER SUCCESS to the source, naming the prepared UE and selected target cell. Neither PRACH nor the user packets are ASN.1 JER messages.
NR RRC completion and XnAP HandoverSuccess, selected-IE JER.
{ "rrc-TransactionIdentifier": 1,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
{ "initiatingMessage": { "procedureCode": 29, "criticality": "ignore", "value": { "protocolIEs": [
{ "id": 73, "criticality": "reject", "value": 12001 },
{ "id": 79, "criticality": "reject", "value": 54002 },
{ "id": 161, "criticality": "reject", "value": { "nr": {
"plmn-id": "00f110", "nr-CI": "1234567890" } } }
] } } }
Step 3. Target orders explicit source release
Once the target path is working and final status has been transferred, the target sends the UE an RRCReconfiguration with daps-SourceRelease-r16. This releases the retained source cell and ends the overlap. Its transaction identifier is new; the UE confirms this release reconfiguration separately.
NR RRC source-release command and completion, selected-field JER.
{ "rrc-TransactionIdentifier": 2, "criticalExtensions": { "rrcReconfiguration": {
"nonCriticalExtension": { "nonCriticalExtension": { "nonCriticalExtension": {
"nonCriticalExtension": { "daps-SourceRelease-r16": "true" } } } } } } }
{ "rrc-TransactionIdentifier": 2,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
Keep the source user plane during access
The source requests DAPS for selected DRBs during target preparation, and the target indicates whether it accepts. On receipt of the handover command, the UE creates target-side MAC and RLC state for those DRBs while retaining source-side user-plane operation. For DAPS DRBs, PDCP handles the two lower-layer paths with separate security and ROHC functions.
The UE can continue downlink reception from the source until source release and uplink transmission to the source until successful target random access (TS 38.300 clause 9.2.3.1). Source and target PCells are the two active cells for DAPS. The source may send EARLY STATUS TRANSFER before the normal SN STATUS TRANSFER; the timing differs from ordinary handover because source PDCP SN assignment can continue during the overlap.
Release the source only after target success
The target sends XnAP HANDOVER SUCCESS after the UE reaches it. The source then sends the required status and stops source-side delivery as the bearer procedure requires. The target explicitly tells the UE to release the source cell. DAPS is complete only after that release, not merely after target RRCReconfigurationComplete.
If target access fails while the source link is still available, the UE can fall back to its source configuration instead of immediately starting RRC re-establishment. This is one reason the source is retained. DAPS and CHO are not configured together, and TS 38.300 v19.4.0 does not support FR2-to-FR2 DAPS handover.
Overlap is per configured DRB : do not assume every bearer uses DAPS.Target access is not final release : an explicit source-cell release ends the overlap.Failure can return to source : only while the retained source link remains usable.
How L1/L2 triggered mobility differs ?
NR also supports L1/L2 Triggered Mobility (LTM). Unlike an ordinary L3 handover, the network prepares candidate cell configurations with RRC and later triggers a cell switch using a MAC control element. This can reduce the control-plane delay at the instant of the switch. It is still cell-level mobility, not merely a beam change.
Figure 6 separates candidate preparation from the short execution command. The same prepared candidates can support subsequent switches, subject to the configured rules and updates.
Figure 6. RRC prepares LTM candidates; a later MAC CE selects the target at execution time.
The example uses LTM candidate ID 2 and PCI 144. RRC candidate configuration is ASN.1 and therefore has JER; the LTM cell switch command is a MAC control element with its own binary fields, so presenting it as ASN.1 JER would be incorrect. The UE's completion is again an RRC message.
Step 1. RRC installs candidate 2
The gNB sends RRCReconfiguration with ltm-Config-r18. Its candidate entry binds ID 2 to PCI 144 and an encoded candidate RRCReconfiguration. The UE stores the candidate, then acknowledges the configuration while still served by the source cell.
NR RRCReconfiguration, selected-field JER; synthetic values.
{ "rrc-TransactionIdentifier": 1, "criticalExtensions": { "rrcReconfiguration": {
"nonCriticalExtension": { "nonCriticalExtension": { "nonCriticalExtension": {
"nonCriticalExtension": { "nonCriticalExtension": { "nonCriticalExtension": {
"ltm-Config-r18": { "setup": { "ltm-CandidateToAddModList-r18": [ {
"ltm-CandidateId-r18": 2, "ltm-CandidatePCI-r18": 144,
"ltm-CandidateConfig-r18": "0140a8804a21c801" } ] } } } } } } } } } } }
{ "rrc-TransactionIdentifier": 1,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
Step 2. Optional early synchronization
Before a switch, the UE may synchronize with candidate downlink beams and obtain target uplink timing advance. Those actions use physical-layer measurements and MAC procedures. If early UL synchronization is configured, its RRC candidate field remains an encoded OCTET STRING at this level of JER.
LTM candidate early-UL field, selected JER excerpt.
{ "ltm-CandidateId-r18": 2, "ltm-CandidatePCI-r18": 144,
"ltm-EarlyUL-SyncConfig-r18": "20018a44" }
Step 3. MAC CE selects candidate 2
The gNB sends an LTM cell switch command MAC CE selecting the prepared candidate and beam state. This is not ASN.1 and has no JER encoding. The readable field example below is deliberately not labelled JER. An actual trace contains binary MAC CE fields, not the table text.
| MAC CE field | Example | Meaning |
|---|---|---|
| Target configuration ID | 2 | Select stored LTM candidate 2 |
| Target beam indication | TCI state 7 | Use the prepared target beam state |
| Target TA | Valid | RACH-less switch may be possible |
Step 4. UE completes the switch
The UE applies candidate 2, performs RACH only if the selected branch requires it, and sends RRCReconfigurationComplete in the target cell. The transaction identifier matches the stored candidate RRC command, not the preceding MAC CE, which has no RRC transaction identifier.
Target-cell NR RRCReconfigurationComplete JER.
{ "rrc-TransactionIdentifier": 3,
"criticalExtensions": { "rrcReconfigurationComplete": {} } }
Candidate preparation and early synchronization
The network supplies candidate cell configurations before execution. It can activate target-cell TCI states early so the UE can synchronize to candidate downlink beams. It can also arrange early uplink timing-advance acquisition. These preparations make the later cell switch shorter, but the candidates are not yet serving cells.
TS 38.300 v19.4.0 supports intra- and inter-gNB LTM, including intra-frequency and inter-frequency licensed-spectrum cases. An inter-gNB case still needs context coordination between nodes; the over-the-air trigger being MAC does not eliminate network preparation. Conditional LTM (CLTM) lets the UE execute when configured conditions are met, but its supported scope is narrower: intra-gNB without dual connectivity in this release.
MAC-triggered cell switch
The gNB sends an LTM cell switch command MAC CE with a target configuration ID and beam indication. It may include target timing advance. The UE applies the stored target configuration and switches cells. With a valid target TA, RACH-less LTM can use a configured or dynamic uplink grant; without one, the UE performs RACH-based LTM. The UE sends RRCReconfigurationComplete to the target cell.
The MAC CE is the execution trigger, not the earlier RRC candidate message. After a switch, the UE resets MAC. RLC and PDCP handling depend on the network configuration. A reader should therefore not apply the ordinary RRC-handover bearer-reset rules to every LTM switch. The same candidate set may be reused for later switches rather than being rebuilt after each execution.
RRC prepares : candidate configurations exist before the switch.MAC triggers : the cell switch command selects the target configuration.RACH may be skipped : a valid TA enables the RACH-less branch.
What about NSA and inter-system mobility ?
The word 5G can mean an NR radio leg added to LTE, or an NR SA connection anchored in the 5GC. Those deployments do not use the same mobility messages. A change of NR secondary cell in NSA is not automatically an NR SA handover, and a move between 5GS and EPS changes more than a radio cell.
NSA secondary-node changes
In EN-DC, the LTE eNB is the master node connected to the EPC; the NR en-gNB is a secondary node connected to the master over X2. The UE can change its NR PSCell or SgNB while the LTE master cell remains unchanged. That procedure uses X2AP SgNB modification or change and NR RRC configuration, not an NGAP PATH SWITCH REQUEST to an AMF.
With NGEN-DC, an ng-eNB is the master on the 5GC side and a gNB is the secondary node. Their coordination uses Xn. In NR-DC, a gNB master and gNB secondary node also use Xn. The same-looking NR radio change can therefore involve X2 or Xn depending on the architecture. TS 37.340 defines the MR-DC node roles and secondary-node procedures; the Xn page shows the EN-DC and NGEN-DC messages side by side.
Handover between 5GS and EPS
Inter-system handover between NR/5GS and LTE/EPS can change the core network, security context and bearer representation in addition to the radio access node. The source cannot treat an LTE eNB as an ordinary target gNB on Xn. The core-network procedures coordinate the transfer and any supported data forwarding; the exact sequence depends on the direction and whether interworking between AMF and MME is available.
Keep three cases separate in a log: NR SA gNB-to-gNB mobility within 5GS, EN-DC secondary NR movement while LTE remains the master, and 5GS-to-EPS or EPS-to-5GS inter-system handover. Their handover commands, bearer identifiers and core-side messages differ. For example, PDU session ID and QFI belong to 5GS, while E-RAB and EPS bearer identities belong to EPS.
Architecture selects the interface : EN-DC uses X2; 5GC-based MR-DC uses Xn.Secondary-cell movement is not always master handover : check which node retains the core control-plane anchor.Inter-system adds core translation : do not read it as only a PCell change.
What happens when handover fails ?
A failed handover has at least two very different meanings. The target may reject the request before the UE receives a command, or the UE may fail to reach a target that was already prepared. The recovery action depends on which phase failed and whether the source radio link still works.
Failure before the UE moves
For Xn preparation, the target can answer HANDOVER PREPARATION FAILURE with a cause, such as resource or configuration problems. The source's preparation timer also protects against a missing outcome. For N2 preparation, target allocation can fail and the AMF returns a failure toward the source. In both cases the UE may remain on the source, because no usable target command was delivered.
Check whether rejection concerns the entire handover or only selected PDU sessions. A target can admit some resources and reject others based on its slice and QoS support. If the source later chooses a different target or route, that is a new decision, not the successful completion of the rejected request.
Failure during target access
After the RRC handover command, the UE starts the target synchronization and access procedure. T304 bounds this execution. A timeout or radio-link problem may lead to RRC connection re-establishment, which is a recovery procedure rather than the planned handover completing. The UE can select a cell for recovery that differs from both the original source and prepared target.
Special modes have exceptions. In DAPS, the UE can resume the retained source link when target access fails and source radio is still usable. In configured CHO recovery, the UE may try a stored candidate once under the specified conditions. LTM can similarly try an eligible candidate with RACH-based recovery if configured; otherwise re-establishment follows. These branches are why a failure trace must include the UE's configuration, not only the final cell identity.
For diagnosis, mark the last successful checkpoint: target acknowledgement, RRC command delivery, random access, RRCReconfigurationComplete, core path update or old-context release. A missing message after that point narrows the problem. A preparation failure should not be reported as a radio-access failure, and a target-access failure should not be blamed on an Xn request that succeeded.
Before command : inspect admission, cause and preparation timer.After command : inspect T304, target synchronization, PRACH and RRC completion.After arrival : inspect path switch or handover notify and old-context release.
How to read a handover trace ?
One UE can have several identifiers at the same time, and each interface may rename the transaction. Start from the radio command and correlate outward rather than searching for a single universal UE ID. The example below is synthetic; its values only show how to align messages across Uu, Xn and NG.
Correlate the UE across interfaces
On NR Uu, the source and target can use different C-RNTIs, and the RRC transaction identifier helps pair reconfiguration with completion. On Xn, source and target NG-RAN node UE XnAP IDs form a pair for the peer transaction. On NG, AMF-UE-NGAP-ID and RAN-UE-NGAP-ID identify the core-facing UE context. The target can allocate a new RAN-UE-NGAP-ID when it takes over.
Use PDU Session ID, DRB ID and QFI to follow the affected user plane. They answer different questions: which core session, which radio bearer and which QoS flow. A forwarding GTP-U TEID is another identifier, not a replacement for any of those. It identifies a tunnel endpoint for packets on a particular path.
Message checkpoints
Suppose a UE with source XnAP ID 420 and target XnAP ID 891 is handed over. A reader can walk the following checkpoints in order. The values are illustrative, not a capture and not fixed 3GPP assignments.
Time | Interface and message | What it proves |
|---|---|---|
10:00:00.000 | Uu MeasurementReport; neighbour PCI 321 | The source received a measurement, not yet a handover decision. |
10:00:00.018 | Xn-C HANDOVER REQUEST; source XnAP ID 420, target CGI | Inter-gNB Xn preparation began. |
10:00:00.031 | Xn-C HANDOVER REQUEST ACKNOWLEDGE; target XnAP ID 891 | The target admitted resources and supplied its radio container. |
10:00:00.038 | Uu RRCReconfiguration; target PCI 321, new C-RNTI | The UE received the execution command. |
10:00:00.052 | Uu RRCReconfigurationComplete at target | Target radio access succeeded. |
10:00:00.064 | NG-C PATH SWITCH REQUEST / ACKNOWLEDGE | The 5GC redirected the downlink path. |
10:00:00.070 | Xn-C UE CONTEXT RELEASE; IDs 420 / 891 | The source can free its old UE context. |
If the corresponding core message were HANDOVER REQUIRED before the radio command and HANDOVER NOTIFY after arrival, this would instead suggest N2 preparation. If F1AP changes appeared without XnAP or NGAP handover preparation, the move might remain inside one gNB. Always confirm the topology before choosing the interpretation.
Correlate IDs, not names alone : HANDOVER REQUEST exists on both XnAP and NGAP.Mark the preparation outcome : it is distinct from UE arrival.Mark the core outcome : radio success can precede path completion.
Key ASN.1 structures
The procedure names tell us which messages to find, but the IEs explain what each side actually knows. The listings below use the latest published Release 19 text checked for this note: TS 38.331, 38.423 and 38.413 v19.4.0. They are specification definitions, not decoded packets. Optional fields absent in one capture are not necessarily a protocol error.
NR RRC target synchronization
The ReconfigurationWithSync type sits inside the target cell-group configuration carried by RRCReconfiguration. Its mandatory newUE-Identity and t304 fields are especially useful in a handover trace. Dedicated RACH configuration and later-release options are conditional or optional, so a real command need not show all of them.
Following is based on
ReconfigurationWithSync ::= SEQUENCE {
spCellConfigCommon ServingCellConfigCommon OPTIONAL, -- Need M
newUE-Identity RNTI-Value,
t304 ENUMERATED {ms50, ms100, ms150, ms200, ms500, ms1000, ms2000, ms10000},
rach-ConfigDedicated CHOICE {
uplink RACH-ConfigDedicated,
supplementaryUplink RACH-ConfigDedicated
} OPTIONAL, -- Need N
...,
[[
smtc SSB-MTC OPTIONAL -- Need S
]],
[[
daps-UplinkPowerConfig-r16 DAPS-UplinkPowerConfig-r16 OPTIONAL -- Need N
]],
[[
sl-PathSwitchConfig-r17 SL-PathSwitchConfig-r17 OPTIONAL -- Cond DirectToIndirect-PathSwitch
]],
[[
rach-LessHO-r18 RACH-LessHO-r18 OPTIONAL, -- Need N
sl-IndirectPathMaintain-r18 ENUMERATED {true} OPTIONAL -- Cond MP
]],
[[
ltm-SchedulingRequestInfo-r19 LTM-SchedulingRequestInfo-r19 OPTIONAL, -- Cond LTM
earlyCSI-Acquisition-r19 EarlyCSI-Acquisition-r19 OPTIONAL -- Need N
]]
}
The extension groups show why an old decoder can miss a new option even when it decodes the basic handover. For example, rach-LessHO-r18 concerns RACH-less operation, while the Release 19 fields add LTM scheduling-request and early CSI support. Neither field means that every handover uses that variant.
XnAP preparation and release
The XnAP response exposes the target-side UE identifier, admitted PDU sessions and the transparent container sent onward to the UE. Later, status transfer addresses DRBs rather than PDU sessions, and UE CONTEXT RELEASE uses the source/target XnAP ID pair. That difference helps separate preparation, continuity and cleanup in a capture.
Following is based on
HandoverRequestAcknowledge ::= SEQUENCE {
protocolIEs ProtocolIE-Container {{HandoverRequestAcknowledge-IEs}},
...
}
HandoverRequestAcknowledge-IEs XNAP-PROTOCOL-IES ::= {
{ ID id-sourceNG-RANnodeUEXnAPID CRITICALITY ignore TYPE NG-RANnodeUEXnAPID PRESENCE mandatory }|
{ ID id-targetNG-RANnodeUEXnAPID CRITICALITY ignore TYPE NG-RANnodeUEXnAPID PRESENCE mandatory }|
{ ID id-PDUSessionResourcesAdmitted-List CRITICALITY ignore TYPE PDUSessionResourcesAdmitted-List PRESENCE mandatory }|
{ ID id-PDUSessionResourcesNotAdmitted-List CRITICALITY ignore TYPE PDUSessionResourcesNotAdmitted-List PRESENCE optional }|
{ ID id-Target2SourceNG-RANnodeTranspContainer CRITICALITY ignore TYPE OCTET STRING PRESENCE mandatory }|
{ ID id-UEContextKeptIndicator CRITICALITY ignore TYPE UEContextKeptIndicator PRESENCE optional }|
{ ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }|
{ ID id-DRBs-transferred-to-MN CRITICALITY ignore TYPE DRB-List PRESENCE optional }|
{ ID id-DAPSResponseInfo-List CRITICALITY reject TYPE DAPSResponseInfo-List PRESENCE optional }|
{ ID id-CHOinformation-Ack CRITICALITY reject TYPE CHOinformation-Ack PRESENCE optional }|
{ ID id-MBS-SessionInformationResponse-List CRITICALITY ignore TYPE MBS-SessionInformationResponse-List PRESENCE optional }|
{ ID id-RRCConfigIndication CRITICALITY ignore TYPE RRCConfigIndication PRESENCE optional }|
{ ID id-PDUSetbasedHandlingIndicator CRITICALITY ignore TYPE PDUSetbasedHandlingIndicator PRESENCE optional }|
{ ID id-LTMHandoverInformationRequestAcknowledge CRITICALITY ignore TYPE LTMHandoverInformationRequestAcknowledge PRESENCE optional }|
{ ID id-EarlySyncInformationResponse CRITICALITY ignore TYPE EarlySyncInformation PRESENCE optional }|
{ ID id-LTMKeptCandidateCellList CRITICALITY ignore TYPE LTMKeptCandidateCell-List PRESENCE optional },
...
}
Following is based on
SNStatusTransfer ::= SEQUENCE {
protocolIEs ProtocolIE-Container {{SNStatusTransfer-IEs}},
...
}
SNStatusTransfer-IEs XNAP-PROTOCOL-IES ::= {
{ ID id-sourceNG-RANnodeUEXnAPID CRITICALITY reject TYPE NG-RANnodeUEXnAPID PRESENCE mandatory }|
{ ID id-targetNG-RANnodeUEXnAPID CRITICALITY reject TYPE NG-RANnodeUEXnAPID PRESENCE mandatory }|
{ ID id-DRBsSubjectToStatusTransfer-List CRITICALITY ignore TYPE DRBsSubjectToStatusTransfer-List PRESENCE mandatory }|
{ ID id-CHOConfiguration CRITICALITY ignore TYPE CHOConfiguration PRESENCE optional }|
{ ID id-MobilityInformation CRITICALITY ignore TYPE MobilityInformation PRESENCE optional },
...
}
UEContextRelease ::= SEQUENCE {
protocolIEs ProtocolIE-Container {{UEContextRelease-IEs}},
...
}
UEContextRelease-IEs XNAP-PROTOCOL-IES ::= {
{ ID id-sourceNG-RANnodeUEXnAPID CRITICALITY reject TYPE NG-RANnodeUEXnAPID PRESENCE mandatory }|
{ ID id-targetNG-RANnodeUEXnAPID CRITICALITY reject TYPE NG-RANnodeUEXnAPID PRESENCE mandatory },
...
}
The optional CHO, DAPS and LTM entries are important because they show that later mobility variants extend the same XnAP procedure family. The mandatory IDs still correlate the peer UE context. For fully decoded synthetic XnAP and RRC message examples, see the Xn handover examples.
NGAP core-assisted preparation
NGAP HANDOVER REQUIRED is the source-to-AMF trigger for N2 handover. The AMF and RAN UE NGAP IDs identify the core-facing context, while TargetID and the source-to-target container identify where and how the UE should be prepared. The optional direct-forwarding indication does not make XnAP preparation mandatory.
Following is based on
HandoverRequired ::= SEQUENCE {
protocolIEs ProtocolIE-Container {{HandoverRequiredIEs}},
...
}
HandoverRequiredIEs NGAP-PROTOCOL-IES ::= {
{ ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }|
{ ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }|
{ ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory }|
{ ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }|
{ ID id-TargetID CRITICALITY reject TYPE TargetID PRESENCE mandatory }|
{ ID id-DirectForwardingPathAvailability CRITICALITY ignore TYPE DirectForwardingPathAvailability PRESENCE optional }|
{ ID id-PDUSessionResourceListHORqd CRITICALITY reject TYPE PDUSessionResourceListHORqd PRESENCE mandatory }|
{ ID id-SourceToTarget-TransparentContainer CRITICALITY reject TYPE SourceToTarget-TransparentContainer PRESENCE mandatory },
...
}
Do not identify this NGAP message only by the word HANDOVER. Its sender is the source gNB and its receiver is the AMF. The AMF then sends NGAP HANDOVER REQUEST to the target. For the Xn path, the source instead sends XnAP HANDOVER REQUEST directly to the target, and the target later sends NGAP PATH SWITCH REQUEST after UE arrival.
RRC carries the target radio configuration :newUE-Identityandt304are key fields.XnAP carries peer context : source/target IDs, admission result and status transfer are separate.NGAP carries core-assisted preparation : HANDOVER REQUIRED begins the N2 route.
Examples
The sections above use synthetic values to explain each procedure. The examples below come from real logs of an Amarisoft gNB. Each example starts with a message sequence table. It then decodes every step with the IEs that matter for the handover, taken from the log as they are.
Example 1 : NR to NR Handover
This example is a handover between two NR SA cells of one Amarisoft gNB. Cell 0x01 is PCI 500 on band n78, NR-ARFCN 632628, with its SSB at 631968. Cell 0x02 is PCI 501 on band n79, NR-ARFCN 713334, with its SSB at 712608. Both cells are TDD with 106 PRB at 30 kHz SCS. One UE registers on cell 0x01 and is then handed over to cell 0x02.
Both cells belong to the same gNB, gNB-ID 0x12345. So this is an inter-frequency handover inside one gNB, the case described in What if both cells belong to one gNB ?. No XnAP or NGAP message appears during the handover. The only NGAP traffic in the log is NG setup, registration and PDU session setup, all before the first measurement report. The same log also has a later return handover from cell 0x02 to cell 0x01. It follows the same pattern and is not repeated here.
The sequence below lists only the messages that drive the handover. The step number links to the decoded message further down. Dir gives the sender and the receiver. Cell 01 is the source cell and Cell 02 is the target cell. "gNB internal" marks a log line where the gNB changes its own UE context without sending anything over the air. PHY and MAC lines are kept only for the random access on the target cell.
Step # | Dir | Message | Comment |
|---|---|---|---|
Cell 01 -> UE | RRCReconfiguration | Measurement setup. MO 1 = SSB 631968 (n78), MO 2 = SSB 712608 (n79). Report configs A1, A2, A3. Only measId 2 (A2 on serving frequency) is linked. | |
Cell 01 -> UE | RRCReconfiguration | DRB 1 for PDU session 1. Adds measId 3 = A3 on MO 2 (n79). | |
UE -> Cell 01 | MeasurementReport | measId 2 (A2). Serving PCI 500 rsrp 56. | |
Cell 01 -> UE | RRCReconfiguration | Measurement gap setup (mgl ms6, mgrp ms40). Removes measId 2, adds measId 1 (A1). | |
UE -> Cell 01 | RRCReconfigurationComplete | Gap and A1 configuration applied. | |
UE -> Cell 01 | MeasurementReport | measId 3 (A3). Serving PCI 500 rsrp 47, neighbour PCI 501 rsrp 53. Handover trigger. | |
Cell 01 -> Cell 02 (gNB internal) | MAC: Allocating new UE 0002 | Target context created inside the gNB. No XnAP or NGAP preparation. | |
Cell 01 -> UE | RRCReconfiguration with reconfigurationWithSync | Handover command. Target PCI 501, newUE-Identity 17922 (0x4602), t304 ms1000, no dedicated RACH. | |
UE -> Cell 02 | PRACH sequence_index=7, RAR rapid=7, Msg3 | First attempt. Msg3 fails CRC five times, temporary context 0003 is freed. | |
UE -> Cell 02 | PRACH sequence_index=1 | Second preamble, snr 18.1, ta 1. | |
Cell 02 -> UE | RAR rapid=1 | Random access response for preamble 1. | |
UE -> Cell 02 | Msg3 with C-RNTI MAC CE 4602 | The gNB matches C-RNTI 0x4602 and resumes UE 0002. | |
UE -> Cell 02 | RRCReconfigurationComplete | Handover complete, 229 ms after the command. | |
Cell 01 (gNB internal) | MAC: Freeing UE 0001 on cell 01 | Source context released. No PATH SWITCH REQUEST, the gNB does not change. | |
UE -> Cell 02 | MeasurementReport | measId 2 (A2), now on the new serving frequency. PCI 501 rsrp 53. | |
Cell 02 -> UE | RRCReconfiguration | Measurement gap set up again. Adds measId 1 (A1). | |
UE -> Cell 02 | RRCReconfigurationComplete | Target cell measurement setup applied. |
Step 1. Source cell sets up the measurements
Right after registration the gNB sends the first RRCReconfiguration on cell 01. It defines the measurement objects and report configurations that later drive the handover. The message also carries the cell group configuration for the UE. That part is not related to the handover and is left out below.
Amarisoft gNB log, RRCReconfiguration, measConfig part
[RRC] DL 0001 01 DCCH-NR: RRC reconfiguration
{
message c1: rrcReconfiguration: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfiguration: {
measConfig {
measObjectToAddModList {
{
measObjectId 1,
measObject measObjectNR: {
ssbFrequency 631968,
ssbSubcarrierSpacing kHz30,
smtc1 {
periodicityAndOffset sf20: 0,
duration sf1
},
referenceSignalConfig {
ssb-ConfigMobility {
deriveSSB-IndexFromCell FALSE
}
},
quantityConfigIndex 1,
offsetMO {
},
freqBandIndicatorNR 78
}
},
{
measObjectId 2,
measObject measObjectNR: {
ssbFrequency 712608,
ssbSubcarrierSpacing kHz30,
smtc1 {
periodicityAndOffset sf20: 0,
duration sf1
},
referenceSignalConfig {
ssb-ConfigMobility {
deriveSSB-IndexFromCell FALSE
}
},
quantityConfigIndex 1,
offsetMO {
},
freqBandIndicatorNR 79
}
}
},
reportConfigToAddModList {
{
reportConfigId 1,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA1: {
a1-Threshold rsrp: 66,
reportOnLeave FALSE,
hysteresis 10,
timeToTrigger ms100
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 1,
includeBeamMeasurements FALSE
}
}
},
{
reportConfigId 2,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA2: {
a2-Threshold rsrp: 56,
reportOnLeave FALSE,
hysteresis 0,
timeToTrigger ms100
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 1,
includeBeamMeasurements FALSE
}
}
},
{
reportConfigId 3,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA3: {
a3-Offset rsrp: 6,
reportOnLeave FALSE,
hysteresis 0,
timeToTrigger ms100,
useAllowedCellList FALSE
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 8,
includeBeamMeasurements FALSE
}
}
}
},
measIdToAddModList {
{
measId 2,
measObjectId 1,
reportConfigId 2
}
},
quantityConfig {
quantityConfigNR-List {
{
quantityConfigCell {
ssb-FilterConfig {
filterCoefficientRSRQ fc3,
filterCoefficientRS-SINR fc5
},
csi-RS-FilterConfig {
}
}
}
}
},
measGapConfig {
gapUE release: NULL
}
},
... (nonCriticalExtension / masterCellGroup not shown)
}
}
}
measObject 1 is the serving SSB frequency 631968 on n78. The second one, measObject 2, is the SSB frequency 712608 on n79, where cell 0x02 lives. Three report configurations are defined. The first, reportConfig 1, is event A1 with a1-Threshold rsrp 66 and hysteresis 10. The second is event A2 with a2-Threshold rsrp 56. The third is event A3 with a3-Offset rsrp 6 and maxReportCells 8. All three use rsType ssb and timeToTrigger ms100, and report RSRP, RSRQ and SINR.
Only measId 2 is linked at this point. It ties A2 to the serving frequency. The measGapConfig is released, so no measurement gap is configured yet.
a3-Offset and hysteresis are coded in 0.5 dB steps. So a3-Offset 6 is 3 dB and hysteresis 10 is 5 dB. The rsrp thresholds are RSRP report indices, and index n means -157+n to -156+n dBm. Index 56 is -101 to -100 dBm and index 66 is -91 to -90 dBm.
Step 2. A3 is linked with the PDU session setup
The reconfiguration for PDU session setup adds DRB 1. In the same message the gNB links the A3 event to the n79 frequency.
Amarisoft gNB log, RRCReconfiguration, radioBearerConfig and measConfig
[RRC] DL 0001 01 DCCH-NR: RRC reconfiguration
{
message c1: rrcReconfiguration: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfiguration: {
radioBearerConfig {
srb-ToAddModList {
{
srb-Identity 2
}
},
drb-ToAddModList {
{
cnAssociation sdap-Config: {
pdu-Session 1,
sdap-HeaderDL absent,
sdap-HeaderUL present,
defaultDRB TRUE,
mappedQoS-FlowsToAdd {
1
}
},
drb-Identity 1,
pdcp-Config {
drb {
discardTimer infinity,
pdcp-SN-SizeUL len18bits,
pdcp-SN-SizeDL len18bits,
headerCompression notUsed: NULL,
statusReportRequired true
},
t-Reordering ms3000
}
}
}
},
measConfig {
measIdToAddModList {
{
measId 3,
measObjectId 2,
reportConfigId 3
}
}
},
... (nonCriticalExtension / masterCellGroup for DRB 1 not shown)
}
}
}
measId 3 links measObject 2 (SSB 712608, n79) to reportConfig 3 (A3). The A3 report in Step 6 comes from this measId. DRB 1 carries QoS flow 1 of PDU session 1. It uses an 18 bit PDCP SN in both directions with statusReportRequired true. This PDCP entity is re-established by the handover command in Step 8.
Step 3. UE reports A2 on the serving cell
About 15 seconds later the serving cell gets weaker, and the UE sends its first measurement report.
Amarisoft gNB log, MeasurementReport
[RRC] UL 0001 01 DCCH-NR: Measurement report
{
message c1: measurementReport: {
criticalExtensions measurementReport: {
measResults {
measId 2,
measResultServingMOList {
{
servCellId 0,
measResultServingCell {
physCellId 500,
measResult {
cellResults {
resultsSSB-Cell {
rsrp 56,
rsrq 65,
sinr 105
}
}
}
}
}
}
}
}
}
}
measId 2 is the A2 event on the serving frequency. The serving cell PCI 500 is at rsrp 56, the same index as a2-Threshold. RSRQ is 65 and SINR is 105. The report has no neighbour list, because A2 looks only at the serving cell.
Step 4. Source cell starts measurement gaps
The gNB does not hand over on an A2 report. It answers in the same millisecond with a reconfiguration that prepares the UE to measure the other frequency.
Amarisoft gNB log, RRCReconfiguration
[RRC] DL 0001 01 DCCH-NR: RRC reconfiguration
{
message c1: rrcReconfiguration: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfiguration: {
measConfig {
measIdToRemoveList {
2
},
measIdToAddModList {
{
measId 1,
measObjectId 1,
reportConfigId 1
}
},
measGapConfig {
gapUE setup: {
gapOffset 18,
mgl ms6,
mgrp ms40,
mgta ms0dot5
}
}
}
}
}
}
measGapConfig sets up a per-UE gap with gapOffset 18, mgl ms6, mgrp ms40 and mgta ms0dot5. The UE gets a 6 ms gap every 40 ms to look at SSB 712608. The reconfiguration also removes measId 2 (A2) and adds measId 1. This new measId links reportConfig 1 (A1) to the serving frequency. An A1 report tells the gNB that the serving cell has recovered above rsrp 66. The A3 link, measId 3 on n79, is not touched and stays active.
Step 5. UE confirms the gap configuration
The UE confirms the new measurement configuration with the same rrc-TransactionIdentifier 0.
Amarisoft gNB log, RRCReconfigurationComplete
[RRC] UL 0001 01 DCCH-NR: RRC reconfiguration complete
{
message c1: rrcReconfigurationComplete: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfigurationComplete: {
}
}
}
Step 6. UE reports A3 for PCI 501
The UE then reports measId 3. This is the A3 event on n79, and it is the report that triggers the handover.
Amarisoft gNB log, MeasurementReport
[RRC] UL 0001 01 DCCH-NR: Measurement report
{
message c1: measurementReport: {
criticalExtensions measurementReport: {
measResults {
measId 3,
measResultServingMOList {
{
servCellId 0,
measResultServingCell {
physCellId 500,
measResult {
cellResults {
resultsSSB-Cell {
rsrp 47,
rsrq 65,
sinr 85
}
}
}
}
}
},
measResultNeighCells measResultListNR: {
{
physCellId 501,
measResult {
cellResults {
resultsSSB-Cell {
rsrp 53,
rsrq 65,
sinr 97
}
}
}
}
}
}
}
}
}
The serving cell PCI 500 is at rsrp 47, about -110 dBm. The neighbour PCI 501 is at rsrp 53, about -104 dBm. The neighbour is 6 dB stronger, which is more than the 3 dB a3-Offset. The neighbour also has the higher SINR, 97 against 85. RSRQ is 65 for both cells. The neighbour appears in measResultListNR, the list for NR neighbour cells.
Step 7. gNB prepares the target cell internally
The gNB decides on the handover in the same millisecond. PCI 501 is its own cell 0x02, so it prepares the target without any interface message.
Amarisoft gNB log, MAC and RRC
[MAC] - 0002 02 Allocating new UE
[RRC] - 0002 02 NR band combinations
[
{
"bands": ["DL N78A + UL N78A", "DL N79A + UL N79A"],
"features_dl": [
["MIMO 2, 40 MHz, SCS 30 kHz", "MIMO 2, 40 MHz, SCS 30 kHz"]
],
"features_ul": [
["MIMO 1, 40 MHz, SCS 30 kHz", "MIMO 1, 40 MHz, SCS 30 kHz"]
]
},
{
"bands": ["DL N78A + UL N78A"],
"features_dl": [
["MIMO 2, 40 MHz, SCS 30 kHz"]
],
"features_ul": [
["MIMO 1, 40 MHz, SCS 30 kHz"]
]
},
{
"bands": ["DL N79A + UL N79A"],
"features_dl": [
["MIMO 2, 40 MHz, SCS 30 kHz"]
],
"features_ul": [
["MIMO 1, 40 MHz, SCS 30 kHz"]
]
}
]
The MAC creates UE context 0002 on cell 02. The RRC then logs the band combinations it will use for this context. They come from the UE capability, and they show that the UE supports both n78 and n79 with 2 DL layers and 1 UL layer at 40 MHz. No XnAP HANDOVER REQUEST and no NGAP HANDOVER REQUIRED is sent. In an inter-gNB handover this is the step that runs over Xn or N2.
Step 8. Source cell sends the handover command
The source cell sends RRCReconfiguration with reconfigurationWithSync. This is the handover command. It moves the UE to PCI 501 and gives it a complete configuration for the target cell. It goes out on SRB1 as a 457 byte MAC SDU on LCID 1. The dedicated part of the target cell configuration is shortened below, and the full message follows in the expandable block.
Amarisoft gNB log, RRCReconfiguration (handover command), spCellConfigDedicated shortened
[RRC] DL 0001 01 DCCH-NR: RRC reconfiguration
{
message c1: rrcReconfiguration: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfiguration: {
radioBearerConfig {
srb-ToAddModList {
{
srb-Identity 1,
reestablishPDCP true
},
{
srb-Identity 2,
reestablishPDCP true
}
},
drb-ToAddModList {
{
drb-Identity 1,
reestablishPDCP true
}
}
},
measConfig {
measObjectToRemoveList {
1,
2
},
measObjectToAddModList {
{
measObjectId 1,
measObject measObjectNR: {
ssbFrequency 712608,
ssbSubcarrierSpacing kHz30,
smtc1 {
periodicityAndOffset sf20: 0,
duration sf1
},
referenceSignalConfig {
ssb-ConfigMobility {
deriveSSB-IndexFromCell FALSE
}
},
quantityConfigIndex 1,
offsetMO {
},
freqBandIndicatorNR 79
}
},
{
measObjectId 2,
measObject measObjectNR: {
ssbFrequency 631968,
ssbSubcarrierSpacing kHz30,
smtc1 {
periodicityAndOffset sf20: 0,
duration sf1
},
referenceSignalConfig {
ssb-ConfigMobility {
deriveSSB-IndexFromCell FALSE
}
},
quantityConfigIndex 1,
offsetMO {
},
freqBandIndicatorNR 78
}
}
},
reportConfigToRemoveList {
1,
2,
3
},
reportConfigToAddModList {
{
reportConfigId 1,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA1: {
a1-Threshold rsrp: 66,
reportOnLeave FALSE,
hysteresis 10,
timeToTrigger ms100
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 1,
includeBeamMeasurements FALSE
}
}
},
{
reportConfigId 2,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA2: {
a2-Threshold rsrp: 56,
reportOnLeave FALSE,
hysteresis 0,
timeToTrigger ms100
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 1,
includeBeamMeasurements FALSE
}
}
},
{
reportConfigId 3,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA3: {
a3-Offset rsrp: 6,
reportOnLeave FALSE,
hysteresis 0,
timeToTrigger ms100,
useAllowedCellList FALSE
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 8,
includeBeamMeasurements FALSE
}
}
}
},
measIdToRemoveList {
1,
3
},
measIdToAddModList {
{
measId 2,
measObjectId 1,
reportConfigId 2
},
{
measId 3,
measObjectId 2,
reportConfigId 3
}
},
quantityConfig {
quantityConfigNR-List {
{
quantityConfigCell {
ssb-FilterConfig {
filterCoefficientRSRQ fc3,
filterCoefficientRS-SINR fc5
},
csi-RS-FilterConfig {
}
}
}
}
},
measGapConfig {
gapUE release: NULL
}
},
nonCriticalExtension {
masterCellGroup {
cellGroupId 0,
rlc-BearerToAddModList {
{
logicalChannelIdentity 4,
reestablishRLC true
},
{
logicalChannelIdentity 1,
reestablishRLC true
},
{
logicalChannelIdentity 2,
reestablishRLC true
}
},
mac-CellGroupConfig {
schedulingRequestConfig {
schedulingRequestToAddModList {
{
schedulingRequestId 0,
sr-TransMax n64
}
}
},
bsr-Config {
periodicBSR-Timer sf20,
retxBSR-Timer sf320
},
tag-Config {
tag-ToAddModList {
{
tag-Id 0,
timeAlignmentTimer infinity
}
}
},
phr-Config setup: {
phr-PeriodicTimer sf500,
phr-ProhibitTimer sf200,
phr-Tx-PowerFactorChange dB3,
multiplePHR FALSE,
dummy FALSE,
phr-Type2OtherCell FALSE,
phr-ModeOtherCG real
},
skipUplinkTxDynamic FALSE,
dataInactivityTimer release: NULL
},
physicalCellGroupConfig {
pdsch-HARQ-ACK-Codebook dynamic
},
spCellConfig {
reconfigurationWithSync {
spCellConfigCommon {
physCellId 501,
downlinkConfigCommon {
frequencyInfoDL {
absoluteFrequencySSB 712608,
frequencyBandList {
79
},
absoluteFrequencyPointA 712062,
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialDownlinkBWP {
genericParameters {
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
pdcch-ConfigCommon setup: {
controlResourceSetZero 4,
searchSpaceZero 0,
commonSearchSpaceList {
{
searchSpaceId 1,
controlResourceSetId 0,
monitoringSlotPeriodicityAndOffset sl1: NULL,
monitoringSymbolsWithinSlot '10000000000000'B,
nrofCandidates {
aggregationLevel1 n0,
aggregationLevel2 n0,
aggregationLevel4 n4,
aggregationLevel8 n0,
aggregationLevel16 n0
},
searchSpaceType common: {
dci-Format0-0-AndFormat1-0 {
}
}
}
},
searchSpaceSIB1 0,
searchSpaceOtherSystemInformation 1,
pagingSearchSpace 1,
ra-SearchSpace 1
},
pdsch-ConfigCommon setup: {
pdsch-TimeDomainAllocationList {
{
mappingType typeA,
startSymbolAndLength 40
},
{
mappingType typeA,
startSymbolAndLength 57
}
}
}
}
},
uplinkConfigCommon {
frequencyInfoUL {
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialUplinkBWP {
genericParameters {
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
rach-ConfigCommon setup: {
rach-ConfigGeneric {
prach-ConfigurationIndex 160,
msg1-FDM one,
msg1-FrequencyStart 7,
zeroCorrelationZoneConfig 15,
preambleReceivedTargetPower -110,
preambleTransMax n7,
powerRampingStep dB4,
ra-ResponseWindow sl20
},
ssb-perRACH-OccasionAndCB-PreamblesPerSSB one: n8,
ra-ContentionResolutionTimer sf64,
prach-RootSequenceIndex l139: 1,
msg1-SubcarrierSpacing kHz30,
restrictedSetConfig unrestrictedSet
},
pusch-ConfigCommon setup: {
pusch-TimeDomainAllocationList {
{
k2 7,
mappingType typeA,
startSymbolAndLength 27
},
{
k2 4,
mappingType typeA,
startSymbolAndLength 27
},
{
k2 2,
mappingType typeA,
startSymbolAndLength 27
}
},
p0-NominalWithGrant -84
},
pucch-ConfigCommon setup: {
pucch-ResourceCommon 11,
pucch-GroupHopping neither,
p0-nominal -90
}
},
dummy ms500
},
ssb-PositionsInBurst mediumBitmap: '80'H,
ssb-periodicityServingCell ms20,
dmrs-TypeA-Position pos2,
ssbSubcarrierSpacing kHz30,
tdd-UL-DL-ConfigurationCommon {
referenceSubcarrierSpacing kHz30,
pattern1 {
dl-UL-TransmissionPeriodicity ms5,
nrofDownlinkSlots 7,
nrofDownlinkSymbols 6,
nrofUplinkSlots 2,
nrofUplinkSymbols 4
}
},
ss-PBCH-BlockPower -41
},
newUE-Identity 17922,
t304 ms1000,
smtc {
periodicityAndOffset sf20: 0,
duration sf1
}
},
spCellConfigDedicated {
... (target cell dedicated PDCCH, PDSCH, PUCCH, PUSCH, SRS and CSI configuration,
see the full message below)
}
lte-CRS-ToMatchAround release: NULL
}
}
},
masterKeyUpdate {
keySetChangeIndicator FALSE,
nextHopChainingCount 0
}
}
}
}
}
radioBearerConfig sets reestablishPDCP true for SRB 1, SRB 2 and DRB 1. The rlc-BearerToAddModList sets reestablishRLC true for logical channels 4, 1 and 2. The masterKeyUpdate carries keySetChangeIndicator FALSE and nextHopChainingCount 0. So the UE derives a new key from the current key, and then re-establishes PDCP and RLC with it.
reconfigurationWithSync is the part that makes this message a handover. Its spCellConfigCommon describes the target cell with physCellId 501, absoluteFrequencySSB 712608 on band 79, absoluteFrequencyPointA 712062 and 106 PRB at 30 kHz. The TDD pattern is ms5 with 7 DL slots, 6 DL symbols, 2 UL slots and 4 UL symbols. The RACH of the target uses prach-ConfigurationIndex 160, msg1-FrequencyStart 7, ra-ResponseWindow sl20, preambleTransMax n7 and powerRampingStep dB4.
newUE-Identity 17922 is C-RNTI 0x4602. The UE used 0x4601 on the source cell. The t304 timer is ms1000, so the UE has 1 second to reach the target. There is no rach-ConfigDedicated. The UE therefore uses contention based random access on the target, as in Steps 9 to 12.
The measConfig swaps the two frequencies. Now measObject 1 is SSB 712608, the new serving frequency, and measObject 2 is SSB 631968, the old one. So measId 2 links A2 to the new serving frequency and measId 3 links A3 to the old one. The A1 link (measId 1) and the measurement gap are released. The UE starts on the target with the same measurement setup it had at the start on the source.
The source cell does not get an acknowledgement for the command. The same 457 byte SRB1 PDU is sent again on cell 01 four more times, 45 to 55 ms apart. Shortly after the command the PUSCH on cell 01 starts to fail CRC, because the UE has already left the cell.
Amarisoft gNB log, SRB1 transmissions of the command on cell 01
[MAC] DL 0001 01 LCID:1 len=457 PAD:len=17 [MAC] DL 0001 01 LCID:1 len=457 PAD:len=67 [MAC] DL 0001 01 LCID:1 len=457 PAD:len=8 [MAC] DL 0001 01 LCID:1 len=457 PAD:len=8 [MAC] DL 0001 01 LCID:1 len=457 PAD:len=27
Full RRCReconfiguration (handover command), about 990 lines, click to expand or collapse
[RRC] DL 0001 01 DCCH-NR: RRC reconfiguration
{
message c1: rrcReconfiguration: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfiguration: {
radioBearerConfig {
srb-ToAddModList {
{
srb-Identity 1,
reestablishPDCP true
},
{
srb-Identity 2,
reestablishPDCP true
}
},
drb-ToAddModList {
{
drb-Identity 1,
reestablishPDCP true
}
}
},
measConfig {
measObjectToRemoveList {
1,
2
},
measObjectToAddModList {
{
measObjectId 1,
measObject measObjectNR: {
ssbFrequency 712608,
ssbSubcarrierSpacing kHz30,
smtc1 {
periodicityAndOffset sf20: 0,
duration sf1
},
referenceSignalConfig {
ssb-ConfigMobility {
deriveSSB-IndexFromCell FALSE
}
},
quantityConfigIndex 1,
offsetMO {
},
freqBandIndicatorNR 79
}
},
{
measObjectId 2,
measObject measObjectNR: {
ssbFrequency 631968,
ssbSubcarrierSpacing kHz30,
smtc1 {
periodicityAndOffset sf20: 0,
duration sf1
},
referenceSignalConfig {
ssb-ConfigMobility {
deriveSSB-IndexFromCell FALSE
}
},
quantityConfigIndex 1,
offsetMO {
},
freqBandIndicatorNR 78
}
}
},
reportConfigToRemoveList {
1,
2,
3
},
reportConfigToAddModList {
{
reportConfigId 1,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA1: {
a1-Threshold rsrp: 66,
reportOnLeave FALSE,
hysteresis 10,
timeToTrigger ms100
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 1,
includeBeamMeasurements FALSE
}
}
},
{
reportConfigId 2,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA2: {
a2-Threshold rsrp: 56,
reportOnLeave FALSE,
hysteresis 0,
timeToTrigger ms100
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 1,
includeBeamMeasurements FALSE
}
}
},
{
reportConfigId 3,
reportConfig reportConfigNR: {
reportType eventTriggered: {
eventId eventA3: {
a3-Offset rsrp: 6,
reportOnLeave FALSE,
hysteresis 0,
timeToTrigger ms100,
useAllowedCellList FALSE
},
rsType ssb,
reportInterval ms120,
reportAmount r1,
reportQuantityCell {
rsrp TRUE,
rsrq TRUE,
sinr TRUE
},
maxReportCells 8,
includeBeamMeasurements FALSE
}
}
}
},
measIdToRemoveList {
1,
3
},
measIdToAddModList {
{
measId 2,
measObjectId 1,
reportConfigId 2
},
{
measId 3,
measObjectId 2,
reportConfigId 3
}
},
quantityConfig {
quantityConfigNR-List {
{
quantityConfigCell {
ssb-FilterConfig {
filterCoefficientRSRQ fc3,
filterCoefficientRS-SINR fc5
},
csi-RS-FilterConfig {
}
}
}
}
},
measGapConfig {
gapUE release: NULL
}
},
nonCriticalExtension {
masterCellGroup {
cellGroupId 0,
rlc-BearerToAddModList {
{
logicalChannelIdentity 4,
reestablishRLC true
},
{
logicalChannelIdentity 1,
reestablishRLC true
},
{
logicalChannelIdentity 2,
reestablishRLC true
}
},
mac-CellGroupConfig {
schedulingRequestConfig {
schedulingRequestToAddModList {
{
schedulingRequestId 0,
sr-TransMax n64
}
}
},
bsr-Config {
periodicBSR-Timer sf20,
retxBSR-Timer sf320
},
tag-Config {
tag-ToAddModList {
{
tag-Id 0,
timeAlignmentTimer infinity
}
}
},
phr-Config setup: {
phr-PeriodicTimer sf500,
phr-ProhibitTimer sf200,
phr-Tx-PowerFactorChange dB3,
multiplePHR FALSE,
dummy FALSE,
phr-Type2OtherCell FALSE,
phr-ModeOtherCG real
},
skipUplinkTxDynamic FALSE,
dataInactivityTimer release: NULL
},
physicalCellGroupConfig {
pdsch-HARQ-ACK-Codebook dynamic
},
spCellConfig {
reconfigurationWithSync {
spCellConfigCommon {
physCellId 501,
downlinkConfigCommon {
frequencyInfoDL {
absoluteFrequencySSB 712608,
frequencyBandList {
79
},
absoluteFrequencyPointA 712062,
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialDownlinkBWP {
genericParameters {
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
pdcch-ConfigCommon setup: {
controlResourceSetZero 4,
searchSpaceZero 0,
commonSearchSpaceList {
{
searchSpaceId 1,
controlResourceSetId 0,
monitoringSlotPeriodicityAndOffset sl1: NULL,
monitoringSymbolsWithinSlot '10000000000000'B,
nrofCandidates {
aggregationLevel1 n0,
aggregationLevel2 n0,
aggregationLevel4 n4,
aggregationLevel8 n0,
aggregationLevel16 n0
},
searchSpaceType common: {
dci-Format0-0-AndFormat1-0 {
}
}
}
},
searchSpaceSIB1 0,
searchSpaceOtherSystemInformation 1,
pagingSearchSpace 1,
ra-SearchSpace 1
},
pdsch-ConfigCommon setup: {
pdsch-TimeDomainAllocationList {
{
mappingType typeA,
startSymbolAndLength 40
},
{
mappingType typeA,
startSymbolAndLength 57
}
}
}
}
},
uplinkConfigCommon {
frequencyInfoUL {
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialUplinkBWP {
genericParameters {
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
rach-ConfigCommon setup: {
rach-ConfigGeneric {
prach-ConfigurationIndex 160,
msg1-FDM one,
msg1-FrequencyStart 7,
zeroCorrelationZoneConfig 15,
preambleReceivedTargetPower -110,
preambleTransMax n7,
powerRampingStep dB4,
ra-ResponseWindow sl20
},
ssb-perRACH-OccasionAndCB-PreamblesPerSSB one: n8,
ra-ContentionResolutionTimer sf64,
prach-RootSequenceIndex l139: 1,
msg1-SubcarrierSpacing kHz30,
restrictedSetConfig unrestrictedSet
},
pusch-ConfigCommon setup: {
pusch-TimeDomainAllocationList {
{
k2 7,
mappingType typeA,
startSymbolAndLength 27
},
{
k2 4,
mappingType typeA,
startSymbolAndLength 27
},
{
k2 2,
mappingType typeA,
startSymbolAndLength 27
}
},
p0-NominalWithGrant -84
},
pucch-ConfigCommon setup: {
pucch-ResourceCommon 11,
pucch-GroupHopping neither,
p0-nominal -90
}
},
dummy ms500
},
ssb-PositionsInBurst mediumBitmap: '80'H,
ssb-periodicityServingCell ms20,
dmrs-TypeA-Position pos2,
ssbSubcarrierSpacing kHz30,
tdd-UL-DL-ConfigurationCommon {
referenceSubcarrierSpacing kHz30,
pattern1 {
dl-UL-TransmissionPeriodicity ms5,
nrofDownlinkSlots 7,
nrofDownlinkSymbols 6,
nrofUplinkSlots 2,
nrofUplinkSymbols 4
}
},
ss-PBCH-BlockPower -41
},
newUE-Identity 17922,
t304 ms1000,
smtc {
periodicityAndOffset sf20: 0,
duration sf1
}
},
spCellConfigDedicated {
initialDownlinkBWP {
pdcch-Config setup: {
controlResourceSetToAddModList {
{
controlResourceSetId 2,
frequencyDomainResources '111111111111111110000000000000000000000000000'B,
duration 1,
cce-REG-MappingType nonInterleaved: NULL,
precoderGranularity sameAsREG-bundle
}
},
searchSpacesToAddModList {
{
searchSpaceId 2,
controlResourceSetId 2,
monitoringSlotPeriodicityAndOffset sl1: NULL,
monitoringSymbolsWithinSlot '10000000000000'B,
nrofCandidates {
aggregationLevel1 n0,
aggregationLevel2 n2,
aggregationLevel4 n1,
aggregationLevel8 n0,
aggregationLevel16 n0
},
searchSpaceType ue-Specific: {
dci-Formats formats0-1-And-1-1
}
}
}
},
pdsch-Config setup: {
dmrs-DownlinkForPDSCH-MappingTypeA setup: {
dmrs-AdditionalPosition pos1
},
tci-StatesToAddModList {
{
tci-StateId 0,
qcl-Type1 {
referenceSignal ssb: 0,
qcl-Type typeD
}
}
},
resourceAllocation resourceAllocationType1,
rbg-Size config1,
mcs-Table qam256,
prb-BundlingType staticBundling: {
bundleSize wideband
},
zp-CSI-RS-ResourceToAddModList {
{
zp-CSI-RS-ResourceId 0,
resourceMapping {
frequencyDomainAllocation row4: '001'B,
nrofPorts p4,
firstOFDMSymbolInTimeDomain 4,
cdm-Type fd-CDM2,
density one: NULL,
freqBand {
startingRB 0,
nrofRBs 108
}
},
periodicityAndOffset slots80: 1
}
},
p-ZP-CSI-RS-ResourceSet setup: {
zp-CSI-RS-ResourceSetId 0,
zp-CSI-RS-ResourceIdList {
0
}
}
}
},
firstActiveDownlinkBWP-Id 0,
uplinkConfig {
initialUplinkBWP {
pucch-Config setup: {
resourceSetToAddModList {
{
pucch-ResourceSetId 0,
resourceList {
0,
1,
2,
3,
4,
5,
6,
7
}
},
{
pucch-ResourceSetId 1,
resourceList {
8,
9,
10,
11
}
}
},
resourceToAddModList {
{
pucch-ResourceId 0,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 1,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 0
}
},
{
pucch-ResourceId 1,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 5,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 0
}
},
{
pucch-ResourceId 2,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 9,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 0
}
},
{
pucch-ResourceId 3,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 1,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 1
}
},
{
pucch-ResourceId 4,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 5,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 1
}
},
{
pucch-ResourceId 5,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 9,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 1
}
},
{
pucch-ResourceId 6,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 1,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 2
}
},
{
pucch-ResourceId 7,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 5,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 2
}
},
{
pucch-ResourceId 8,
startingPRB 1,
intraSlotFrequencyHopping enabled,
secondHopPRB 104,
format format2: {
nrofPRBs 1,
nrofSymbols 2,
startingSymbolIndex 0
}
},
{
pucch-ResourceId 9,
startingPRB 1,
intraSlotFrequencyHopping enabled,
secondHopPRB 104,
format format2: {
nrofPRBs 1,
nrofSymbols 2,
startingSymbolIndex 2
}
},
{
pucch-ResourceId 10,
startingPRB 1,
intraSlotFrequencyHopping enabled,
secondHopPRB 104,
format format2: {
nrofPRBs 1,
nrofSymbols 2,
startingSymbolIndex 4
}
},
{
pucch-ResourceId 11,
startingPRB 1,
intraSlotFrequencyHopping enabled,
secondHopPRB 104,
format format2: {
nrofPRBs 1,
nrofSymbols 2,
startingSymbolIndex 6
}
},
{
pucch-ResourceId 12,
startingPRB 105,
intraSlotFrequencyHopping enabled,
secondHopPRB 0,
format format1: {
initialCyclicShift 9,
nrofSymbols 14,
startingSymbolIndex 0,
timeDomainOCC 2
}
},
{
pucch-ResourceId 13,
startingPRB 1,
intraSlotFrequencyHopping enabled,
secondHopPRB 104,
format format2: {
nrofPRBs 1,
nrofSymbols 2,
startingSymbolIndex 8
}
}
},
format1 setup: {
},
format2 setup: {
maxCodeRate zeroDot25
},
schedulingRequestResourceToAddModList {
{
schedulingRequestResourceId 1,
schedulingRequestID 0,
periodicityAndOffset sl40: 8,
resource 12
}
},
dl-DataToUL-ACK {
8,
7,
6,
5,
4,
12,
11
}
},
pusch-Config setup: {
txConfig codebook,
dmrs-UplinkForPUSCH-MappingTypeA setup: {
dmrs-AdditionalPosition pos1,
transformPrecodingDisabled {
}
},
pusch-PowerControl {
msg3-Alpha alpha1,
p0-AlphaSets {
{
p0-PUSCH-AlphaSetId 0,
p0 0,
alpha alpha1
}
},
pathlossReferenceRSToAddModList {
{
pusch-PathlossReferenceRS-Id 0,
referenceSignal ssb-Index: 0
}
},
sri-PUSCH-MappingToAddModList {
{
sri-PUSCH-PowerControlId 0,
sri-PUSCH-PathlossReferenceRS-Id 0,
sri-P0-PUSCH-AlphaSetId 0,
sri-PUSCH-ClosedLoopIndex i0
}
}
},
resourceAllocation resourceAllocationType1,
mcs-Table qam256,
mcs-TableTransformPrecoder qam256,
codebookSubset nonCoherent,
maxRank 1,
uci-OnPUSCH setup: {
betaOffsets semiStatic: {
betaOffsetACK-Index1 9,
betaOffsetACK-Index2 9,
betaOffsetACK-Index3 9,
betaOffsetCSI-Part1-Index1 7,
betaOffsetCSI-Part1-Index2 7,
betaOffsetCSI-Part2-Index1 7,
betaOffsetCSI-Part2-Index2 7
},
scaling f1
}
},
srs-Config setup: {
srs-ResourceSetToAddModList {
{
srs-ResourceSetId 0,
srs-ResourceIdList {
0
},
resourceType aperiodic: {
aperiodicSRS-ResourceTrigger 1,
slotOffset 7
},
usage codebook,
p0 -84,
pathlossReferenceRS ssb-Index: 0
}
},
srs-ResourceToAddModList {
{
srs-ResourceId 0,
nrofSRS-Ports port1,
transmissionComb n2: {
combOffset-n2 0,
cyclicShift-n2 0
},
resourceMapping {
startPosition 0,
nrofSymbols n1,
repetitionFactor n1
},
freqDomainPosition 0,
freqDomainShift 9,
freqHopping {
c-SRS 22,
b-SRS 3,
b-hop 0
},
groupOrSequenceHopping neither,
resourceType aperiodic: {
},
sequenceId 501
}
}
}
},
firstActiveUplinkBWP-Id 0,
pusch-ServingCellConfig setup: {
}
},
pdcch-ServingCellConfig setup: {
},
pdsch-ServingCellConfig setup: {
nrofHARQ-ProcessesForPDSCH n16,
maxMIMO-Layers 2
},
csi-MeasConfig setup: {
nzp-CSI-RS-ResourceToAddModList {
{
nzp-CSI-RS-ResourceId 0,
resourceMapping {
frequencyDomainAllocation other: '000001'B,
nrofPorts p2,
firstOFDMSymbolInTimeDomain 3,
cdm-Type fd-CDM2,
density one: NULL,
freqBand {
startingRB 0,
nrofRBs 108
}
},
powerControlOffset 0,
scramblingID 501,
periodicityAndOffset slots80: 1,
qcl-InfoPeriodicCSI-RS 0
},
{
nzp-CSI-RS-ResourceId 1,
resourceMapping {
frequencyDomainAllocation row1: '1'H,
nrofPorts p1,
firstOFDMSymbolInTimeDomain 5,
cdm-Type noCDM,
density three: NULL,
freqBand {
startingRB 0,
nrofRBs 108
}
},
powerControlOffset 0,
scramblingID 501,
periodicityAndOffset slots80: 1,
qcl-InfoPeriodicCSI-RS 0
},
{
nzp-CSI-RS-ResourceId 2,
resourceMapping {
frequencyDomainAllocation row1: '1'H,
nrofPorts p1,
firstOFDMSymbolInTimeDomain 9,
cdm-Type noCDM,
density three: NULL,
freqBand {
startingRB 0,
nrofRBs 108
}
},
powerControlOffset 0,
scramblingID 501,
periodicityAndOffset slots80: 1,
qcl-InfoPeriodicCSI-RS 0
},
{
nzp-CSI-RS-ResourceId 3,
resourceMapping {
frequencyDomainAllocation row1: '1'H,
nrofPorts p1,
firstOFDMSymbolInTimeDomain 5,
cdm-Type noCDM,
density three: NULL,
freqBand {
startingRB 0,
nrofRBs 108
}
},
powerControlOffset 0,
scramblingID 501,
periodicityAndOffset slots80: 2,
qcl-InfoPeriodicCSI-RS 0
},
{
nzp-CSI-RS-ResourceId 4,
resourceMapping {
frequencyDomainAllocation row1: '1'H,
nrofPorts p1,
firstOFDMSymbolInTimeDomain 9,
cdm-Type noCDM,
density three: NULL,
freqBand {
startingRB 0,
nrofRBs 108
}
},
powerControlOffset 0,
scramblingID 501,
periodicityAndOffset slots80: 2,
qcl-InfoPeriodicCSI-RS 0
}
},
nzp-CSI-RS-ResourceSetToAddModList {
{
nzp-CSI-ResourceSetId 0,
nzp-CSI-RS-Resources {
0
}
},
{
nzp-CSI-ResourceSetId 1,
nzp-CSI-RS-Resources {
1,
2,
3,
4
},
trs-Info true
}
},
csi-IM-ResourceToAddModList {
{
csi-IM-ResourceId 0,
csi-IM-ResourceElementPattern pattern1: {
subcarrierLocation-p1 s0,
symbolLocation-p1 4
},
freqBand {
startingRB 0,
nrofRBs 108
},
periodicityAndOffset slots80: 1
}
},
csi-IM-ResourceSetToAddModList {
{
csi-IM-ResourceSetId 0,
csi-IM-Resources {
0
}
}
},
csi-ResourceConfigToAddModList {
{
csi-ResourceConfigId 0,
csi-RS-ResourceSetList nzp-CSI-RS-SSB: {
nzp-CSI-RS-ResourceSetList {
0
}
},
bwp-Id 0,
resourceType periodic
},
{
csi-ResourceConfigId 1,
csi-RS-ResourceSetList csi-IM-ResourceSetList: {
0
},
bwp-Id 0,
resourceType periodic
},
{
csi-ResourceConfigId 2,
csi-RS-ResourceSetList nzp-CSI-RS-SSB: {
nzp-CSI-RS-ResourceSetList {
1
}
},
bwp-Id 0,
resourceType periodic
}
},
csi-ReportConfigToAddModList {
{
reportConfigId 0,
resourcesForChannelMeasurement 0,
csi-IM-ResourcesForInterference 1,
reportConfigType periodic: {
reportSlotConfig slots80: 9,
pucch-CSI-ResourceList {
{
uplinkBandwidthPartId 0,
pucch-Resource 13
}
}
},
reportQuantity cri-RI-PMI-CQI: NULL,
reportFreqConfiguration {
cqi-FormatIndicator widebandCQI,
pmi-FormatIndicator widebandPMI
},
timeRestrictionForChannelMeasurements notConfigured,
timeRestrictionForInterferenceMeasurements notConfigured,
codebookConfig {
codebookType type1: {
subType typeI-SinglePanel: {
nrOfAntennaPorts two: {
twoTX-CodebookSubsetRestriction '111111'B
},
typeI-SinglePanel-ri-Restriction '03'H
},
codebookMode 1
}
},
groupBasedBeamReporting disabled: {
},
cqi-Table table2,
subbandSize value1
}
}
},
tag-Id 0,
servingCellMO 1,
lte-CRS-ToMatchAround release: NULL
}
}
},
masterKeyUpdate {
keySetChangeIndicator FALSE,
nextHopChainingCount 0
}
}
}
}
}
Step 9. First random access attempt on the target fails
The UE reaches cell 02 about 115 ms after the command. Its first random access attempt there does not complete.
Amarisoft gNB log, cell 02, PHY and MAC
[PHY] UL - 02 - 599.19 PRACH: sequence_index=7 ta=6 prb=7:12 symb=2:12 snr=12.0 p=-82.9 [MAC] - 0003 02 Allocating new UE [MAC] DL - 02 RAR: rapid=7 [PHY] DL - 02 010d 600.13 PDSCH: harq=si prb=58:2 symb=1:13 CW0: tb_len=11 mod=2 rv_idx=0 cr=0.19 [PHY] DL - 02 010d 600.13 PDCCH: ss_id=1 cce_index=0 al=4 dci=1_0 [PHY] UL 0003 02 4603 600.18 PUSCH: harq=0 prb=1 symb=0:14 CW0: tb_len=9 mod=2 rv_idx=0 cr=0.30 retx=0 crc=KO snr=-1.7 epre=-106.9 ta=14.0 [PHY] DL 0003 02 4603 601.5 PDCCH: ss_id=1 cce_index=0 al=4 dci=0_0 k2=4 [PHY] UL 0003 02 4603 601.9 PUSCH: harq=0 prb=2 symb=0:14 CW0: tb_len=9 mod=2 rv_idx=2 cr=0.33 retx=1 crc=KO snr=-0.1 epre=-105.4 ta=1.0 [PHY] DL 0003 02 4603 602.1 PDCCH: ss_id=1 cce_index=0 al=4 dci=0_0 k2=7 [PHY] UL 0003 02 4603 602.8 PUSCH: harq=0 prb=103 symb=0:14 CW0: tb_len=9 mod=2 rv_idx=3 cr=0.33 retx=2 crc=KO snr=-3.0 epre=-111.0 ta=-1.5 [PHY] DL 0003 02 4603 602.15 PDCCH: ss_id=1 cce_index=0 al=4 dci=0_0 k2=4 [PHY] UL 0003 02 4603 602.19 PUSCH: harq=0 prb=103 symb=0:14 CW0: tb_len=9 mod=2 rv_idx=1 cr=0.33 retx=3 crc=KO snr=-8.7 epre=-116.2 ta=6.6 [PHY] DL 0003 02 4603 603.11 PDCCH: ss_id=1 cce_index=0 al=4 dci=0_0 k2=7 [PHY] UL 0003 02 4603 603.18 PUSCH: harq=0 prb=103 symb=0:14 CW0: tb_len=9 mod=2 rv_idx=0 cr=0.33 retx=4 crc=KO snr=-2.3 epre=-109.2 ta=-1.9 [MAC] - 0003 02 Freeing UE
A preamble with sequence_index 7 arrives with snr 12.0 and ta 6. The gNB creates temporary context 0003 and sends a RAR with rapid 7. The Msg3 PUSCH for temporary C-RNTI 0x4603 fails CRC five times, with SNR between -8.7 and -0.1 dB. The gNB then frees context 0003. There is no contention resolution, so the UE has to try again.
Step 10. UE sends a second preamble
100 ms after the first preamble, a second one arrives on cell 02.
Amarisoft gNB log, cell 02, PRACH
[PHY] UL - 02 - 609.19 PRACH: sequence_index=1 ta=1 prb=7:12 symb=2:12 snr=18.1 p=-79.1 [MAC] - 0004 02 Allocating new UE
The preamble has sequence_index 1, snr 18.1, ta 1 and p -79.1. The first one had p -82.9 and snr 12.0. The PRACH position prb 7:12 matches msg1-FrequencyStart 7 from the handover command. The gNB creates temporary context 0004.
Step 11. Target cell answers with a RAR
The target cell sends the random access response for preamble 1 three milliseconds later.
Amarisoft gNB log, cell 02, RAR
[MAC] DL - 02 RAR: rapid=1 [PHY] DL - 02 010d 610.13 PDSCH: harq=si prb=58:2 symb=1:13 CW0: tb_len=11 mod=2 rv_idx=0 cr=0.19 [PHY] DL - 02 010d 610.13 PDCCH: ss_id=1 cce_index=0 al=4 dci=1_0
The RAR carries rapid 1. It is scheduled with DCI 1_0 on ss_id 1, the ra-SearchSpace of cell 02, with RA-RNTI 0x010d. The Msg3 that follows is scheduled for temporary C-RNTI 0x4604, the one assigned by this RAR.
Step 12. Msg3 carries the C-RNTI from the handover command
This time Msg3 is decoded. It identifies the UE by the C-RNTI it received in the handover command.
Amarisoft gNB log, cell 02, Msg3
[PHY] UL 0004 02 4604 610.18 PUSCH: harq=0 prb=1 symb=0:14 CW0: tb_len=9 mod=2 rv_idx=0 cr=0.30 retx=0 crc=OK snr=11.6 epre=-91.8 ta=0.1 [MAC] - 0004 02 mac_crnti=0x4602: resuming connection of ue_id=0x0002 [MAC] UL 0002 02 CRNTI:4602 LBSR:bitmap=81 bs(0)=1 bs(7)=221 PAD:len=0 [MAC] - 0004 02 Freeing UE [PHY] DL 0002 02 4602 611.5 PDCCH: ss_id=2 cce_index=8 al=2 dci=0_1 k2=4
The Msg3 PUSCH for 0x4604 passes CRC with snr 11.6. It holds a C-RNTI MAC CE with value 4602 and a long BSR. The gNB matches 0x4602 to the context from Step 7 and logs "resuming connection of ue_id=0x0002". It frees the temporary context 0004. The next PDCCH is DCI 0_1 on ss_id 2, addressed to C-RNTI 0x4602. That uplink grant is what tells the UE that the contention is resolved.
Step 13. UE completes the handover
The UE sends RRCReconfigurationComplete on the target cell with the grant from Step 12. This ends the radio part of the handover.
Amarisoft gNB log, cell 02, MAC and RRC
[PHY] UL 0002 02 4602 611.9 PUSCH: harq=0 prb=2 symb=0:14 CW0: tb_len=22 mod=2 rv_idx=0 cr=0.62 retx=0 crc=OK snr=31.9 epre=-70.3 ta=-0.3
[MAC] UL 0002 02 LCID:1 len=10 LBSR:bitmap=81 bs(0)=6 bs(7)=221 SE PHR:ph=47 pc=53 PAD:len=1
[RRC] UL 0002 02 DCCH-NR: RRC reconfiguration complete
{
message c1: rrcReconfigurationComplete: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfigurationComplete: {
}
}
}
The PUSCH carries the message on LCID 1, together with a long BSR and a PHR. Its rrc-TransactionIdentifier 0 matches the handover command. The complete arrives 229 ms after the command, which is well inside t304 ms1000. Downlink data on LCID 4 restarts on cell 02 in the same millisecond. From the next log line on, the gNB shows the UE as 0001 on cell 02 with RNTI 0x4602.
Step 14. gNB releases the source context
One millisecond after the complete, the gNB removes the UE from the source cell.
Amarisoft gNB log, MAC
[MAC] - 0001 01 Freeing UE
This is the internal counterpart of the source release in an inter-gNB handover. No XnAP UE CONTEXT RELEASE is needed. No NGAP PATH SWITCH REQUEST is sent either. The UE is still on the same gNB, so the AMF and the NG-U path see no change.
Step 15. UE reports A2 on the new serving cell
The measurement setup from the handover command produces a report right away.
Amarisoft gNB log, cell 02, MeasurementReport
[RRC] UL 0001 02 DCCH-NR: Measurement report
{
message c1: measurementReport: {
criticalExtensions measurementReport: {
measResults {
measId 2,
measResultServingMOList {
{
servCellId 0,
measResultServingCell {
physCellId 501,
measResult {
cellResults {
resultsSSB-Cell {
rsrp 53,
rsrq 65,
sinr 98
}
}
}
}
}
}
}
}
}
}
measId 2 is now A2 on SSB 712608, the new serving frequency. The serving cell PCI 501 is at rsrp 53, below a2-Threshold 56. SINR is 98. The UE has moved to a stronger cell, but that cell is still below the A2 threshold.
Step 16. Target cell starts measurement gaps
The target cell reacts the same way the source did in Step 4.
Amarisoft gNB log, cell 02, RRCReconfiguration
[RRC] DL 0001 02 DCCH-NR: RRC reconfiguration
{
message c1: rrcReconfiguration: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfiguration: {
measConfig {
measIdToRemoveList {
2
},
measIdToAddModList {
{
measId 1,
measObjectId 1,
reportConfigId 1
}
},
measGapConfig {
gapUE setup: {
gapOffset 18,
mgl ms6,
mgrp ms40,
mgta ms0dot5
}
}
}
}
}
}
The gap has the same values as before: gapOffset 18, mgl ms6, mgrp ms40, mgta ms0dot5. The reconfiguration removes measId 2 and adds measId 1 (A1 on the serving frequency). After the handover, measId 3 is A3 on SSB 631968. With the gap, the UE watches the old cell PCI 500 as a handover candidate. The later return handover to cell 0x01 is triggered by this measId.
Step 17. UE confirms the target measurement setup
The UE confirms the configuration 16 ms later. The UE is now fully on cell 02 with the same measurement setup it had on cell 01.
Amarisoft gNB log, cell 02, RRCReconfigurationComplete
[RRC] UL 0001 02 DCCH-NR: RRC reconfiguration complete
{
message c1: rrcReconfigurationComplete: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfigurationComplete: {
}
}
}
Reference
- TS 38.300 v19.4.0 - NR and NG-RAN overall description; Stage 2
- TS 38.331 v19.4.0 - NR Radio Resource Control (RRC)
- TS 38.423 v19.4.0 - NG-RAN Xn Application Protocol (XnAP)
- TS 38.413 v19.4.0 - NG Application Protocol (NGAP)
- TS 38.473 v19.4.0 - F1 Application Protocol (F1AP)
- TS 37.340 v19.3.0 - Multi-connectivity; Overall description; Stage 2