Coverage Report

Created: 2026-10-28 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ocudu/lib/rrc/ue/rrc_ue_impl.h
Line
Count
Source
1
// SPDX-FileCopyrightText: Copyright (C) 2021-2026 Software Radio Systems Limited
2
// SPDX-FileCopyrightText: Copyright (C) 2026 OCUDU contributors
3
// SPDX-License-Identifier: BSD-3-Clause-Open-MPI
4
// Portions of this file may implement 3GPP specifications, which may be subject to additional licensing requirements.
5
6
#pragma once
7
8
#include "procedures/rrc_ue_event_manager.h"
9
#include "rrc_ue_context.h"
10
#include "rrc_ue_logger.h"
11
#include "ocudu/asn1/rrc_nr/ul_dcch_msg.h"
12
#include "ocudu/asn1/rrc_nr/ul_dcch_msg_ies.h"
13
#include "ocudu/ran/cu_cp_types.h"
14
#include "ocudu/rrc/rrc_cell_context.h"
15
#include "ocudu/rrc/rrc_ue.h"
16
17
namespace ocudu::ocucp {
18
19
/// Main UE representation in RRC
20
class rrc_ue_impl final : public rrc_ue_interface, public rrc_ue_controller
21
{
22
public:
23
  rrc_ue_impl(rrc_pdu_f1ap_notifier&                 f1ap_pdu_notifier_,
24
              rrc_ue_ngap_notifier&                  ngap_notifier_,
25
              rrc_ue_context_update_notifier&        cu_cp_notifier_,
26
              rrc_ue_measurement_notifier&           measurement_notifier_,
27
              rrc_ue_cu_cp_ue_notifier&              cu_cp_ue_notifier_,
28
              rrc_ue_event_notifier&                 metrics_notifier_,
29
              rrc_ue_srb_pdcp_manager&               pdcp_manager_,
30
              cu_cp_ue_index_t                       ue_index_,
31
              rnti_t                                 c_rnti_,
32
              const rrc_cell_context&                cell_,
33
              const rrc_ue_cfg_t&                    cfg_,
34
              const byte_buffer&                     du_to_cu_container_,
35
              std::optional<rrc_ue_transfer_context> rrc_context,
36
              std::optional<rrc_resume_context_t>    remote_resume_context = std::nullopt);
37
  ~rrc_ue_impl();
38
39
  // rrc_ul_pdu_handler
40
  void handle_ul_ccch_pdu(byte_buffer pdu, rnti_t c_rnti) override;
41
  void handle_ul_dcch_pdu(srb_id_t srb_id, byte_buffer rrc_pdu, bool integrity_verified) override;
42
43
  // rrc_ue_interface
44
0
  rrc_ue_controller&              get_controller() override { return *this; }
45
102k
  rrc_ul_pdu_handler&             get_ul_pdu_handler() override { return *this; }
46
24.8k
  rrc_ngap_message_handler&       get_rrc_ngap_message_handler() override { return *this; }
47
48.5k
  rrc_ue_control_message_handler& get_rrc_ue_control_message_handler() override { return *this; }
48
0
  rrc_ue_context_handler&         get_rrc_ue_context_handler() override { return *this; }
49
0
  rrc_ue_capability_handler&      get_rrc_ue_capability_handler() override { return *this; }
50
51
  // rrc_ngap_message_handler
52
  void        handle_dl_nas_transport_message(byte_buffer nas_pdu) override;
53
  byte_buffer get_packed_handover_preparation_message() override;
54
55
  // rrc_ue_control_message_handler
56
  rrc_ue_security_mode_command_context get_security_mode_command_context() override;
57
  async_task<bool>                     handle_security_mode_complete_expected(uint8_t transaction_id) override;
58
  byte_buffer                          get_packed_ue_capability_rat_container_list() const override;
59
  bool                                 verify_reestablishment_short_mac_i(const security::sec_short_mac_i& short_mac_i,
60
                                                                          pci_t                            source_pci,
61
                                                                          rnti_t                           source_c_rnti,
62
                                                                          nr_cell_identity                 target_nci) override;
63
  bool        verify_resume_mac_i(const security::sec_short_mac_i& resume_mac_i, nr_cell_identity target_nci) override;
64
  byte_buffer get_packed_ue_radio_access_cap_info() const override;
65
  async_task<bool> handle_rrc_reconfiguration_request(const rrc_reconfiguration_procedure_request& msg) override;
66
  rrc_ue_handover_reconfiguration_context
67
  get_rrc_ue_handover_reconfiguration_context(const rrc_reconfiguration_procedure_request& request) override;
68
  rrc_ue_cond_reconfiguration_context
69
  get_rrc_ue_cond_reconfiguration_context(const rrc_reconfiguration_procedure_request& request) override;
70
  async_task<bool> handle_handover_reconfiguration_complete_expected(uint8_t                   transaction_id,
71
                                                                     std::chrono::milliseconds timeout_ms,
72
                                                                     bool release_on_failure = true) override;
73
  bool             store_ue_capabilities(byte_buffer ue_capabilities) override;
74
  async_task<bool> handle_rrc_ue_capability_transfer_request(const rrc_ue_capability_transfer_request& msg) override;
75
  void             fill_ue_derived_location(cu_cp_user_location_info_nr& user_location_info) const override;
76
  void             request_coarse_ue_location() override;
77
78
  /// Returns the TAC of the configured area holding the coarse position the UE reported, if any.
79
  std::optional<tac_t> get_ue_location_derived_tac() const;
80
81
  /// Returns the Mapped Cell ID of the configured area holding the coarse position the UE reported, if any.
82
  std::optional<nr_cell_identity> get_ue_mapped_cell_id() const;
83
  rrc_ue_release_context
84
                          get_rrc_ue_release_context(bool                                          requires_rrc_message,
85
                                                     std::optional<std::chrono::seconds>           release_wait_time = std::nullopt,
86
                                                     std::optional<rrc_inactivity_context>         inactivity_context = std::nullopt,
87
                                                     std::optional<cu_cp_release_redirect_nr_info> redirect_nr_info = std::nullopt) override;
88
  rrc_ue_transfer_context get_transfer_context() override;
89
  std::optional<rrc_meas_cfg>
90
              generate_meas_config(const std::optional<rrc_meas_cfg>& current_meas_config = std::nullopt,
91
                                   bool                               cond_meas           = false,
92
                                   span<const pci_t>                  candidate_pcis      = {}) override;
93
  byte_buffer get_packed_meas_config(span<const pci_t> candidate_pcis = {}) override;
94
  void        update_meas_config(const rrc_meas_cfg& cfg) override;
95
0
  std::optional<rrc_meas_cfg>           get_meas_config() override { return context.meas_cfg; }
96
  std::optional<byte_buffer>            get_packed_location_meas_info() const override;
97
  std::optional<uint8_t>                get_serving_cell_mo() override;
98
  byte_buffer                           get_rrc_handover_command(const rrc_reconfiguration_procedure_request& request,
99
                                                                 unsigned                                     transaction_id) override;
100
  byte_buffer                           handle_rrc_handover_command(byte_buffer cmd) override;
101
  bool                                  handle_rrc_handover_preparation_info(byte_buffer pdu) override;
102
  void                                  create_srb(const srb_creation_message& msg) override;
103
  static_vector<srb_id_t, MAX_NOF_SRBS> get_srbs() override;
104
0
  void                                  set_rrc_state(rrc_state state) override { context.state = state; }
105
  rrc_state                             get_rrc_state() const override;
106
  void                                  cancel_handover_reconfiguration_transaction(uint8_t transaction_id) override;
107
  void                                  cancel_all_transactions() override;
108
109
  // rrc_ue_context_handler
110
  rrc_ue_reestablishment_context_response get_context() override;
111
  void                                    update_c_rnti(rnti_t crnti) override;
112
0
  rrc_cell_context                        get_cell_context() const override { return context.cell; }
113
  void                                    update_cell_group_config(byte_buffer cell_group_config) override;
114
0
  byte_buffer&                            get_cell_group_config() override { return context.cell_group_config; }
115
116
  // rrc_ue_capability_handler
117
0
  bool is_rrc_inactive_supported() const override { return context.capabilities.rrc_inactive_supported; }
118
  bool is_conditional_handover_supported() const override
119
0
  {
120
0
    return context.capabilities.conditional_handover_supported;
121
0
  }
122
  bool is_conditional_handover_two_trigger_events_supported() const override
123
0
  {
124
0
    return context.capabilities.conditional_handover_two_trigger_events_supported;
125
0
  }
126
  bool is_conditional_handover_event_a4_supported() const override
127
0
  {
128
0
    return context.capabilities.conditional_handover_event_a4_supported;
129
0
  }
130
  bool is_conditional_handover_location_based_supported() const override
131
0
  {
132
0
    return context.capabilities.conditional_handover_location_based_supported;
133
0
  }
134
  bool is_conditional_handover_time_based_supported() const override
135
0
  {
136
0
    return context.capabilities.conditional_handover_time_based_supported;
137
0
  }
138
139
private:
140
  void stop() override;
141
142
  // message handlers
143
  void handle_pdu(srb_id_t srb_id, byte_buffer rrc_pdu, bool integrity_verified);
144
  void handle_rrc_setup_request(const asn1::rrc_nr::rrc_setup_request_s& msg);
145
  void handle_rrc_reest_request(const asn1::rrc_nr::rrc_reest_request_s& msg);
146
  void handle_rrc_resume_request(const asn1::rrc_nr::rrc_resume_request_s& msg, rnti_t c_rnti);
147
  void handle_ul_info_transfer(const asn1::rrc_nr::ul_info_transfer_ies_s& ul_info_transfer);
148
  void handle_security_mode_complete(const asn1::rrc_nr::security_mode_complete_s& msg);
149
150
  void handle_measurement_report(const asn1::rrc_nr::meas_report_s& msg);
151
  void handle_location_measurement_indication(const asn1::rrc_nr::location_meas_ind_s& msg);
152
  void handle_rrc_transaction_complete(const asn1::rrc_nr::ul_dcch_msg_s& msg, uint8_t transaction_id_);
153
  /// Dispatches the UL-DCCH message class extension, which is where UEInformationResponse lives.
154
  void handle_ul_dcch_msg_class_ext(const asn1::rrc_nr::ul_dcch_msg_s& ul_dcch_msg, bool integrity_verified);
155
  void cancel_rrc_transaction(uint8_t transaction_id_);
156
157
  // message senders
158
  /// Packs a DL-CCCH message and logs the message
159
  void send_dl_ccch(const asn1::rrc_nr::dl_ccch_msg_s& dl_ccch_msg);
160
  void send_dl_dcch(srb_id_t srb_id, const asn1::rrc_nr::dl_dcch_msg_s& dl_dcch_msg);
161
162
  // rrc_ue_setup_proc_notifier
163
  void on_new_dl_ccch(const asn1::rrc_nr::dl_ccch_msg_s& dl_ccch_msg) override;
164
  void on_ue_release_required(const ngap_cause_t& cause) override;
165
166
  // rrc_ue_security_mode_command_proc_notifier
167
  void on_new_dl_dcch(srb_id_t srb_id, const asn1::rrc_nr::dl_dcch_msg_s& dl_dcch_msg) override;
168
  void on_new_as_security_context(bool security_mode_active) override;
169
  void on_as_security_activated() override;
170
171
  // helpers
172
  void handle_illegal_pdu_integrity(const char* msg, bool integrity_verified);
173
174
  rrc_ue_logger                   logger;
175
  rrc_ue_context_t                context;
176
  rrc_pdu_f1ap_notifier&          f1ap_pdu_notifier;    // PDU notifier to the F1AP
177
  rrc_ue_ngap_notifier&           ngap_notifier;        // notifier to the NGAP
178
  rrc_ue_context_update_notifier& cu_cp_notifier;       // notifier to the CU-CP
179
  rrc_ue_measurement_notifier&    measurement_notifier; // cell measurement notifier
180
  rrc_ue_cu_cp_ue_notifier&       cu_cp_ue_notifier;    // cu-cp ue notifier
181
  rrc_ue_event_notifier&          metrics_notifier;     // metrics notifier
182
  byte_buffer                     du_to_cu_container;   // initial RRC message from DU to CU
183
184
  // RRC procedures handling
185
  std::unique_ptr<rrc_ue_event_manager> event_mng;
186
};
187
188
} // namespace ocudu::ocucp