Merge remote-tracking branch 'origin/cleanup-pdu-session' into integration_2025_w26 (!3435)
Cleanup PDU Session Handling in RRC/NGAP
Currently, NGAP and RRC share the same structures and responsibilities when
handling PDU Session information: this creates tight coupling, redundancy, and
makes the code harder to maintain.
- NGAP should be responsible only for: Protocol-specific encoding/decoding
(3GPP TS 38.413)
- RRC should own: PDU Session handling and storage in the UE context
This MR is the first step in a broader refactoring of the PDU Session handling
code across NGAP and RRC layers, with the goal of splitting responsibilities
cleanly between both modules.
- Unified gtpu_tunnel_t for tunnel endpoint config (formerly f1u_tunnel_t)
- Refactored and relocated PDU Session struct definitions for better separation
between NGAP and RRC
- Moved pdusession_t for PDU Session handling out of NGAP, now defined and
managed by RRC only
- Defined 3GPP TS 38.413 message-specific structs in NGAP module
- NGAP now decodes NGAP PDU Session Resource Setup/Modify IEs and transfers
decoded data to RRC via ITTI
- Add helper functions to copy from NGAP message to pdusession_t
- Introduced new encoders/decoders/helpers in NGAP for handling PDU Session
Resource Setup/Modify procedures (e.g. decode_pdusession_transfer)
- Migrated to NGAP and removed duplicated logic for QoS information decoding
(fill_qos)
- Improved logging of GTP tunnel info
- Merged redundant functions (f1u_dl_gtp_update and f1u_ul_gtp_update)
- Removed unused code and obsolete types
- do free_func in seq_arr_erase_it on the provided range and updated unit test
- Other fixes and simplifications (e.g. simplified and clarified naming of
tunnel/session parameters and structs)
This cleanup improves code readability, has a high code churn (the deletions are
~159.7% of the insertions) and prepares for better modularity before the
refactoring of PDU Session handling in RRC/NGAP.
This commit is contained in:
@@ -45,6 +45,14 @@ typedef struct nr_guami_s {
|
||||
uint8_t amf_pointer;
|
||||
} nr_guami_t;
|
||||
|
||||
typedef enum {
|
||||
PDUSessionType_ipv4 = 0,
|
||||
PDUSessionType_ipv6 = 1,
|
||||
PDUSessionType_ipv4v6 = 2,
|
||||
PDUSessionType_ethernet = 3,
|
||||
PDUSessionType_unstructured = 4
|
||||
} pdu_session_type_t;
|
||||
|
||||
typedef enum { NON_DYNAMIC, DYNAMIC } fiveQI_t;
|
||||
|
||||
#endif
|
||||
|
||||
+11
-9
@@ -218,25 +218,27 @@ typedef struct nr_lcid_rb_t {
|
||||
} nr_lcid_rb_t;
|
||||
|
||||
typedef struct transport_layer_addr_s {
|
||||
/**
|
||||
* Transport Layer Address as a bitstring:
|
||||
* - 32 bits for IPv4 (RFC 791),
|
||||
* - 128 bits for IPv6 (RFC 2460),
|
||||
* - 160 bits for both IPv4 and IPv6, with IPv4 in the first 32 bits.
|
||||
* The S1AP/NGAP layer forwards this address (bitstring<1..160>)
|
||||
* to S1-U/NG-U without interpreting it.
|
||||
*/
|
||||
/** Transport Layer Address in bytes:
|
||||
* - 4 bytes for IPv4 (RFC 791), 16 bytes for IPv6 (RFC 2460),
|
||||
* - 20 bytes for both IPv4 and IPv6, with IPv4 in the first 4 bytes. */
|
||||
uint8_t length;
|
||||
/// Buffer: address in network byte order
|
||||
uint8_t buffer[20];
|
||||
} transport_layer_addr_t;
|
||||
|
||||
/** @brief GTP tunnel configuration */
|
||||
typedef struct {
|
||||
// Tunnel endpoint identifier
|
||||
uint32_t teid;
|
||||
// Transport layer address
|
||||
transport_layer_addr_t addr;
|
||||
} gtpu_tunnel_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GTPV1U TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef uint32_t teid_t; // tunnel endpoint identifier
|
||||
typedef uint8_t ebi_t; // eps bearer id
|
||||
typedef uint8_t pdusessionid_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -123,11 +123,10 @@ void seq_arr_erase_it(seq_arr_t* arr, void* start_it, void* end_it, void (*free_
|
||||
return;
|
||||
|
||||
if (free_func != NULL) {
|
||||
void* start_it = seq_arr_front(arr);
|
||||
void* end_it = seq_arr_end(arr);
|
||||
while (start_it != end_it) {
|
||||
free_func(start_it);
|
||||
start_it = seq_arr_next(arr, start_it);
|
||||
void* it = start_it;
|
||||
while (it != end_it) {
|
||||
free_func(it);
|
||||
it = seq_arr_next(arr, it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,13 @@ static int compar(const void* m0, const void* m1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int free_func_call_count = 0;
|
||||
|
||||
static void dummy_free_func(void* it)
|
||||
{
|
||||
++free_func_call_count;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
seq_arr_t arr = {0};
|
||||
@@ -83,6 +90,19 @@ int main()
|
||||
void* it = bsearch(&key, base, nmemb, size, compar);
|
||||
assert(seq_arr_dist(&arr, seq_arr_front(&arr), it) == 4);
|
||||
|
||||
// Regression test: erase a partial range only
|
||||
// Erase 92, 93, 94 (i.e., indices 1 to 3)
|
||||
int* start = seq_arr_at(&arr, 1);
|
||||
int* end = seq_arr_at(&arr, 4);
|
||||
seq_arr_erase_it(&arr, start, end, dummy_free_func);
|
||||
|
||||
// Now values should be: [91, 95, 96, 97, 98, 99]
|
||||
assert(free_func_call_count == 3);
|
||||
assert(seq_arr_size(&arr) == 6);
|
||||
assert(*(int*)seq_arr_at(&arr, 0) == 91);
|
||||
assert(*(int*)seq_arr_at(&arr, 1) == 95);
|
||||
assert(*(int*)seq_arr_at(&arr, 5) == 99);
|
||||
|
||||
// Free data structure
|
||||
seq_arr_free(&arr, NULL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user