Compare commits

...

12 Commits

Author SHA1 Message Date
Nada Bouknana
bce35b1204 report the UE ID in order to support multiple UEs 2025-09-09 12:01:47 +02:00
Nada Bouknana
dfc140f517 Revert "tmp: send srs time estimates"
This reverts commit 40f83319fc.
2025-07-16 16:19:31 +02:00
Nada Bouknana
c7378cbbe4 increase the size of fapi structures to support 8 antennas 2025-07-03 10:27:10 +02:00
Nada Bouknana
40f83319fc tmp: send srs time estimates 2025-06-13 15:01:28 +02:00
Nada Bouknana
d906a0b67e fill the srs channel matrix with all the subcarrier values from srs_estimated_channel_freq 2025-06-09 20:29:12 +02:00
Nada Bouknana
2cd704aace send the full FAPI SRS.indication message to the RIC instead of just the SRS PDUs 2025-05-28 15:21:09 +02:00
Nada Bouknana
37a300aec6 send full srs channel estimates 2025-05-20 15:51:55 +02:00
Nada Bouknana
0444a7038a send the whole srs_indication_pdu_t including the estimated srs channel 2025-05-20 15:51:55 +02:00
Nada Bouknana
059e927af6 send the whole srs_indication_pdu_t including the estimated srs channel 2025-05-09 19:00:16 +02:00
Nada Bouknana
11def4f355 fix subscription for SRS-SM 2025-04-29 10:50:20 +02:00
Nada Bouknana
82a687d014 add support for SRS-SM event trigger 2025-04-25 10:52:59 +02:00
Nada Bouknana
25be958d65 add initial support for SRS-SM 2025-04-24 05:33:45 +02:00
13 changed files with 460 additions and 18 deletions

View File

@@ -1810,7 +1810,7 @@ typedef struct {
uint16_t num_ue_srs_ports; // Nu: Number of sampled UE SRS ports. Value: 07
uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) to which the same digital beamforming gets applied. Value: 1->272
uint16_t num_prgs; // Number of PRGs Np to be reported for this SRS PDU. Value: 0-> 272
uint8_t channel_matrix[272*2*8*4]; // Array of (numPRGs*Nu*Ng) entries of the type denoted by iqRepresentation H{PRG pI} [ueAntenna uI, gNB antenna gI] = array[uI*Ng*Np + gI*Np + pI]; uI: 0…Nu-1 (UE antenna index); gI: 0…Ng-1 (gNB antenna index); pI: 0…Np-1 (PRG index)
uint8_t channel_matrix[4096*2*8*4]; // Array of (NR_NB_SC_PER_RB*(numPRGs*Nu*Ng)) entries of the type denoted by iqRepresentation H{PRG pI} [ueAntenna uI, gNB antenna gI] = array[uI*Ng*Np + gI*Np + pI]; uI: 0…Nu-1 (UE antenna index); gI: 0…Ng-1 (gNB antenna index); pI: 0…Np-1 (PRG index)
} nfapi_nr_srs_normalized_channel_iq_matrix_t;
// Beamforming report
@@ -1837,7 +1837,7 @@ typedef struct {
typedef struct {
uint16_t tag; // 0: Report is carried directly in the value field; 3: The offset from the end of the control portion of the message to the beginning of the report. Other values are reserved.
uint32_t length; // Length of the actual report in bytes, without the padding bytes.
uint32_t value[16384]; // tag=0: Only the most significant bytes of the size indicated by length field are valid. Remaining bytes are zero padded to the nearest 32-bit bit boundary; Tag=2 Offset from the end of the control portion of the message to the payload is in the value field. Occupies 32-bits.
uint32_t value[4*16384]; // tag=0: Only the most significant bytes of the size indicated by length field are valid. Remaining bytes are zero padded to the nearest 32-bit bit boundary; Tag=2 Offset from the end of the control portion of the message to the payload is in the value field. Occupies 32-bits.
} nfapi_srs_report_tlv_t;
typedef struct {

View File

@@ -42,6 +42,8 @@
#include "nr_fapi.h"
#include "nr_fapi_p7.h"
//#include "common/utils/nr/nr_common.h"
extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMsg, void *user_data);
extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, void *user_data);
@@ -2531,9 +2533,14 @@ int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf
return 0;
}
uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs
uint32_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs
* nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports
* nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
// if (nr_srs_normalized_channel_iq_matrix->prg_size == 0){
// // (Not definde by FAPI) used for E2AP SRS-SM to send the full channel estimates to the RIC
// channel_matrix_size = NR_NB_SC_PER_RB * channel_matrix_size;
// }
if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) {
// 0: 16-bit normalized complex number (iqSize = 2)
channel_matrix_size <<= 1;
@@ -2542,7 +2549,7 @@ int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf
channel_matrix_size <<= 2;
}
for (int i = 0; i < channel_matrix_size; i++) {
for (size_t i = 0; i < channel_matrix_size; i++) {
if (!push8(nr_srs_normalized_channel_iq_matrix->channel_matrix[i], &pWritePackedMessage, end)) {
return 0;
}
@@ -4406,9 +4413,14 @@ int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf,
return -1;
}
uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs
uint32_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs
* nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports
* nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
// if (nr_srs_normalized_channel_iq_matrix->prg_size == 0){
// // (Not definde by FAPI) used for E2AP SRS-SM to send the full channel estimates to the RIC
// channel_matrix_size = NR_NB_SC_PER_RB * channel_matrix_size;
// }
if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) {
// 0: 16-bit normalized complex number (iqSize = 2)
channel_matrix_size <<= 1;
@@ -4417,7 +4429,7 @@ int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf,
channel_matrix_size <<= 2;
}
for (int i = 0; i < channel_matrix_size; i++) {
for (size_t i = 0; i < channel_matrix_size; i++) {
if (!pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->channel_matrix[i], end)) {
return 0;
}

View File

@@ -44,6 +44,7 @@
//#define DEBUG_RXDATA
//#define SRS_IND_DEBUG
#define E2_AGENT
int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols)
{
@@ -649,13 +650,16 @@ int fill_srs_channel_matrix(uint8_t *channel_matrix,
const uint16_t num_gnb_antenna_elements,
const uint16_t num_ue_srs_ports,
const uint16_t prg_size,
const uint16_t num_prgs,
const uint16_t num_samples,
const NR_DL_FRAME_PARMS *frame_parms,
const c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)])
[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)], uint16_t step_size)
{
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
const uint16_t step = prg_size*NR_NB_SC_PER_RB;
uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
const uint16_t step = step_size; //prg_size*NR_NB_SC_PER_RB;
if(prg_size == 0){
subcarrier_offset = 0;
}
c16_t *channel_matrix16 = (c16_t*)channel_matrix;
c8_t *channel_matrix8 = (c8_t*)channel_matrix;
@@ -664,13 +668,16 @@ int fill_srs_channel_matrix(uint8_t *channel_matrix,
for(int gI = 0; gI < num_gnb_antenna_elements; gI++) {
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[uI][0];
if(prg_size == 0){
subcarrier = subcarrier_offset;
}
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
for(int pI = 0; pI < num_prgs; pI++) {
for(int pI = 0; pI < num_samples; pI++) {
const c16_t *srs_estimated_channel16 = srs_estimated_channel_freq[gI][uI] + subcarrier;
uint16_t index = uI*num_gnb_antenna_elements*num_prgs + gI*num_prgs + pI;
uint16_t index = uI*num_gnb_antenna_elements*num_samples + gI*num_samples + pI;
if (normalized_iq_representation == 0) {
channel_matrix8[index].r = (int8_t)(srs_estimated_channel16->r>>8);
@@ -1065,6 +1072,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
nr_srs_channel_iq_matrix.num_ue_srs_ports = srs_pdu->srs_parameters_v4.num_total_ue_antennas;
nr_srs_channel_iq_matrix.prg_size = srs_pdu->srs_parameters_v4.prg_size;
nr_srs_channel_iq_matrix.num_prgs = srs_pdu->srs_parameters_v4.srs_bandwidth_size / srs_pdu->srs_parameters_v4.prg_size;
uint16_t step = nr_srs_channel_iq_matrix.prg_size*NR_NB_SC_PER_RB;
//uint16_t num_samples = nr_srs_channel_iq_matrix.num_prgs;
#ifdef E2_AGENT
nr_srs_channel_iq_matrix.prg_size = 0;
step = 1;
//num_samples = &gNB->frame_parms.ofdm_symbol_size;// NR_NB_SC_PER_RB * num_samples;
nr_srs_channel_iq_matrix.num_prgs = gNB->frame_parms.ofdm_symbol_size;
#endif
fill_srs_channel_matrix(nr_srs_channel_iq_matrix.channel_matrix,
srs_pdu,
gNB->nr_srs_info[i],
@@ -1074,8 +1090,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
nr_srs_channel_iq_matrix.prg_size,
nr_srs_channel_iq_matrix.num_prgs,
&gNB->frame_parms,
srs_estimated_channel_freq);
srs_estimated_channel_freq, step);
#ifdef SRS_IND_DEBUG
LOG_I(NR_PHY, "nr_srs_channel_iq_matrix.normalized_iq_representation = %i\n", nr_srs_channel_iq_matrix.normalized_iq_representation);
LOG_I(NR_PHY, "nr_srs_channel_iq_matrix.num_gnb_antenna_elements = %i\n", nr_srs_channel_iq_matrix.num_gnb_antenna_elements);

View File

@@ -79,6 +79,11 @@ set(SM_ENCODING_GTP "PLAIN" CACHE STRING "The GTP SM encoding to use")
set_property(CACHE SM_ENCODING_GTP PROPERTY STRINGS "PLAIN")
message(STATUS "Selected GTP SM_ENCODING: ${SM_ENCODING_GTP}")
# SRS Service Model
set(SM_ENCODING_SRS "PLAIN" CACHE STRING "The SRS SM encoding to use")
set_property(CACHE SM_ENCODING_SRS PROPERTY STRINGS "PLAIN")
message(STATUS "Selected SRS SM_ENCODING: ${SM_ENCODING_SRS}")
if(E2AP_VERSION STREQUAL "E2AP_V1")
add_library(e2ap_ran_func_obj OBJECT

View File

@@ -51,9 +51,12 @@ add_library(e2_ran_func_cuup STATIC
CUSTOMIZED/ran_func_pdcp.c
CUSTOMIZED/ran_func_tc.c # currently, not implemented; therefore, filling rnd data
../flexric/test/rnd/fill_rnd_data_tc.c
CUSTOMIZED/ran_func_srs.c # just a first step
CUSTOMIZED/ran_func_srs_subs.c
../flexric/src/sm/srs_sm/ie/srs_data_ie.c
)
target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds alg sm_common_enc_asn_obj_rc 3gpp_derived_ie_enc_asn_obj_rc)
target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds alg sm_common_enc_asn_obj_rc 3gpp_derived_ie_enc_asn_obj_rc nfapi_common nr_fapi_p7)
target_compile_definitions(e2_ran_func_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_CUUP)
@@ -75,9 +78,12 @@ add_library(e2_ran_func_du_cucp_cuup STATIC
../flexric/test/rnd/fill_rnd_data_slice.c
CUSTOMIZED/ran_func_tc.c # currently, not implemented; therefore, filling rnd data
../flexric/test/rnd/fill_rnd_data_tc.c
CUSTOMIZED/ran_func_srs.c # just a first step
CUSTOMIZED/ran_func_srs_subs.c
../flexric/src/sm/srs_sm/ie/srs_data_ie.c
)
target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds sm_common_enc_asn_obj_rc 3gpp_derived_ie_enc_asn_obj_rc)
target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds sm_common_enc_asn_obj_rc 3gpp_derived_ie_enc_asn_obj_rc nfapi_common nr_fapi_p7)
target_compile_definitions(e2_ran_func_du_cucp_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_DU NGRAN_GNB_CUCP NGRAN_GNB_CUUP)
# Current implementation:

View File

@@ -0,0 +1,177 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "ran_func_srs.h"
#include "ran_func_srs_extern.h"
#include "ran_func_srs_subs.h"
#include <stdio.h>
#include <assert.h>
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
#include "../../flexric/src/agent/e2_agent_api.h"
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
// for the packing functions
#include "nfapi/open-nFAPI/common/public_inc/nfapi.h"
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h"
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi.h"
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi_p7_utils.h"
#include "openair2/F1AP/f1ap_ids.h"
static seq_arr_t srs_subs_data = {0};
bool read_srs_sm(void* data)
{
assert(data != NULL);
assert(0!=0 && "Not implemented");
return true;
}
void read_srs_setup_sm(void* data)
{
assert(data != NULL);
assert(0!=0 && "Not implemented");
}
sm_ag_if_ans_t write_ctrl_srs_sm(void const* src)
{
assert(src != NULL);
assert(0 !=0 && "Not supported");
}
static srs_ind_hdr_t fill_srs_ind_hdr(void)
{
srs_ind_hdr_t hdr = {0};
hdr.ev_trigger_cond_id = 2;
return hdr;
}
static srs_ind_msg_t fill_srs_ind_msg(nfapi_nr_srs_indication_t *nfapi_srs_ind)
{
srs_ind_msg_t msg = {0};
msg.len = 1; // only for now
msg.tstamp = time_now_us();
if(msg.len > 0 ){
msg.indication_stats = calloc(msg.len, sizeof(srs_indication_stats_impl_t));
assert(msg.indication_stats != NULL && "Memory exhausted");
}
for(uint32_t i = 0; i < msg.len; ++i){
srs_indication_stats_impl_t* indication_stats = &msg.indication_stats[i];
f1_ue_data_t ue_data = du_get_f1_ue_data(nfapi_srs_ind->pdu_list[0].rnti); // Unique CU-UE ID
indication_stats->ue_id= ue_data.secondary_ue;
printf("CU-UE ID: %u\n", indication_stats->ue_id);
size_t ba_len = get_srs_indication_size(nfapi_srs_ind);
byte_array_t ba = {.len = ba_len};
ba.buf = malloc(ba.len);
uint8_t *pPackedBuf = ba.buf;
uint8_t *pWritePackedMessage = pPackedBuf;
uint8_t *pPackMessageEnd = pPackedBuf + ba.len;
printf("[RIC DEBUG INFO] pointer = %p\n",(void*)nfapi_srs_ind);
printf("[RIC DEBUG INFO] ba initialized len: %zu bytes\n", ba.len);
printf("[RIC DEBUG INFO] Sending SFN: %u\n", nfapi_srs_ind->sfn);
printf("[RIC DEBUG INFO] Sending Slot: %u\n", nfapi_srs_ind->slot);
printf("[RIC DEBUG INFO] Sending num srs: %d\n", nfapi_srs_ind->number_of_pdus);
const uint8_t result = pack_nr_srs_indication(nfapi_srs_ind, &pWritePackedMessage, pPackMessageEnd, 0);
assert(result != 0 && "Error in packing SRS Indication message");
size_t packedBufLen = pWritePackedMessage - pPackedBuf;// this should be eq to the ba.len
ba.len = packedBufLen;
printf("[RIC DEBUG INFO] ba updated len: %zu bytes\n", ba.len);
indication_stats->srs_indication_ba = copy_byte_array(ba);
// Clean up
free_byte_array(ba);
}
return msg;
}
static void send_ric_indication(const uint32_t ric_req_id, srs_ind_data_t* srs_ind_data)
{
async_event_agent_api(ric_req_id, srs_ind_data);
printf("Event for RIC Req ID %u generated\n", ric_req_id);
}
static void free_aperiodic_subscription(uint32_t ric_req_id)
{
remove_srs_subs_data(&srs_subs_data, ric_req_id);
}
static srs_ind_data_t* fill_fapi_srs_indication(nfapi_nr_srs_indication_t *nfapi_srs_ind)
{
srs_ind_data_t* srs_ind = calloc(1,sizeof(srs_ind_data_t));
assert(srs_ind != NULL && "Memory exhausted");
srs_ind->hdr = fill_srs_ind_hdr();
srs_ind->msg = fill_srs_ind_msg(nfapi_srs_ind);
return srs_ind;
}
void signal_nfapi_srs_indication(nfapi_nr_srs_indication_t *nfapi_srs_ind)
{
// Check number of subscriptions:
const size_t num_subs = seq_arr_size(&srs_subs_data);
for (size_t sub_idx = 0; sub_idx < num_subs; sub_idx++) {
const ran_param_data_t data = *(const ran_param_data_t *)seq_arr_at(&srs_subs_data, sub_idx);
srs_ind_data_t* srs_ind_data = fill_fapi_srs_indication(nfapi_srs_ind);
//Send RIC indication
send_ric_indication(data.ric_req_id, srs_ind_data);
}
}
sm_ag_if_ans_t write_subs_srs_sm(void const* src)
{
assert(src != NULL);
wr_srs_sub_data_t* wr_srs = (wr_srs_sub_data_t*)src;
assert(wr_srs->srs.ad != NULL && "Cannot be NULL");
sm_ag_if_ans_t ans = {0};
const uint32_t ric_req_id = wr_srs->ric_req_id;
struct ran_param_data data = { .ric_req_id = ric_req_id};
init_srs_subs_data(&srs_subs_data);
insert_srs_subs_data(&srs_subs_data,&data);
ans.type = SUBS_OUTCOME_SM_AG_IF_ANS_V0;
ans.subs_out.type = APERIODIC_SUBSCRIPTION_FLRC;
ans.subs_out.aper.free_aper_subs = free_aperiodic_subscription;
return ans;
}

View File

@@ -0,0 +1,35 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef RAN_FUNC_SM_SRS_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_SRS_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/../sm/sm_io.h"
bool read_srs_sm(void* data);
void read_srs_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_srs_sm(void const* data);
sm_ag_if_ans_t write_subs_srs_sm(void const* src);
#endif

View File

@@ -0,0 +1,35 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef RAN_FUNC_SM_SRS_EXTERN_AGENT_H
#define RAN_FUNC_SM_SRS_EXTERN_AGENT_H
// #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#include "openair2/E2AP/flexric/src/util/byte_array.h"
// uint8_t pack_nr_srs_report_tlv(const nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
// uint8_t pack_nr_srs_indication_body(const nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end);
// void signal_nfapi_srs_indication(NR_UL_IND_t *UL_info, nfapi_nr_srs_indication_pdu_t *nfapi_srs_ind);
void signal_nfapi_srs_indication(nfapi_nr_srs_indication_t *nfapi_srs_ind);
#endif

View File

@@ -0,0 +1,56 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "ran_func_srs_subs.h"
#include "common/utils/assertions.h"
#include "common/utils/alg/find.h"
#include <assert.h>
#include <pthread.h>
// static pthread_mutex_t srs_mutex = PTHREAD_MUTEX_INITIALIZER;
static bool eq_int(const void* value, const void* it)
{
const uint32_t ric_req_id = *(uint32_t *)value;
const ran_param_data_t *dit = (const ran_param_data_t *)it;
return ric_req_id == dit->ric_req_id;
}
void init_srs_subs_data(seq_arr_t *srs_subs_data)
{
seq_arr_init(srs_subs_data, sizeof(ran_param_data_t));
}
void insert_srs_subs_data(seq_arr_t *seq_arr, ran_param_data_t *data)
{
// Insert RIC Req ID
seq_arr_push_back(seq_arr, data, sizeof(*data));
}
void remove_srs_subs_data(seq_arr_t *srs_subs_data, uint32_t ric_req_id){
elm_arr_t elm = find_if(srs_subs_data, (void *)&ric_req_id, eq_int);
ran_param_data_t *data = elm.it;
if (data != NULL) {
// free_srs_event_trigger...
seq_arr_erase(srs_subs_data, elm.it);
}
}

View File

@@ -0,0 +1,40 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef RAN_FUNC_SM_SRS_SUBSCRIPTION_AGENT_H
#define RAN_FUNC_SM_SRS_SUBSCRIPTION_AGENT_H
#include "openair2/E2AP/flexric/src/sm/srs_sm/ie/srs_data_ie.h"
#include "common/utils/ds/seq_arr.h"
typedef struct ran_param_data {
uint32_t ric_req_id;
//srs_event_trigger_t ev_tr;
} ran_param_data_t;
// seq_arr_t srs_subs_data;
void init_srs_subs_data(seq_arr_t *srs_subs_data);
void insert_srs_subs_data(seq_arr_t *seq_arr, ran_param_data_t *data);
void remove_srs_subs_data(seq_arr_t *srs_subs_data, uint32_t ric_req_id);
#endif

View File

@@ -36,6 +36,7 @@
#include "O-RAN/ran_func_kpm.h"
#include "O-RAN/ran_func_rc.h"
#include "CUSTOMIZED/ran_func_srs.h"
static
void init_read_ind_tbl(read_ind_fp (*read_ind_tbl)[SM_AGENT_IF_READ_V0_END])
@@ -53,6 +54,7 @@ void init_read_ind_tbl(read_ind_fp (*read_ind_tbl)[SM_AGENT_IF_READ_V0_END])
(*read_ind_tbl)[KPM_STATS_V3_0] = read_kpm_sm ;
(*read_ind_tbl)[RAN_CTRL_STATS_V1_03] = read_rc_sm;
(*read_ind_tbl)[SRS_STATS_V0] = read_srs_sm;
}
static
@@ -71,6 +73,7 @@ void init_read_setup_tbl(read_e2_setup_fp (*read_setup_tbl)[SM_AGENT_IF_E2_SETUP
(*read_setup_tbl)[KPM_V3_0_AGENT_IF_E2_SETUP_ANS_V0] = read_kpm_setup_sm ;
(*read_setup_tbl)[RAN_CTRL_V1_3_AGENT_IF_E2_SETUP_ANS_V0] = read_rc_setup_sm;
(*read_setup_tbl)[SRS_AGENT_IF_E2_SETUP_ANS_V0] = read_srs_setup_sm ;
}
static
@@ -88,6 +91,7 @@ void init_write_ctrl( write_ctrl_fp (*write_ctrl_tbl)[SM_AGENT_IF_WRITE_CTRL_V0_
#endif
(*write_ctrl_tbl)[RAN_CONTROL_CTRL_V1_03] = write_ctrl_rc_sm;
(*write_ctrl_tbl)[SRS_CTRL_REQ_V0] = write_ctrl_srs_sm;
}
static
@@ -106,6 +110,7 @@ void init_write_subs(write_subs_fp (*write_subs_tbl)[SM_AGENT_IF_WRITE_SUBS_V0_E
(*write_subs_tbl)[KPM_SUBS_V3_0] = NULL;
(*write_subs_tbl)[RAN_CTRL_SUBS_V1_03] = write_subs_rc_sm;
(*write_subs_tbl)[SRS_SUBS_V0] = write_subs_srs_sm;
}
sm_io_ag_ran_t init_ran_func_ag(void)

View File

@@ -38,6 +38,32 @@
//#define SRS_IND_DEBUG
static void dump_srs_channel_iq_matrix(nfapi_nr_srs_normalized_channel_iq_matrix_t* channel_iq_matrix, const char* filename) {
FILE* f = fopen(filename, "wb");
if (!f) {
perror("Failed to open file");
return;
}
uint16_t Ng = channel_iq_matrix->num_gnb_antenna_elements;
uint16_t Nu = channel_iq_matrix->num_ue_srs_ports;
// uint16_t prg_size = channel_iq_matrix->prg_size;
uint16_t num_prgs = channel_iq_matrix->num_prgs;
// Could be a csv file header
//fprintf(f, "Num gNB antennas, Num UE SRS Ports, PRG size, Num of PRG");
printf("Ng = %u\t ,Nu = %u\t, Np = %u\n", Ng, Nu, num_prgs);
uint32_t total = Nu * Ng * num_prgs;
const c16_t *channel = (const c16_t*)channel_iq_matrix->channel_matrix;
fwrite(channel, sizeof(c16_t), total, f);
fclose(f);
return;
}
int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot)
{
/* we assume that this function is mutex-protected from outside */
@@ -1518,6 +1544,10 @@ void handle_nr_srs_measurements(const module_id_t module_id,
report_tlv->length,
&nr_srs_channel_iq_matrix,
sizeof(nfapi_nr_srs_normalized_channel_iq_matrix_t));
#ifdef E2_AGENT
dump_srs_channel_iq_matrix(&nr_srs_channel_iq_matrix, "mac_channel_rfsim.iq");
break;
#endif
#ifdef SRS_IND_DEBUG
LOG_I(NR_MAC, "nr_srs_channel_iq_matrix.normalized_iq_representation = %i\n", nr_srs_channel_iq_matrix.normalized_iq_representation);

View File

@@ -46,6 +46,10 @@
#include "utils.h"
#include "nfapi/oai_integration/nfapi_pnf.h"
#ifdef E2_AGENT
#include "openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_srs_extern.h"
#endif
#define MAX_IF_MODULES 100
static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES];
@@ -210,6 +214,22 @@ static void handle_nr_ulsch(NR_UL_IND_t *UL_info)
}
}
// static void dump_srs_report(const nfapi_srs_report_tlv_t* report_tlv, const char* filename) {
// FILE* f = fopen(filename, "w");
// if (!f) {
// perror("Failed to open file");
// return;
// }
// for (size_t i = 0; i < 16384; ++i) {
// fprintf(f, "%zu,%u\n", i, report_tlv->value[i]);
// }
// fclose(f);
// return;
// }
static void handle_nr_srs(NR_UL_IND_t *UL_info)
{
if(NFAPI_MODE == NFAPI_MODE_PNF) {
@@ -229,14 +249,20 @@ static void handle_nr_srs(NR_UL_IND_t *UL_info)
nfapi_nr_srs_indication_pdu_t *srs_list = UL_info->srs_ind.pdu_list;
// from here
for (int i = 0; i < num_srs; i++) {
nfapi_nr_srs_indication_pdu_t *srs_ind = &srs_list[i];
LOG_D(NR_PHY, "(%d.%d) UL_info->srs_ind.pdu_list[%d].rnti: 0x%04x\n", frame, slot, i, srs_ind->rnti);
LOG_I(NR_PHY, "(%d.%d) UL_info->srs_ind.pdu_list[%d].rnti: 0x%04x\n", frame, slot, i, srs_ind->rnti);
handle_nr_srs_measurements(module_id,
frame,
slot,
srs_ind);
#ifdef E2_AGENT
printf("[RIC DEBUG INFO] Sent pointer = %p\n",(void*)&UL_info->srs_ind);
signal_nfapi_srs_indication(&UL_info->srs_ind);
#endif
// if (num_srs>0 && i==0){
// dump_srs_report(&srs_ind->report_tlv, "tlv_value_agent.csv");
// }
}
UL_info->srs_ind.number_of_pdus = 0;