mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-17 22:50:31 +00:00
Compare commits
1 Commits
pre-commit
...
rrc-sib10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbf46555bd |
@@ -150,6 +150,8 @@ typedef struct f1ap_gnb_du_system_info_s {
|
||||
// SIB1 message (Mandatory)
|
||||
uint8_t *sib1;
|
||||
int sib1_length;
|
||||
// SIB10 message (optional, TS 38.473 §9.3.1.18)
|
||||
byte_array_t *sib10;
|
||||
} f1ap_gnb_du_system_info_t;
|
||||
|
||||
typedef struct f1ap_setup_req_s {
|
||||
|
||||
@@ -429,6 +429,7 @@ static void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_d
|
||||
if (sys_info) {
|
||||
free(sys_info->mib);
|
||||
free(sys_info->sib1);
|
||||
FREE_OPT_BYTE_ARRAY(sys_info->sib10);
|
||||
free((void *)sys_info);
|
||||
}
|
||||
free(info->measurement_timing_config);
|
||||
@@ -599,6 +600,20 @@ static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_sy
|
||||
AssertFatal(sys_info->sib1 != NULL, "SIB1 must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&enc_sys_info->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length);
|
||||
|
||||
/* Optional: SIB10-message extension IE (TS 38.473 9.3.1.18) */
|
||||
if (sys_info->sib10) {
|
||||
byte_array_t *sib10 = sys_info->sib10;
|
||||
DevAssert(sib10->buf != NULL);
|
||||
DevAssert(sib10->len > 0);
|
||||
F1AP_ProtocolExtensionContainer_11023P123_t *p = calloc_or_fail(1, sizeof(*p));
|
||||
enc_sys_info->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p;
|
||||
asn1cSequenceAdd(p->list, F1AP_GNB_DU_System_Information_ExtIEs_t, ext);
|
||||
ext->id = F1AP_ProtocolIE_ID_id_SIB10_message;
|
||||
ext->criticality = F1AP_Criticality_ignore;
|
||||
ext->extensionValue.present = F1AP_GNB_DU_System_Information_ExtIEs__extensionValue_PR_SIB10_message;
|
||||
OCTET_STRING_fromBuf(&ext->extensionValue.choice.SIB10_message, (const char *)sib10->buf, sib10->len);
|
||||
}
|
||||
|
||||
return enc_sys_info;
|
||||
}
|
||||
|
||||
@@ -612,6 +627,24 @@ static void decode_system_info(struct F1AP_GNB_DU_System_Information *DUsi, f1ap
|
||||
sys_info->sib1 = calloc_or_fail(DUsi->sIB1_message.size, sizeof(*sys_info->sib1));
|
||||
memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size);
|
||||
sys_info->sib1_length = DUsi->sIB1_message.size;
|
||||
|
||||
/* Optional: SIB10-message extension IE */
|
||||
sys_info->sib10 = NULL;
|
||||
if (DUsi->iE_Extensions) {
|
||||
F1AP_ProtocolExtensionContainer_11023P123_t *p = (F1AP_ProtocolExtensionContainer_11023P123_t *)DUsi->iE_Extensions;
|
||||
for (int i = 0; i < p->list.count; ++i) {
|
||||
F1AP_GNB_DU_System_Information_ExtIEs_t *ext = p->list.array[i];
|
||||
struct F1AP_GNB_DU_System_Information_ExtIEs__extensionValue *val = &ext->extensionValue;
|
||||
if (ext->id == F1AP_ProtocolIE_ID_id_SIB10_message
|
||||
&& val->present == F1AP_GNB_DU_System_Information_ExtIEs__extensionValue_PR_SIB10_message) {
|
||||
F1AP_SIB10_message_t *sib10_msg = &val->choice.SIB10_message;
|
||||
if (sib10_msg->size > 0) {
|
||||
sys_info->sib10 = calloc_or_fail(1, sizeof(*sys_info->sib10));
|
||||
*sys_info->sib10 = create_byte_array(sib10_msg->size, sib10_msg->buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void encode_cells_to_activate(const served_cells_to_activate_t *cell, F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_ies)
|
||||
@@ -936,6 +969,11 @@ static f1ap_gnb_du_system_info_t *copy_f1ap_gnb_du_system_info(const f1ap_gnb_du
|
||||
memcpy(dst->sib1, src->sib1, dst->sib1_length);
|
||||
}
|
||||
|
||||
if (src->sib10) {
|
||||
dst->sib10 = calloc_or_fail(1, sizeof(*dst->sib10));
|
||||
*(dst->sib10) = copy_byte_array(*(src->sib10));
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ bool eq_f1ap_sys_info(const f1ap_gnb_du_system_info_t *a, const f1ap_gnb_du_syst
|
||||
_EQ_CHECK_INT(a->sib1_length, b->sib1_length);
|
||||
for (int i = 0; i < a->sib1_length; i++)
|
||||
_EQ_CHECK_INT(a->sib1[i], b->sib1[i]);
|
||||
/* SIB10 (optional) */
|
||||
_EQ_CHECK_OPTIONAL_PTR(a, b, sib10);
|
||||
if (a->sib10 && b->sib10) {
|
||||
if (!eq_byte_array(a->sib10, b->sib10))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
#include "asn_internal.h"
|
||||
#include "NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
|
||||
#include "NR_SIB10-r16.h"
|
||||
#include "common/5g_platform_types.h"
|
||||
#include "common/config/config_paramdesc.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
@@ -62,6 +64,7 @@
|
||||
#include "f1ap_common.h"
|
||||
#include "gnb_paramdef.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
#include "f1ap_lib_common.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "nfapi_pnf.h"
|
||||
#include "nfapi_vnf.h"
|
||||
@@ -1084,6 +1087,48 @@ static f1ap_fdd_info_t read_fdd_config(const NR_ServingCellConfigCommon_t *scc)
|
||||
return fdd;
|
||||
}
|
||||
|
||||
static byte_array_t encode_sib10_from_hrnn_list(paramdef_t *GNBparamarray)
|
||||
{
|
||||
byte_array_t msg = {.buf = NULL, .len = 0};
|
||||
|
||||
const paramdef_t *p = &GNBparamarray[GNB_NPN_HRNN_LIST_IDX];
|
||||
if (p->numelt == 0 || p->strlistptr == NULL) {
|
||||
LOG_W(GNB_APP, "Failed to encode SIB10: npn_hrnn_list not configured\n");
|
||||
return msg;
|
||||
}
|
||||
|
||||
NR_SIB10_r16_t *sib10 = calloc_or_fail(1, sizeof(*sib10));
|
||||
sib10->hrnn_List_r16 = calloc_or_fail(1, sizeof(*sib10->hrnn_List_r16));
|
||||
|
||||
for (int i = 0; i < p->numelt; ++i) {
|
||||
const char *hrnn = p->strlistptr[i];
|
||||
if (!hrnn || hrnn[0] == '\0') {
|
||||
LOG_W(GNB_APP, "SIB10: HRNN[%d] is empty or NULL, skipping\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
NR_HRNN_r16_t *item = calloc_or_fail(1, sizeof(*item));
|
||||
item->hrnn_r16 = calloc_or_fail(1, sizeof(*item->hrnn_r16));
|
||||
OCTET_STRING_fromBuf(item->hrnn_r16, hrnn, strlen(hrnn));
|
||||
ASN_SEQUENCE_ADD(&sib10->hrnn_List_r16->list, item);
|
||||
LOG_I(GNB_APP, "SIB10: added HRNN[%d]=\"%s\" (len=%zu)\n", i, hrnn, strlen(hrnn));
|
||||
}
|
||||
|
||||
if (sib10->hrnn_List_r16->list.count == 0) {
|
||||
LOG_W(GNB_APP, "Failed to encode SIB10: all HRNN entries empty\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB10_r16, sib10);
|
||||
return msg;
|
||||
}
|
||||
|
||||
msg = do_SIB10_NR(sib10);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB10_r16, sib10);
|
||||
if (!msg.buf || msg.len <= 0) {
|
||||
LOG_E(GNB_APP, "Failed to encode SIB10\n");
|
||||
FREE_AND_ZERO_BYTE_ARRAY(msg);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1, seq_arr_t *du_SIBs)
|
||||
{
|
||||
int buf_len = 3;
|
||||
@@ -1104,9 +1149,15 @@ f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCC
|
||||
if (du_SIBs) {
|
||||
for (int i = 0; i < du_SIBs->size; i++) {
|
||||
nr_SIBs_t *si = (nr_SIBs_t *)seq_arr_at(du_SIBs, i);
|
||||
// other SIB in gNB-DU System Information not implemented yet
|
||||
// only DU SIB not included in this message is SIB19
|
||||
AssertFatal(si->SIB_type == 19, "Cannot handle SIB%d in gNB-DU System Information\n", si->SIB_type);
|
||||
if (si->SIB_type == 10) {
|
||||
sys_info->sib10 = calloc_or_fail(1, sizeof(*sys_info->sib10));
|
||||
*sys_info->sib10 = create_byte_array(si->SIB_size, si->SIB_buffer);
|
||||
LOG_I(GNB_APP, "Attached SIB10 (%d bytes) to gNB-DU System Information\n", si->SIB_size);
|
||||
} else {
|
||||
// other SIB in gNB-DU System Information not implemented yet
|
||||
// only DU SIB not included in this message is SIB19
|
||||
AssertFatal(si->SIB_type == 19, "Cannot handle SIB%d in gNB-DU System Information\n", si->SIB_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sys_info;
|
||||
@@ -1267,6 +1318,14 @@ static seq_arr_t *fill_du_sibs(paramdef_t *GNBparamarray)
|
||||
nr_SIBs_t *du_sib = calloc_or_fail(1, sizeof(nr_SIBs_t));
|
||||
du_sib->SIB_type = sib_value;
|
||||
LOG_I(GNB_APP, "activate SIB%d at DU\n", sib_value);
|
||||
if (sib_value == 10) {
|
||||
byte_array_t sib10 = encode_sib10_from_hrnn_list(GNBparamarray);
|
||||
du_sib->SIB_buffer = calloc_or_fail(sib10.len, sizeof(*du_sib->SIB_buffer));
|
||||
memcpy(du_sib->SIB_buffer, sib10.buf, sib10.len);
|
||||
du_sib->SIB_size = sib10.len;
|
||||
free_byte_array(sib10);
|
||||
LOG_I(GNB_APP, "SIB10: encoded %d bytes for DU SIB list\n", du_sib->SIB_size);
|
||||
}
|
||||
seq_arr_push_back(du_SIBs, du_sib, sizeof(nr_SIBs_t));
|
||||
}
|
||||
return du_SIBs;
|
||||
|
||||
@@ -124,6 +124,7 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_CONFIG_REP "CSI_report_type"
|
||||
#define GNB_CONFIG_STRING_1ST_ACTIVE_BWP "first_active_bwp"
|
||||
#define GNB_CONFIG_STRING_LIMIT_RSRP_REPORT "max_num_RSRP_reported"
|
||||
#define GNB_CONFIG_STRING_NPN_HRNN_LIST "npn_hrnn_list"
|
||||
|
||||
#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n"
|
||||
#define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support"
|
||||
@@ -186,6 +187,7 @@ typedef enum {
|
||||
{GNB_CONFIG_STRING_CONFIG_REP, GNB_CONFIG_HLP_CONFIG_REP, 0, .strptr=NULL, .defstrval="ssb_rsrp", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_1ST_ACTIVE_BWP, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_LIMIT_RSRP_REPORT, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{GNB_CONFIG_STRING_NPN_HRNN_LIST, NULL, 0, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST,0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -230,6 +232,7 @@ typedef enum {
|
||||
#define GNB_CONFIG_REP_IDX 37
|
||||
#define GNB_1ST_ACTIVE_BWP_IDX 38
|
||||
#define GNB_LIMIT_RSRP_REPORT_IDX 39
|
||||
#define GNB_NPN_HRNN_LIST_IDX 40
|
||||
|
||||
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
|
||||
#define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32}
|
||||
@@ -279,6 +282,7 @@ typedef enum {
|
||||
3 } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -44,9 +44,11 @@
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "NR_ServingCellConfigCommon.h"
|
||||
#include "NR_MIB.h"
|
||||
#include "NR_SIB10-r16.h"
|
||||
#include "SCHED_NR/phy_frame_config_nr.h"
|
||||
#include "T.h"
|
||||
#include "asn_internal.h"
|
||||
#include "uper_decoder.h"
|
||||
#include "assertions.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "common/utils/T/T.h"
|
||||
@@ -964,8 +966,20 @@ bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_
|
||||
add_sib_to_systeminformation(sysInfov17, type_du);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
AssertFatal(false, "Invalid or not supported SIB%d\n", sib_idx);
|
||||
case 10: {
|
||||
AssertFatal(si->SIB_buffer != NULL && si->SIB_size > 0, "SIB10 configured but empty payload\n");
|
||||
NR_SIB10_r16_t *sib10 = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB10_r16, (void **)&sib10, si->SIB_buffer, si->SIB_size);
|
||||
AssertFatal(dec_rval.code == RC_OK && sib10 != NULL, "Failed to decode SIB10 from payload\n");
|
||||
|
||||
struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type_du = calloc(1, sizeof(*type_du));
|
||||
type_du->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610;
|
||||
type_du->choice.sib10_v1610 = sib10;
|
||||
add_sib_to_systeminformation(sysInfo, type_du);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
AssertFatal(false, "Invalid or not supported DU SIB (index=%d, type=%u)\n", sib_idx, si->SIB_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -280,6 +280,18 @@ int do_SIB2_NR(uint8_t **msg_SIB2, NR_SSB_MTC_t *ssbmtc)
|
||||
return size;
|
||||
}
|
||||
|
||||
byte_array_t do_SIB10_NR(const NR_SIB10_r16_t *sib10)
|
||||
{
|
||||
byte_array_t msg = {.buf = NULL, .len = 0};
|
||||
|
||||
msg.len = uper_encode_to_new_buffer(&asn_DEF_NR_SIB10_r16, NULL, (void *)sib10, (void **)&msg.buf);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "Failed to encode SIB10\n");
|
||||
return msg;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int do_RRCReject(uint8_t *const buffer)
|
||||
{
|
||||
asn_enc_rval_t enc_rval;
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "NR_MeasurementTimingConfiguration.h"
|
||||
#include "NR_UE-NR-Capability.h"
|
||||
#include "NR_UE-CapabilityRAT-ContainerList.h"
|
||||
#include "NR_SIB10-r16.h"
|
||||
#include "ds/seq_arr.h"
|
||||
#include "ds/byte_array.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_configuration.h"
|
||||
@@ -88,6 +89,7 @@ typedef struct {
|
||||
int xer_sprint_NR(char *string, size_t string_size, struct asn_TYPE_descriptor_s *td, void *sptr);
|
||||
|
||||
int do_SIB2_NR(uint8_t **msg_SIB2, NR_SSB_MTC_t *ssbmtc);
|
||||
byte_array_t do_SIB10_NR(const NR_SIB10_r16_t *sib10);
|
||||
|
||||
int do_RRCReject(uint8_t *const buffer);
|
||||
|
||||
|
||||
@@ -155,6 +155,55 @@ TEST(nr_asn1, rrc_reconfiguration)
|
||||
free_RRCReconfiguration_params(params);
|
||||
}
|
||||
|
||||
static NR_SIB10_r16_t *build_sib10_with_hrnn(const std::vector<std::string> &hrnns)
|
||||
{
|
||||
NR_SIB10_r16_t *sib10 = (NR_SIB10_r16_t *)calloc_or_fail(1, sizeof(*sib10));
|
||||
sib10->hrnn_List_r16 = (NR_HRNN_List_r16_t *)calloc_or_fail(1, sizeof(*sib10->hrnn_List_r16));
|
||||
for (size_t i = 0; i < hrnns.size(); ++i) {
|
||||
NR_HRNN_r16_t *item = (NR_HRNN_r16_t *)calloc_or_fail(1, sizeof(*item));
|
||||
const std::string &h = hrnns[i];
|
||||
item->hrnn_r16 = (OCTET_STRING_t *)calloc_or_fail(1, sizeof(*item->hrnn_r16));
|
||||
OCTET_STRING_fromBuf(item->hrnn_r16, h.c_str(), h.size());
|
||||
ASN_SEQUENCE_ADD(&sib10->hrnn_List_r16->list, item);
|
||||
}
|
||||
return sib10;
|
||||
}
|
||||
|
||||
static NR_SIB10_r16_t *encode_and_decode_sib10(NR_SIB10_r16_t *sib10, byte_array_t *ba)
|
||||
{
|
||||
*ba = do_SIB10_NR(sib10);
|
||||
EXPECT_GT(ba->len, 0);
|
||||
EXPECT_NE(ba->buf, nullptr);
|
||||
|
||||
asn_dec_rval_t dec_rval;
|
||||
NR_SIB10_r16_t *out = nullptr;
|
||||
dec_rval = uper_decode_complete(nullptr, &asn_DEF_NR_SIB10_r16, (void **)&out, ba->buf, ba->len);
|
||||
EXPECT_EQ(dec_rval.code, RC_OK);
|
||||
return out;
|
||||
}
|
||||
|
||||
TEST(nr_asn1, sib10_basic_encode_decode)
|
||||
{
|
||||
std::vector<std::string> hrnns = {"OAI-NPN-1", "FactoryFloor", "CampusNet"};
|
||||
NR_SIB10_r16_t *sib10 = build_sib10_with_hrnn(hrnns);
|
||||
|
||||
byte_array_t ba = {};
|
||||
NR_SIB10_r16_t *decoded = encode_and_decode_sib10(sib10, &ba);
|
||||
|
||||
ASSERT_TRUE(decoded->hrnn_List_r16 != nullptr);
|
||||
ASSERT_EQ(decoded->hrnn_List_r16->list.count, (int)hrnns.size());
|
||||
for (size_t i = 0; i < hrnns.size(); ++i) {
|
||||
NR_HRNN_r16_t *item = decoded->hrnn_List_r16->list.array[i];
|
||||
ASSERT_NE(item->hrnn_r16, nullptr);
|
||||
std::string decoded_hrnn((char *)item->hrnn_r16->buf, (size_t)item->hrnn_r16->size);
|
||||
EXPECT_EQ(decoded_hrnn, hrnns[i]);
|
||||
}
|
||||
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB10_r16, sib10);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB10_r16, decoded);
|
||||
free_byte_array(ba);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logInit();
|
||||
|
||||
Reference in New Issue
Block a user