- 1. Introduction
- 2. XRAN
- 3. FAPI
- 4. DU UE context creation/deletion
- 5. MAC scheduler
- 6. PDCP
- 7. E1AP procedures
- 8. CUCP UE Context Management
- 9. NGAP
- 10. RRC
- 11. RLC
- 11.1. RLC downlink
- 11.1.1. rlc_dl_creation
- 11.1.2. rlc_dl_deletion
- 11.1.3. rlc_dl_new_sdu
- 11.1.4. rlc_dl_lost_sdu
- 11.1.5. rlc_dl_discard_sdu
- 11.1.6. rlc_dl_sdu_send_started
- 11.1.7. rlc_dl_sdu_send_completed
- 11.1.8. rlc_dl_sdu_delivered
- 11.1.9. rlc_dl_tx_pdu
- 11.1.10. rlc_dl_rx_status
- 11.1.11. rlc_dl_am_tx_pdu_retx_count
- 11.1.12. rlc_dl_am_tx_pdu_max_retx_count_reached
- 11.2. RLC uplink
- 11.1. RLC downlink
- 12. Slice management
- 13. Periodic performance hook
- 14. PDU Sessions
Numerous Jbpf hooks have been added to the srsRAN codebase.
When a codelet is called, all parameters are passed in a "context" parameter. The following sections describe the hooks, along with the "context" details. The hook names are listed in bullets in the sections below.
Context info:
data: pointer to start of the XRAN packet
data_end: pointer to end of the XRAN packet
direction: 0-tx, 1=rxContext info:
cell_id: Cell identifier
data: pointer to start of the FAPI message
data_end: pointer to end of the FAPI messageContext "data" field points to a fapi::rx_data_indication_message structure.
Context "data" field points to a fapi::crc_indication_message structure.
Context "data" field points to a fapi::uci_indication_message structure.
Context "data" field points to a fapi::srs_indication_message structure.
Context "data" field points to a fapi::rach_indication_message structure.
Context "data" field points to a fapi::dl_tti_request_message structure.
Context "data" field points to a fapi::ul_tti_request_message structure.
Context "data" field points to a fapi::ul_dci_request_message structure.
Context "data" field points to a fapi::tx_data_request_message structure.
These hooks have information passed in using a jbpf_du_ue_ctx_info as shown below ..
struct jbpf_du_ue_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint32_t du_ue_index;
uint32_t tac;
uint32_t plmn;
uint64_t nci;
uint16_t pci;
uint16_t crnti;
};Context info:
data: pointer to the jbpf_du_ue_ctx_info
data_end: pointer to end of the jbpf_du_ue_ctx_info
These hooks are called when a scheduler context is created/updated/deleted.
Context info:
du_ue_index: The index used in the DU entity to identify the UE
These hooks are called when a scheduler receives information e.g. Buffer-Status-Reports, Power-Headroom-Reports etc.
Context info:
du_ue_index: The index used in the DU entity to identify the UE
data: pointer to start of the scheduler input message
data_end: pointer to end of the scheduler input message
Context "data" field points to an srsran::ul_bsr_indication_message structure.
Context "data" field points to an srsran::ul_crc_pdu_indication structure.
Context "data" field points to an srsran::uci_indication::uci_pdu structure.
Context "data" field points to an srsran::dl_mac_ce_indication structure.
Context "data" field points to an srsran::cell_ph_report structure.
Context "data" field points to an srsran::dl_buffer_state_indication_message structure.
Context "data" field points to an srsran::srs_indication::srs_indication_pdu structure.
These hooks have information passed in using a jbpf_pdcp_ctx_info as shown below ..
typedef struct {
uint8_t used; /* Is the window used, 0 = not-used, 1 = used */
uint32_t num_pkts; /* Total packets */
uint32_t num_bytes; /* Total bytes*/
} jbpf_queue_info_t;
struct jbpf_pdcp_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint32_t cu_ue_index; /* if is_srb=True is cu_cp_ue_index, if is_srb=False is cu_up_ue_index */
uint8_t is_srb; /* true=srb, false=drb */
uint8_t rb_id; /* if is_srb=True: 0=srb0, 1=srb1, 2=srb2,
if is_srb=False: 1=drb1, 2=drb2, 3-drb3 ... */
uint8_t rlc_mode; /* 0=UM, 1=AM*/
// window details
jbpf_queue_info_t window_info; /* Window info */
};Called when a downlink PDCP bearer is created.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
```
Called when a downlink PDCP bearer is deleted.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
```
Called when a new SDU is received from higher layers.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1: sdu_length << 32 | count
```
Called when a PDCP data PDU is sent to RLC.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1 = pdu_length << 32 | count;
srs_meta_data2 = is_retx << 32 | latency_set
srs_meta_data3 = latency_ns // from sdu-arrival to transmission of the PDU
```
Called when a PDCP control PDU is sent to RLC.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1 = pdu_length
```
This is a notification when first byte of a PDCP SDU is transmitted by RLC.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1 = notif_count
```
Note that the notif_count means "up to and including" that count. i.e. in the following example
pdcp_dl_handle_tx_notification notif_count=0
pdcp_dl_handle_tx_notification notif_count=1
pdcp_dl_handle_tx_notification notif_count=5
the last message means that counts 2-5 are all being notified.
In RLC TM/UM mode, this is a notificaion when all bytes of a PDCP SDU have been sent to lower layers.
In RLC AM mode, this is a notificaion when all bytes of a PDCP SDU have been sent to lower layers, and acknowledged by the UE.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1 = notif_count
```
Note that the notif_count means "up to and including" that count. i.e. in the following example
pdcp_dl_handle_delivery_notification notif_count=0
pdcp_dl_handle_delivery_notification notif_count=1
pdcp_dl_handle_delivery_notification notif_count=5
the last message means that counts 2-5 are all being notified.
Called when an SDU is discarded by the PDCP layer
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1 = count <<
```
Called when a PDCP DL bearer is restablished.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
```
Called when a uplink PDCP bearer is created.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
```
Called when a uplink PDCP bearer is deleted.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
```
Called when a uplink PDCP data PDU is received from lower layers.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1: pdu_length << 32 | header_length
srs_meta_data2: count
```
Called when a uplink PDCP control PDU is received from lower layers.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1: pdu_length
```
Called when PDCP delivers an SDU to higher layers.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
srs_meta_data1: sdu_length
```
Called when a PDCP DL bearer is restablished.
Context info:
```
data: pointer to the jbpf_pdcp_ctx_info
data_end: pointer to end of the jbpf_pdcp_ctx_info
```
These hooks have information passed in using a jbpf_cucp_e1_ctx_info as shown below ..
struct jbpf_cucp_e1_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint64_t cu_cp_ue_index;
uint64_t gnb_cu_cp_ue_e1ap_id;
uint64_t gnb_cu_up_ue_e1ap_id;
};All of the CUCP hooks have this context.
Context info:
```
data: pointer to the jbpf_cucp_e1_ctx_info
data_end: pointer to end of the jbpf_cucp_e1_ctx_info
```
Called when CUCP sends a setup request to CUUP.
Called when CUCP sends a modification request to CUUP.
Called when CUCP sends a delete request to CUUP.
Called when CUCP determines that a bearer is inactive.
These hooks have information passed in using a jbpf_cuup_e1_ctx_info as shown below ..
struct jbpf_cuup_e1_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint64_t cu_up_ue_index;
uint64_t gnb_cu_cp_ue_e1ap_id;
uint64_t gnb_cu_up_ue_e1ap_id;
};All of the CUUP hooks have this context.
Context info:
```
data: pointer to the jbpf_cuup_e1_ctx_info
data_end: pointer to end of the jbpf_cuup_e1_ctx_info
srs_meta_data1 = success/fail
```
Called when CUUP processes a setup request from the CUCP.
Called when CUUP processes a modification request from the CUCP.
Called when CUUP processes a release request from the CUCP.
These hooks are called when UE contexts are created/upated/deleted in the CUCP.
These hooks have information passed in using a jbpf_cucp_uemgr_ctx_info as shown below ..
struct jbpf_cucp_uemgr_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint16_t du_index;
uint32_t plmn; /* (mcc << 16) || mnc */
uint64_t cu_cp_ue_index;
};Called when a new UE context is created.
Context info:
```
data: pointer to the jbpf_cuup_e1_ctx_info
data_end: pointer to end of the jbpf_cuup_e1_ctx_info
srs_meta_data1 = pci_set << 16 | pci
srs_meta_data2 = rnti_set << 16 | rnti
```
Called when a new UE context is updated.
Context info:
```
data: pointer to the jbpf_cuup_e1_ctx_info
data_end: pointer to end of the jbpf_cuup_e1_ctx_info
srs_meta_data1 = pci
srs_meta_data2 = rnti
```
Called when a new UE context is deleted.
Context info:
```
data: pointer to the jbpf_cuup_e1_ctx_info
data_end: pointer to end of the jbpf_cuup_e1_ctx_info
```
These hooks are called when NGAP procedures are execured.
These hooks have information passed in using a jbpf_ngap_ctx_info as shown below ..
struct jbpf_ngap_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint64_t cucp_ue_index;
uint16_t ran_ue_ngap_id_set;
uint64_t ran_ue_ngap_id; /* RAN UE NGAP ID */
uint16_t amf_ue_ngap_id_set;
uint64_t amf_ue_ngap_id; /* AMF UE NGAP ID */
};The different procedures are identified by this enum ..
typedef enum {
NGAP_PROCEDURE_INITIAL_CONTEXT_SETUP = 1,
NGAP_PROCEDURE_UE_CONTEXT_RELEASE,
NGAP_PROCEDURE_PDU_SESSION_SETUP,
NGAP_PROCEDURE_PDU_SESSION_MODIFY,
NGAP_PROCEDURE_PDU_SESSION_RELEASE,
NGAP_PROCEDURE_RESOURCE_ALLOCATION,
NGAP_PROCEDURE_MAX
} JbpfNgapProcedure_t;Called when an NGAP procedure is started.
Context info:
```
data: pointer to the jbpf_ngap_ctx_info
data_end: pointer to end of the jbpf_ngap_ctx_info
srs_meta_data1: procedure (i.e. JbpfNgapProcedure_t)
```
Called when an NGAP procedure is completed.
Context info:
```
data: pointer to the jbpf_ngap_ctx_info
data_end: pointer to end of the jbpf_ngap_ctx_info
srs_meta_data1: = success << 32 | procedure;
```
Called when an NGAP RESET occurs.
Context info:
```
data: pointer to the jbpf_ngap_ctx_info
data_end: pointer to end of the jbpf_ngap_ctx_info
```
These hooks are called when RRC procedures are execured.
These hooks have information passed in using a jbpf_rrc_ctx_info as shown below ..
struct jbpf_rrc_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint64_t cu_cp_ue_index;
};The different procedures are identified by this enum ..
typedef enum {
RRC_SETUP = 1,
RRC_RECONFIGURATION,
RRC_REESTABLISHMENT,
RRC_UE_CAPABILITY,
RRC_PROCEDURE_MAX
} JbpfRrcProcedure_t;Called when a UE entity is created in RRC.
Context info:
```
data: pointer to the jbpf_rrc_ctx_info
data_end: pointer to end of the jbpf_rrc_ctx_info
srs_meta_data1 = (c_rnti << 48) | (pci << 32) | tac
srs_meta_data2 = plmn
srs_meta_data3 = nci
```
Called when a UE entity is updated in RRC.
Context info:
```
data: pointer to the jbpf_rrc_ctx_info
data_end: pointer to end of the jbpf_rrc_ctx_info
srs_meta_data1: old_cu_ue_index;
srs_meta_data2: (c_rnti << 48) | (pci << 32) | tac
srs_meta_data3: plmn
srs_meta_data4: nci;
```
Called when a UE'd 5GTMSI is updated in RRC.
Context info:
```
data: pointer to the jbpf_rrc_ctx_info
data_end: pointer to end of the jbpf_rrc_ctx_info
srs_meta_data1 =_5gtimsi;
```
Called when a UE entity is deleted in RRC.
Context info:
```
data: pointer to the jbpf_rrc_ctx_info
data_end: pointer to end of the jbpf_rrc_ctx_info
```
Called when an RRC procedure is started.
Context info:
```
data: pointer to the jbpf_rrc_ctx_info
data_end: pointer to end of the jbpf_rrc_ctx_info
srs_meta_data1: procedure (i.e JbpfRrcProcedure_t)
```
Called when an RRC procedure is completed.
Context info:
```
data: pointer to the jbpf_rrc_ctx_info
data_end: pointer to end of the jbpf_rrc_ctx_info
srs_meta_data1:srs_meta_data1 = (success << 32) | procedure;
```
These hooks have information passed in using a jbpf_rlc_ctx_info as shown below ..
struct jbpf_rlc_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint64_t gnb_du_id;
uint16_t du_ue_index;
uint8_t is_srb; /* true=srb, false=drb */
uint8_t rb_id; /* if is_srb=True: 0=srb0, 1=srb1, 2=srb2,
if is_srb=False: 1=drb1, 2=drb2, 3-drb3 ... */
JbpfDirection_t direction; /* 0 DL, 1 UL */
JbpfRlcMode_t rlc_mode; /* 0=TM, 1=UM, 2=AM*/
union {
struct {
jbpf_queue_info_t sdu_queue_info; /* SDU queue info */
} tm_tx;
struct {
jbpf_queue_info_t sdu_queue_info; /* SDU queue info */
} um_tx;
struct {
jbpf_queue_info_t sdu_queue_info; /* SDU queue info */
jbpf_queue_info_t window_info; /* Window info */
} am_tx;
struct {
uint32_t window_num_pkts; /* Window info */
} um_rx;
struct {
uint32_t window_num_pkts; /* Window info */
} am_rx;
} u;
};These enums are also used ..
typedef enum {
JBPF_RLC_MODE_TM = 1,
JBPF_RLC_MODE_UM,
JBPF_RLC_MODE_AM,
JBPF_RLC_MODE_MAX
} JbpfRlcMode_t;
typedef enum {
JBPF_RLC_PDUTYPE_STATUS = 1,
JBPF_RLC_PDUTYPE_DATA,
JBPF_RLC_PDUTYPE_DATA_RETX,
JBPF_RLC_PDUTYPE_MAX
} JbpfRlcPdu_t;Called when a downlink RLC bearer is created.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
```
Called when a downlink RLC bearer is deleted.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
```
Called when a new SDU is received from PDCP.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: sdu_length << 32 | pdcp_sn
srs_meta_data2: is_retx
```
Called when an SDU is dropped due to an internal overflow.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: sdu_length << 32 | pdcp_sn
srs_meta_data2: is_retx
```
Called when a SDU is discarded.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: pdcp_sn << 32 | success
```
Called when the first byte of an SDU is transmitted.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: pdcp_sn << 32 | is_retx
srs_meta_data2: latency_ns // time from sdu-arrival to start of transmission of the first byte
```
Called when all bytes of the SDU have been transmitted.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: pdcp_sn << 32 | is_retx
srs_meta_data2: latency_ns // time from sdu-arrival to when all bytes have been transmitted.
```
Called when all bytes of the SDU have been received by the peer RLC entity
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: pdcp_sn << 32 | is_retx
srs_meta_data2: latency_ns // time from sdu-arrival to when all bytes have been acknowledgd as received by the UE.
```
Called when an RLC PDU is transmitted.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: pdu_type << 32 | pdu_len
```
Called when a STATUS PDU is received from lower layers.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
```
Called when a PDU is retransmitted, ahd shows thw retx count.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: sn << 32 | retx_count
```
Called when the maximum allowed RLC retransmissions is reached.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: sn << 32 | retx_count
```
Called when a uplink RLC bearer is created.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
```
Called when a uplink RLC bearer is deleted.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
```
Called when a PDU is received from lower layers.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: pdu_type << 32 | pdu_len
```
Called when a PDU is received for an SDU for which no bytes have previously been received.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1 = sn
```
Called when an SDU is delivered to higher layers.
Context info:
```
data: pointer to the jbpf_rlc_ctx_info
data_end: pointer to end of the jbpf_rlc_ctx_info
srs_meta_data1: sn << 32 | sdu_length
srs_meta_data2: latency_ns // from start of SDU reception to SDU delivery
```
This is called from the code in the srsRAN where the scheduler is deciding how to schedule the various slices.
The hook has the current slice configuration passed in using a __jbpf_slice_allocation__ structure as shown below ..
// MAC slice control
#define JBPF_MAX_SLICES (16)
struct jbpf_slice_allocation {
uint8_t num_slices;
struct {
uint16_t pci;
uint32_t plmn_id; // bcd format
struct {
uint8_t sst;
uint32_t sd;
} nssai;
uint8_t min_prb_policy_ratio; // Sets the minimum percentage of PRBs to be allocated to the slice. Supported [0 - 100].
uint8_t max_prb_policy_ratio; // Sets the maximum percentage of PRBs to be allocated to the slice. Supported [1 - 100].
uint8_t priority; // Sets the slice priority. Values: [0 - 254].
} slices[JBPF_MAX_SLICES];
};Context info:
```
sfn : current sfn
slot_index: current slot index
data: pointer to the __jbpf_slice_allocation__
data_end: pointer to end of the __jbpf_slice_allocation__
```
It is a control hook. The srsRAN slice configuration is updated if the codelet changes the contents of the __jbpf_slice_allocation__ structure.
Note that no slices can added or deleted, only the __min_prb_policy_ratio__, __max_prb_policy_ratio__ and __priority__ fields can be changed.
This is a predefine hook built into the Jbpf framework. It is called invoked every second.
The information passed is shown below. However any codelet can be bound to this hook if a periodic trigger is required.
The hook has information passed in using a jbpf_perf_hook_list_ as shown below ..
struct jbpf_perf_data
{
uint64_t num;
uint64_t min;
uint64_t max;
uint32_t hist[JBPF_NUM_HIST_BINS];
jbpf_hook_name_t hook_name;
};
struct jbpf_perf_hook_list
{
uint8_t num_reported_hooks;
struct jbpf_perf_data perf_data[MAX_NUM_HOOKS];
} Context info:
```
data: pointer to the jbpf_perf_hook_list
data_end: pointer to end of the jbpf_perf_hook_list
meas_period: Period of measurements in ms
```
These hoks are used to track PDU sessions, and can be used to correlate the slice NSSAI and bearer DRB.
All the hooks have information passed in using a jbpf_pdu_session_ctx_info as shown below ..
struct jbpf_pdu_session_ctx_info {
uint16_t ctx_id; /* Context id (could be implementation specific) */
uint64_t cu_cp_ue_index;
uint16_t pdu_session_id;
uint16_t drb_id;
struct {
uint8_t sst;
uint32_t sd;
} nssai;
};Context info:
data: pointer to the jbpf_pdu_session_ctx_info
data_end: pointer to end of the jbpf_pdu_session_ctx_info