diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 3d4fdae8c..1c484585c 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -221,6 +221,8 @@ public: srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; virtual void enable_integrity(uint16_t rnti, uint32_t lcid) = 0; virtual void enable_encryption(uint16_t rnti, uint32_t lcid) = 0; + virtual bool + get_bearer_status(uint16_t rnti, uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) = 0; }; // PDCP interface for RLC @@ -294,6 +296,12 @@ public: class s1ap_interface_rrc { public: + struct bearer_status_info { + uint8_t erab_id; + uint16_t pdcp_dl_sn, pdcp_ul_sn; + uint16_t dl_hfn, ul_hfn; + }; + virtual void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer_t pdu) = 0; virtual void initial_ue(uint16_t rnti, @@ -312,6 +320,7 @@ public: uint32_t target_eci, srslte::plmn_id_t target_plmn, srslte::unique_byte_buffer_t rrc_container) = 0; + virtual bool send_enb_status_transfer_proc(uint16_t rnti, std::vector& bearer_status_list) = 0; }; // Combined interface for PHY to access stack (MAC and RRC) diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 84f7f605f..13cedc0b3 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -63,6 +63,7 @@ public: INTEGRITY_ALGORITHM_ID_ENUM integ_algo); void enable_integrity(uint32_t lcid); void enable_encryption(uint32_t lcid); + bool get_bearer_status(uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn); // RLC interface void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu); diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index 921b0320d..c67a9dbd1 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -58,6 +58,7 @@ public: // GW/RRC interface void write_sdu(unique_byte_buffer_t sdu, bool blocking); + void get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn); uint32_t get_dl_count(); uint32_t get_ul_count(); diff --git a/lib/src/asn1/liblte_s1ap.cc b/lib/src/asn1/liblte_s1ap.cc index 1edc854fc..b4a520703 100644 --- a/lib/src/asn1/liblte_s1ap.cc +++ b/lib/src/asn1/liblte_s1ap.cc @@ -1892,7 +1892,7 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_hfn(LIBLTE_S1AP_HFN_STRUCT* ie, uint8_t** ptr // lb:0, ub:1048575 // Range > 65536 - encoded based on value { - uint32_t n_bits = floor(log2(ie->HFN - 0) + 1); + uint32_t n_bits = (ie->HFN == 0) ? 1u : (uint32_t)floor(log2(ie->HFN - 0) + 1); // avoid log(0) uint32_t n_octets = (n_bits + 7) / 8; liblte_value_2_bits(n_octets - 1, ptr, 2); liblte_align_up_zero(ptr, 8); @@ -3434,7 +3434,7 @@ liblte_s1ap_unpack_source_totarget_transparentcontainer(uint8_t** if (0 == liblte_bits_2_value(ptr, 1)) { ie->n_octets = liblte_bits_2_value(ptr, 14); } else { - // FIXME: Unlikely to have more than 16K of octets + // FIXME: Unlikely to have more than 16k of octets } } @@ -3495,7 +3495,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_srvcchoindication(uint8_t** ptr, LIBLTE_S1A /* ProtocolIE SourceRNC_ToTargetRNC_TransparentContainer DYNAMIC OCTET STRING ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcernc_totargetrnc_transparentcontainer( - LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -3524,7 +3525,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcernc_totargetrnc_transparentcontainer( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourcernc_totargetrnc_transparentcontainer( - uint8_t** ptr, LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -3635,7 +3637,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_synchronizationstatus(uint8_t** /* ProtocolIE TargetRNC_ToSourceRNC_TransparentContainer DYNAMIC OCTET STRING ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_tosourcernc_transparentcontainer( - LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -3664,7 +3667,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_tosourcernc_transparentcontainer( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_tosourcernc_transparentcontainer( - uint8_t** ptr, LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -5778,7 +5782,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_serialnumber(uint8_t** ptr, LIBLTE_S1AP_SER /* ProtocolIE SourceBSS_ToTargetBSS_TransparentContainer DYNAMIC OCTET STRING ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcebss_totargetbss_transparentcontainer( - LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -5807,7 +5812,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcebss_totargetbss_transparentcontainer( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourcebss_totargetbss_transparentcontainer( - uint8_t** ptr, LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -6200,7 +6206,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_threshold_rsrp(uint8_t** ptr, LIBLTE_S1AP_T /* ProtocolIE Time_UE_StayedInCell_EnhancedGranularity INTEGER ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_time_ue_stayedincell_enhancedgranularity( - LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -6217,7 +6224,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_time_ue_stayedincell_enhancedgranularity( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_time_ue_stayedincell_enhancedgranularity( - uint8_t** ptr, LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -8217,7 +8225,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tabasedmdt(uint8_t** ptr, LIBLTE_S1AP_TABAS /* ProtocolIE TargeteNB_ToSourceeNB_TransparentContainer SEQUENCE ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer( - LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -8249,7 +8258,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_tosourceenb_transparentcontainer( - uint8_t** ptr, LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -10123,7 +10133,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_id(uint8_t** ptr, LIBLTE_S1AP_TAR /* ProtocolIE TargetBSS_ToSourceBSS_TransparentContainer DYNAMIC OCTET STRING ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetbss_tosourcebss_transparentcontainer( - LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -10152,7 +10163,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetbss_tosourcebss_transparentcontainer( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetbss_tosourcebss_transparentcontainer( - uint8_t** ptr, LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -14587,7 +14599,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdtmode(uint8_t** ptr, LIBLTE_S1AP_MDTMODE_ /* ProtocolIE SourceeNB_ToTargeteNB_TransparentContainer SEQUENCE ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer( - LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -14640,7 +14653,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_totargetenb_transparentcontainer( - uint8_t** ptr, LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -14656,6 +14670,7 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_totargetenb_transparentcontainer( ie->e_RABInformationList_present = liblte_bits_2_value(ptr, 1); ie->subscriberProfileIDforRFP_present = liblte_bits_2_value(ptr, 1); ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); if (liblte_s1ap_unpack_rrc_container(ptr, &ie->rRC_Container) != LIBLTE_SUCCESS) { @@ -14982,7 +14997,8 @@ liblte_s1ap_pack_enb_statustransfer_transparentcontainer(LIBLTE_S1AP_ENB_STATUST } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_statustransfer_transparentcontainer( - uint8_t** ptr, LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -16632,7 +16648,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taiitem(uint8_t** ptr, LIBLTE_S1AP_TAIITEM_ ********************************************************************************/ // lb:1, ub:256 LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistres( - LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -16675,7 +16692,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistres( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistres( - uint8_t** ptr, LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -16716,7 +16734,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistres( ********************************************************************************/ // lb:1, ub:256 LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistresack( - LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT* ie, uint8_t** ptr) + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT* ie, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -16759,7 +16778,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistresack( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistresack( - uint8_t** ptr, LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT* ie) + uint8_t** ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT* ie) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -18086,7 +18106,8 @@ liblte_s1ap_pack_allocationandretentionpriority_ext(LIBLTE_S1AP_MESSAGE_ALLOCATI } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_allocationandretentionpriority_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_ALLOCATIONANDRETENTIONPRIORITY_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_ALLOCATIONANDRETENTIONPRIORITY_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -18874,7 +18895,8 @@ liblte_s1ap_pack_criticalitydiagnostics_ie_item_ext(LIBLTE_S1AP_MESSAGE_CRITICAL } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ie_item_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_IE_ITEM_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_IE_ITEM_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -18936,7 +18958,8 @@ liblte_s1ap_pack_emergencyareaid_broadcast_item_ext(LIBLTE_S1AP_MESSAGE_EMERGENC } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_broadcast_item_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_BROADCAST_ITEM_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_BROADCAST_ITEM_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -18998,7 +19021,8 @@ liblte_s1ap_pack_emergencyareaid_cancelled_item_ext(LIBLTE_S1AP_MESSAGE_EMERGENC } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_cancelled_item_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_CANCELLED_ITEM_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_CANCELLED_ITEM_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -19211,7 +19235,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_globalenb_id_ext(uint8_t** ptr, LIBLTE_S1AP /* Protocol Message ENB_StatusTransfer_TransparentContainer_Ext STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_statustransfer_transparentcontainer_ext( - LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -19240,7 +19265,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_statustransfer_transparentcontainer_ext( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_statustransfer_transparentcontainer_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21142,7 +21168,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_id_ext(uint8_t** ptr, LIBLTE_S1AP /* Protocol Message TargeteNB_ToSourceeNB_TransparentContainer_Ext STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer_ext( - LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21171,7 +21198,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer_ex } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_tosourceenb_transparentcontainer_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21451,7 +21479,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_s1ap_id_pair_ext(uint8_t** /* Protocol Message UE_associatedLogicalS1_ConnectionItemExt STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemext( - LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21480,7 +21509,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemext( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitemext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21696,7 +21726,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2exttla_ext(uint8_t** ptr, LIBLTE_S1AP_ /* Protocol Message SourceeNB_ToTargeteNB_TransparentContainer_Ext STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer_ext( - LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21745,7 +21776,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer_ex } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_totargetenb_transparentcontainer_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21884,7 +21916,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlist(uint8_t** /* Protocol Message LastVisitedEUTRANCellInformation_Ext STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedeutrancellinformation_ext( - LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -21953,7 +21986,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedeutrancellinformation_ext( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedeutrancellinformation_ext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -22105,7 +22139,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformationreply_ext(uint8_t** /* Protocol Message Bearers_SubjectToStatusTransfer_ItemExt STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_itemext( - LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -22196,7 +22231,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_itemext( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_itemext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -22540,7 +22576,8 @@ liblte_s1ap_unpack_x2tnlconfigurationinfo_ext(uint8_t** ptr, LIBLTE_S1AP_MESSAGE /* Protocol Message Bearers_SubjectToStatusTransfer_Item STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_item( - LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -22586,7 +22623,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_item( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_item( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -24978,7 +25016,8 @@ liblte_s1ap_pack_e_rabtobemodifyitembearermodreqext(LIBLTE_S1AP_MESSAGE_E_RABTOB } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifyitembearermodreqext( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFYITEMBEARERMODREQEXT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFYITEMBEARERMODREQEXT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -28286,7 +28325,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nasnondeliveryindication(uint8_t** /* Protocol Message UE_associatedLogicalS1_ConnectionItem STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitem( - LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -28332,7 +28372,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitem( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -28379,7 +28420,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem( /* Protocol Message UE_associatedLogicalS1_ConnectionItemRes STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemres( - LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -28426,7 +28468,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemres( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitemres( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -31475,7 +31518,8 @@ liblte_s1ap_pack_locationreportingfailureindication(LIBLTE_S1AP_MESSAGE_LOCATION } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_locationreportingfailureindication( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -33590,7 +33634,8 @@ liblte_s1ap_unpack_uplinkueassociatedlppatransport(uint8_t** /* Protocol Message DownlinkNonUEAssociatedLPPaTransport STRUCT ********************************************************************************/ LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinknonueassociatedlppatransport( - LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT* msg, uint8_t** ptr) + LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT* msg, + uint8_t** ptr) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -33648,7 +33693,8 @@ LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinknonueassociatedlppatransport( } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinknonueassociatedlppatransport( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -33758,7 +33804,8 @@ liblte_s1ap_pack_uplinknonueassociatedlppatransport(LIBLTE_S1AP_MESSAGE_UPLINKNO } LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinknonueassociatedlppatransport( - uint8_t** ptr, LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT* msg) + uint8_t** ptr, + LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 16c38b0f7..5bf145c57 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -247,6 +247,15 @@ void pdcp::enable_encryption(uint32_t lcid) pthread_rwlock_unlock(&rwlock); } +bool pdcp::get_bearer_status(uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) +{ + if (not valid_lcid(lcid)) { + return false; + } + pdcp_array[lcid]->get_bearer_status(dlsn, dlhfn, ulsn, ulhfn); + return true; +} + /******************************************************************************* RLC interface *******************************************************************************/ diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 18ecb3e5a..775c60daf 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -292,6 +292,28 @@ uint32_t pdcp_entity_lte::get_ul_count() return tx_count; } +void pdcp_entity_lte::get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) +{ + if (cfg.rb_type == PDCP_RB_IS_DRB) { + if (12 == cfg.sn_len) { + *dlsn = (uint16_t)(tx_count & 0xFFFu); + *dlhfn = (uint16_t)((tx_count - *dlsn) >> 12u); + *ulsn = (uint16_t)(rx_count & 0xFFFu); + *ulhfn = (uint16_t)((rx_count - *ulsn) >> 12u); + } else { + *dlsn = (uint16_t)(tx_count & 0x7Fu); + *dlhfn = (uint16_t)((tx_count - *dlsn) >> 7u); + *ulsn = (uint16_t)(rx_count & 0x7Fu); + *ulhfn = (uint16_t)((rx_count - *ulsn) >> 7u); + } + } else { // is control + *dlsn = (uint16_t)(tx_count & 0x1Fu); + *dlhfn = (uint16_t)((tx_count - *dlsn) >> 5u); + *ulsn = (uint16_t)(rx_count & 0x1Fu); + *ulhfn = (uint16_t)((rx_count - *ulsn) >> 5u); + } +} + /**************************************************************************** * Pack/Unpack helper functions * Ref: 3GPP TS 36.323 v10.1.0 diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index fe4d7ae7f..1ae378a35 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -91,6 +91,7 @@ private: enum class ho_interface_t { S1, X2, interSector }; bool start_ho_preparation(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available); + bool start_enb_status_transfer(); rrc::ue* rrc_ue = nullptr; rrc* rrc_enb = nullptr; @@ -131,7 +132,7 @@ private: asn1::rrc::meas_result_eutra_s meas_res; uint32_t target_eci = 0; - enum class state_t { ho_preparation } state{}; + enum class state_t { ho_preparation, ho_execution } state{}; ho_interface_t ho_interface{}; bool fwd_direct_path_available = false; }; diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 6326430b7..95a4f4c0f 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -57,6 +57,8 @@ public: srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_); void enable_integrity(uint16_t rnti, uint32_t lcid); void enable_encryption(uint16_t rnti, uint32_t lcid); + bool get_bearer_status(uint16_t rnti, uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) + override; private: class user_interface_rlc : public srsue::rlc_interface_pdcp diff --git a/srsenb/hdr/stack/upper/s1ap.h b/srsenb/hdr/stack/upper/s1ap.h index f7e07c49b..7eca568bb 100644 --- a/srsenb/hdr/stack/upper/s1ap.h +++ b/srsenb/hdr/stack/upper/s1ap.h @@ -149,15 +149,17 @@ private: bool send_ho_required(uint16_t rnti, uint32_t target_eci, srslte::plmn_id_t target_plmn, - srslte::unique_byte_buffer_t rrc_container); + srslte::unique_byte_buffer_t rrc_container) override; bool handle_hopreparationfailure(LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT* msg); bool handle_s1hocommand(LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT& msg); + bool send_enb_status_transfer_proc(uint16_t rnti, std::vector& bearer_status_list) override; bool find_mme_ue_id(uint32_t mme_ue_id, uint16_t* rnti, uint32_t* enb_ue_id); std::string get_cause(const LIBLTE_S1AP_CAUSE_STRUCT* c); // UE-specific data and procedures struct ue { + //! TS 36.413, Section 8.4.1 - Handover Preparation Procedure class ho_prep_proc_t { public: @@ -187,9 +189,12 @@ private: ue_ctxt_t& get_ctxt() { return ctxt; } srslte::proc_t& get_ho_prep_proc() { return ho_prep_proc; } + bool send_enb_status_transfer_proc(std::vector& bearer_status_list); + private: bool send_ho_required(uint32_t target_eci_, srslte::plmn_id_t target_plmn_, srslte::unique_byte_buffer_t rrc_container); + //! TS 36.413, Section 8.4.6 - eNB Status Transfer procedure s1ap* s1ap_ptr; srslte::log* s1ap_log; diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index dfde889f1..0427b9252 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -883,6 +883,31 @@ void rrc::ue::rrc_mobility::handle_ho_preparation_complete(bool is_success, srsl source_ho_proc.trigger(sourceenb_ho_proc_t::ho_prep_result{is_success, std::move(container)}); } +/** + * TS 36.413, Section 8.4.6 - eNB Status Transfer + * Description: Send "eNBStatusTransfer" message from source eNB to MME + * - Pass bearers' DL/UL HFN and PDCP SN to be put inside a transparent container + */ +bool rrc::ue::rrc_mobility::start_enb_status_transfer() +{ + std::vector bearer_list; + bearer_list.reserve(rrc_ue->erabs.size()); + + for (const auto& erab_pair : rrc_ue->erabs) { + s1ap_interface_rrc::bearer_status_info b = {}; + uint8_t lcid = erab_pair.second.id - 2u; + b.erab_id = erab_pair.second.id; + if (not rrc_enb->pdcp->get_bearer_status(rrc_ue->rnti, lcid, &b.pdcp_dl_sn, &b.dl_hfn, &b.pdcp_ul_sn, &b.ul_hfn)) { + Error("PDCP bearer lcid=%d for rnti=0x%x was not found\n", lcid, rrc_ue->rnti); + return false; + } + bearer_list.push_back(b); + } + + Info("PDCP Bearer list sent to S1AP to initiate the eNB Status Transfer\n"); + return rrc_enb->s1ap->send_enb_status_transfer_proc(rrc_ue->rnti, bearer_list); +} + /************************************************************************************************* * sourceenb_ho_proc_t class ************************************************************************************************/ @@ -965,6 +990,13 @@ srslte::proc_outcome_t rrc::ue::rrc_mobility::sourceenb_ho_proc_t::react(ho_prep /* Send HO Command to UE */ parent->rrc_ue->send_dl_dcch(&dl_dcch_msg); procInfo("HandoverCommand of rnti=0x%x handled successfully.\n", parent->rrc_ue->rnti); + state = state_t::ho_execution; + + /* Start S1AP eNBStatusTransfer Procedure */ + if (not parent->start_enb_status_transfer()) { + return srslte::proc_outcome_t::error; + } + return srslte::proc_outcome_t::success; } diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 9607e33e5..8e6047a08 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -138,6 +138,18 @@ void pdcp::enable_encryption(uint16_t rnti, uint32_t lcid) pthread_rwlock_unlock(&rwlock); } +bool pdcp::get_bearer_status(uint16_t rnti, + uint32_t lcid, + uint16_t* dlsn, + uint16_t* dlhfn, + uint16_t* ulsn, + uint16_t* ulhfn) +{ + if (users.count(rnti) == 0) + return false; + return users[rnti].pdcp->get_bearer_status(lcid, dlsn, dlhfn, ulsn, ulhfn); +} + void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) { pthread_rwlock_rdlock(&rwlock); diff --git a/srsenb/src/stack/upper/s1ap.cc b/srsenb/src/stack/upper/s1ap.cc index 987bbe165..b1cb8ae17 100644 --- a/srsenb/src/stack/upper/s1ap.cc +++ b/srsenb/src/stack/upper/s1ap.cc @@ -1221,6 +1221,19 @@ bool s1ap::send_ho_required(uint16_t rnti, return true; } +bool s1ap::send_enb_status_transfer_proc(uint16_t rnti, std::vector& bearer_status_list) +{ + if (not mme_connected) { + return false; + } + auto it = users.find(rnti); + if (it == users.end()) { + return false; + } + + return it->second->send_enb_status_transfer_proc(bearer_status_list); +} + // bool s1ap::send_ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps) //{ // srslte::byte_buffer_t msg; @@ -1468,4 +1481,40 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, return s1ap_ptr->sctp_send_s1ap_pdu(&tx_pdu, ctxt.rnti, "HORequired"); } +bool s1ap::ue::send_enb_status_transfer_proc(std::vector& bearer_status_list) +{ + if (bearer_status_list.empty()) { + return false; + } + + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu = {}; + tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE; + tx_pdu.choice.initiatingMessage.choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBSTATUSTRANSFER; + tx_pdu.choice.initiatingMessage.procedureCode = 24; + + auto& status = tx_pdu.choice.initiatingMessage.choice.ENBStatusTransfer; + status.eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ctxt.eNB_UE_S1AP_ID; + status.MME_UE_S1AP_ID.MME_UE_S1AP_ID = ctxt.MME_UE_S1AP_ID; + + /* Create StatusTransfer transparent container with all the bearer ctxt to transfer */ + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT& status_cont = + status.eNB_StatusTransfer_TransparentContainer; + status_cont.bearers_SubjectToStatusTransferList.len = bearer_status_list.size(); + for (uint32_t i = 0; i < bearer_status_list.size(); ++i) { + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT& asn1bearer = + status_cont.bearers_SubjectToStatusTransferList.buffer[i]; + bearer_status_info& item = bearer_status_list[i]; + + asn1bearer.e_RAB_ID.E_RAB_ID = item.erab_id; + asn1bearer.dL_COUNTvalue.pDCP_SN.PDCP_SN = item.pdcp_dl_sn; + asn1bearer.dL_COUNTvalue.hFN.HFN = item.dl_hfn; + asn1bearer.uL_COUNTvalue.pDCP_SN.PDCP_SN = item.pdcp_ul_sn; + asn1bearer.uL_COUNTvalue.hFN.HFN = item.ul_hfn; + + // TODO: asn1bearer.receiveStatusofULPDCPSDUs_present + } + + return s1ap_ptr->sctp_send_s1ap_pdu(&tx_pdu, ctxt.rnti, "ENBStatusTransfer"); +} + } // namespace srsenb