Merge remote-tracking branch 'origin/OAI_develop' into oai_develop_nfapi
This commit is contained in:
+20
-5
@@ -543,11 +543,11 @@ class SSHConnection():
|
||||
sys.exit('Insufficient Parameter')
|
||||
ci_full_config_file = config_path + '/ci-' + config_file
|
||||
rruCheck = False
|
||||
result = re.search('rru|du', str(config_file))
|
||||
result = re.search('rru|du.band', str(config_file))
|
||||
if result is not None:
|
||||
rruCheck = True
|
||||
# do not reset board twice in IF4.5 case
|
||||
result = re.search('rru|enb|du', str(config_file))
|
||||
result = re.search('rru|enb|du.band', str(config_file))
|
||||
if result is not None:
|
||||
self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 10)
|
||||
result = re.search('type: b200', str(self.ssh.before))
|
||||
@@ -571,11 +571,12 @@ class SSHConnection():
|
||||
self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
|
||||
self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
|
||||
self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
|
||||
if not rruCheck:
|
||||
result = re.search('rcc|enb|cu.band', str(config_file))
|
||||
if result is not None:
|
||||
self.eNBLogFile = 'enb_' + self.testCase_id + '.log'
|
||||
if extra_options != '':
|
||||
self.eNBOptions = extra_options
|
||||
result = re.search('rru|du', str(config_file))
|
||||
result = re.search('rru|du.band', str(config_file))
|
||||
if result is not None:
|
||||
self.rruLogFile = 'enb_' + self.testCase_id + '.log'
|
||||
time.sleep(6)
|
||||
@@ -2527,6 +2528,7 @@ class SSHConnection():
|
||||
pdcpFailure = 0
|
||||
ulschFailure = 0
|
||||
cdrxActivationMessageCount = 0
|
||||
dropNotEnoughRBs = 0
|
||||
self.htmleNBFailureMsg = ''
|
||||
for line in enb_log_file.readlines():
|
||||
if self.rruOptions != '':
|
||||
@@ -2546,6 +2548,9 @@ class SSHConnection():
|
||||
if result is not None and not exitSignalReceived:
|
||||
foundSegFault = True
|
||||
result = re.search('[Cc]ore [dD]ump', str(line))
|
||||
if result is not None and not exitSignalReceived:
|
||||
foundSegFault = True
|
||||
result = re.search('./lte_build_oai/build/lte-softmodem', str(line))
|
||||
if result is not None and not exitSignalReceived:
|
||||
foundSegFault = True
|
||||
result = re.search('[Aa]ssertion', str(line))
|
||||
@@ -2596,6 +2601,9 @@ class SSHConnection():
|
||||
result = re.search('Canceled RA procedure for UE rnti', str(line))
|
||||
if result is not None:
|
||||
rachCanceledProcedure += 1
|
||||
result = re.search('dropping, not enough RBs', str(line))
|
||||
if result is not None:
|
||||
dropNotEnoughRBs += 1
|
||||
enb_log_file.close()
|
||||
logging.debug(' File analysis completed')
|
||||
if uciStatMsgCount > 0:
|
||||
@@ -2610,6 +2618,10 @@ class SSHConnection():
|
||||
statMsg = 'eNB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)'
|
||||
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
|
||||
self.htmleNBFailureMsg += statMsg + '\n'
|
||||
if dropNotEnoughRBs > 0:
|
||||
statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)'
|
||||
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
|
||||
self.htmleNBFailureMsg += statMsg + '\n'
|
||||
if rrcSetupComplete > 0:
|
||||
rrcMsg = 'eNB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)'
|
||||
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
|
||||
@@ -2688,6 +2700,9 @@ class SSHConnection():
|
||||
if result is not None and not exitSignalReceived:
|
||||
foundSegFault = True
|
||||
result = re.search('[Cc]ore [dD]ump', str(line))
|
||||
if result is not None and not exitSignalReceived:
|
||||
foundSegFault = True
|
||||
result = re.search('./lte-uesoftmodem', str(line))
|
||||
if result is not None and not exitSignalReceived:
|
||||
foundSegFault = True
|
||||
result = re.search('[Aa]ssertion', str(line))
|
||||
@@ -2890,7 +2905,7 @@ class SSHConnection():
|
||||
self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!'
|
||||
self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
|
||||
return
|
||||
logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m')
|
||||
logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m ' + fileToAnalyze)
|
||||
logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze)
|
||||
if (logStatus < 0):
|
||||
self.CreateHtmlTestRow('N/A', 'KO', logStatus)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201
|
||||
030102 000010 040301 040502 000011 040302 000001 000012 040303 000002 000013 040503 040401 040201 030201
|
||||
050102
|
||||
030102 000020 040301 040504 000021 040302 000001 000022 040303 000002 040504 000023 040401 040201 030201
|
||||
030103 000020 040301 040504 000021 040302 000001 000022 040303 000002 040504 000023 040401 040201 030201
|
||||
050202
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
@@ -113,13 +113,13 @@
|
||||
|
||||
<testCase id="030102">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize eNB (FDD/Band7/5MHz)</desc>
|
||||
<desc>Initialize eNB (FDD/Band7/5MHz) for RRC Inactivity Timer testing -- no FlexRan Ctl</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf</Initialize_eNB_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030103">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize eNB (FDD/Band7/5MHz)</desc>
|
||||
<desc>Initialize eNB (FDD/Band7/5MHz) for RRC Inactivity Timer testing -- with FlexRan Ctl</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf</Initialize_eNB_args>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ set(CMAKE_C_FLAGS
|
||||
"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D${MKVER}"
|
||||
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D${MKVER}"
|
||||
)
|
||||
|
||||
|
||||
@@ -604,8 +604,6 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE
|
||||
add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} )
|
||||
set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||
|
||||
add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c)
|
||||
|
||||
##########################################################
|
||||
|
||||
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
|
||||
@@ -887,6 +885,7 @@ add_library(FLEXRAN_AGENT
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_internal.c
|
||||
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c
|
||||
${OPENAIR2_DIR}/ENB_APP/flexran_agent.c
|
||||
${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c
|
||||
@@ -1986,6 +1985,11 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_
|
||||
target_link_libraries(enbscope ${XFORMS_LIBRARIES})
|
||||
target_link_libraries(uescope ${XFORMS_LIBRARIES})
|
||||
|
||||
add_library(rfsimulator MODULE
|
||||
${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
|
||||
)
|
||||
target_link_libraries(rfsimulator SIMU ${ATLAS_LIBRARIES})
|
||||
|
||||
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
|
||||
|
||||
#include T directory even if the T is off because T macros are in the code
|
||||
@@ -2029,6 +2033,25 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
|
||||
#################################
|
||||
# add executables for operation
|
||||
#################################
|
||||
add_library(minimal_lib
|
||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||
${OPENAIR_DIR}/common/utils/LOG/log.c
|
||||
${OPENAIR_DIR}/common/config/config_userapi.c
|
||||
${OPENAIR_DIR}/common/config/config_load_configmodule.c
|
||||
${OPENAIR_DIR}/common/config/config_cmdline.c
|
||||
${OPENAIR_DIR}/common/utils/minimal_stub.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(minimal_lib pthread dl ${T_LIB})
|
||||
|
||||
add_executable(replay_node
|
||||
${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c
|
||||
)
|
||||
target_link_libraries (replay_node minimal_lib)
|
||||
|
||||
add_executable(measurement_display
|
||||
${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c)
|
||||
target_link_libraries (measurement_display minimal_lib)
|
||||
|
||||
# lte-softmodem is both eNB and UE implementation
|
||||
###################################################
|
||||
|
||||
@@ -450,7 +450,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
|
||||
config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double));
|
||||
|
||||
if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) {
|
||||
*(cfgoptions->u64ptr)=cfgoptions->defdblval;
|
||||
*(cfgoptions->dblptr)=cfgoptions->defdblval;
|
||||
status=1;
|
||||
printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
int T_stdout;
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef __SIMPLE_EXE_H__
|
||||
#define __SIMPLE_EXE_H__
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <common/utils/assertions.h>
|
||||
#include <common/utils/LOG/log.h>
|
||||
#include "common_lib.h"
|
||||
|
||||
#ifdef T
|
||||
#undef T
|
||||
#define T(...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -33,7 +33,9 @@
|
||||
#define __PHY_DEFS_ENB__H__
|
||||
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -415,7 +415,7 @@ typedef struct {
|
||||
/// nprach_CP_Length_r13, for the CP length(unit us) only 66.7 and 266.7 is implemented
|
||||
uint16_t nprach_CP_Length;
|
||||
/// The criterion for UEs to select a NPRACH resource. Up to 2 RSRP threshold values can be signalled. \vr{[1..2]}
|
||||
struct rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList;
|
||||
rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList;
|
||||
/// NPRACH Parameters List
|
||||
NPRACH_List_NB_IoT_t nprach_ParametersList;
|
||||
|
||||
|
||||
@@ -282,8 +282,16 @@ typedef struct {
|
||||
#define cmax(a,b) ((a>b) ? (a) : (b))
|
||||
#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c))
|
||||
#define cmin(a,b) ((a<b) ? (a) : (b))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef min
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
#else
|
||||
#define max(a,b) cmax(a,b)
|
||||
#define min(a,b) cmin(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef malloc16
|
||||
# ifdef __AVX2__
|
||||
|
||||
@@ -39,6 +39,8 @@ MESSAGE_DEF(X2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, x2ap_reg
|
||||
MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_deregistered_enb_ind_t , x2ap_deregistered_enb_ind)
|
||||
|
||||
/* handover messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_SETUP_REQ , MESSAGE_PRIORITY_MED, x2ap_setup_req_t , x2ap_setup_req)
|
||||
MESSAGE_DEF(X2AP_SETUP_RESP , MESSAGE_PRIORITY_MED, x2ap_setup_resp_t , x2ap_setup_resp)
|
||||
MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req)
|
||||
MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack)
|
||||
MESSAGE_DEF(X2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, x2ap_handover_cancel_t , x2ap_handover_cancel)
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
// Defines to access message fields.
|
||||
|
||||
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
|
||||
#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req
|
||||
#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp
|
||||
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
|
||||
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
|
||||
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
|
||||
@@ -41,6 +43,16 @@
|
||||
|
||||
// eNB application layer -> X2AP messages
|
||||
|
||||
typedef struct x2ap_setup_req_s {
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
} x2ap_setup_req_t;
|
||||
|
||||
typedef struct x2ap_setup_resp_s {
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
} x2ap_setup_resp_t;
|
||||
|
||||
/* X2AP UE CONTEXT RELEASE */
|
||||
typedef struct x2ap_ue_context_release_s {
|
||||
/* used for X2AP->RRC in source and RRC->X2AP in target */
|
||||
|
||||
@@ -826,7 +826,6 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
}
|
||||
}
|
||||
free(ue_report);
|
||||
ue_report = NULL;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file flexran_agent_mac.c
|
||||
/*! \file flexran_agent_rrc.c
|
||||
* \brief FlexRAN agent Control Module RRC
|
||||
* \author shahab SHARIAT BAGHERI
|
||||
* \date 2017
|
||||
@@ -130,6 +130,18 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) {
|
||||
free(msg->ue_state_change_msg->header);
|
||||
if (msg->ue_state_change_msg->config->capabilities)
|
||||
free(msg->ue_state_change_msg->config->capabilities);
|
||||
if (msg->ue_state_change_msg->config->info) {
|
||||
if (msg->ue_state_change_msg->config->info->cell_individual_offset) {
|
||||
free(msg->ue_state_change_msg->config->info->cell_individual_offset);
|
||||
}
|
||||
if (msg->ue_state_change_msg->config->info->event) {
|
||||
if (msg->ue_state_change_msg->config->info->event->a3) {
|
||||
free(msg->ue_state_change_msg->config->info->event->a3);
|
||||
}
|
||||
free(msg->ue_state_change_msg->config->info->event);
|
||||
}
|
||||
free(msg->ue_state_change_msg->config->info);
|
||||
}
|
||||
free(msg->ue_state_change_msg->config);
|
||||
free(msg->ue_state_change_msg);
|
||||
free(msg);
|
||||
@@ -381,7 +393,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
/* Check flag for creation of buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) {
|
||||
|
||||
/*Source Cell*/
|
||||
/*Source cell EUTRA Measurements*/
|
||||
Protocol__FlexRrcMeasurements *rrc_measurements;
|
||||
rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements));
|
||||
if (rrc_measurements == NULL)
|
||||
@@ -397,7 +409,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, rnti);
|
||||
rrc_measurements->has_pcell_rsrq = 1 ;
|
||||
|
||||
/* Target Cell, Neghibouring*/
|
||||
/* Neighbouring cells EUTRA Measurements*/
|
||||
Protocol__FlexNeighCellsMeasurements *neigh_meas;
|
||||
neigh_meas = malloc(sizeof(Protocol__FlexNeighCellsMeasurements));
|
||||
if (neigh_meas == NULL) {
|
||||
@@ -406,14 +418,12 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
goto error;
|
||||
}
|
||||
protocol__flex_neigh_cells_measurements__init(neigh_meas);
|
||||
|
||||
|
||||
neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, rnti);
|
||||
|
||||
Protocol__FlexEutraMeasurements **eutra_meas = NULL;
|
||||
|
||||
if (neigh_meas->n_eutra_meas > 0){
|
||||
|
||||
if (neigh_meas->n_eutra_meas > 0) {
|
||||
eutra_meas = malloc(sizeof(Protocol__FlexEutraMeasurements) * neigh_meas->n_eutra_meas);
|
||||
if (eutra_meas == NULL) {
|
||||
free(neigh_meas);
|
||||
@@ -422,127 +432,138 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (int j = 0; j < neigh_meas->n_eutra_meas; j++ ){
|
||||
for (int j = 0; j < neigh_meas->n_eutra_meas; j++ ) {
|
||||
eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements));
|
||||
if (eutra_meas[j] == NULL) {
|
||||
for (int k = 0 ; k < j ; k++)
|
||||
free(eutra_meas[k]);
|
||||
free(eutra_meas);
|
||||
free(neigh_meas);
|
||||
free(rrc_measurements);
|
||||
rrc_measurements = NULL;
|
||||
goto error;
|
||||
}
|
||||
protocol__flex_eutra_measurements__init(eutra_meas[j]);
|
||||
|
||||
eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements));
|
||||
if (eutra_meas[j] == NULL) {
|
||||
for (int k = 0 ; k < j ; k++) {
|
||||
free(eutra_meas[k]);
|
||||
}
|
||||
free(eutra_meas);
|
||||
free(neigh_meas);
|
||||
free(rrc_measurements);
|
||||
rrc_measurements = NULL;
|
||||
goto error;
|
||||
}
|
||||
/* Fill in the physical cell identifier. */
|
||||
eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, rnti, j);
|
||||
eutra_meas[j]->has_phys_cell_id = 1;
|
||||
|
||||
protocol__flex_eutra_measurements__init(eutra_meas[j]);
|
||||
/* The following is not correctly implemented */
|
||||
//if (flexran_get_rrc_neigh_cgi(mod_id, rnti, j)) {
|
||||
// /* Initialize CGI measurements. */
|
||||
// Protocol__FlexEutraCgiMeasurements *cgi_meas;
|
||||
// cgi_meas = malloc(sizeof(Protocol__FlexEutraCgiMeasurements));
|
||||
|
||||
eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, rnti, j);
|
||||
eutra_meas[j]->has_phys_cell_id = 1;
|
||||
// if (cgi_meas) {
|
||||
// protocol__flex_eutra_cgi_measurements__init(cgi_meas);
|
||||
|
||||
// cgi_meas->tracking_area_code = flexran_get_rrc_neigh_cgi_tac(mod_id, rnti, j);
|
||||
// cgi_meas->has_tracking_area_code = 1;
|
||||
|
||||
/*TODO: Extend for CGI and PLMNID*/
|
||||
// /* EUTRA Cell Global Identity (CGI) */
|
||||
// Protocol__FlexCellGlobalEutraId *cgi;
|
||||
// cgi = malloc(sizeof(Protocol__FlexCellGlobalEutraId));
|
||||
|
||||
Protocol__FlexEutraRefSignalMeas *meas_result;
|
||||
meas_result = malloc(sizeof(Protocol__FlexEutraRefSignalMeas));
|
||||
// if (cgi) {
|
||||
// protocol__flex_cell_global_eutra_id__init(cgi);
|
||||
|
||||
protocol__flex_eutra_ref_signal_meas__init(meas_result);
|
||||
// cgi->cell_id = flexran_get_rrc_neigh_cgi_cell_id(mod_id, rnti, j);
|
||||
// cgi->has_cell_id = 1;
|
||||
|
||||
meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, rnti, eutra_meas[j]->phys_cell_id);
|
||||
// /* PLMN for neighbouring cell */
|
||||
// Protocol__FlexPlmnIdentity *plmn_id;
|
||||
// plmn_id = malloc(sizeof(Protocol__FlexPlmnIdentity));
|
||||
|
||||
// if (plmn_id) {
|
||||
// protocol__flex_plmn_identity__init(plmn_id);
|
||||
|
||||
// plmn_id->mcc = 0;
|
||||
// plmn_id->n_mcc = flexran_get_rrc_neigh_cgi_num_mcc(mod_id, rnti, j);
|
||||
|
||||
// for (int m = 0; m < plmn_id->n_mcc; m++) {
|
||||
// plmn_id->mcc += flexran_get_rrc_neigh_cgi_mcc(mod_id, rnti, j, m);
|
||||
// }
|
||||
|
||||
// plmn_id->mnc = 0;
|
||||
// plmn_id->n_mnc = flexran_get_rrc_neigh_cgi_num_mnc(mod_id, rnti, j);
|
||||
|
||||
// for (int m = 0; m < plmn_id->n_mnc; m++) {
|
||||
// plmn_id->mnc += flexran_get_rrc_neigh_cgi_mnc(mod_id, rnti, j, m);
|
||||
// }
|
||||
|
||||
// cgi->plmn_id = plmn_id;
|
||||
// }
|
||||
// cgi_meas->cgi = cgi;
|
||||
// }
|
||||
// eutra_meas[j]->cgi_meas = cgi_meas;
|
||||
// }
|
||||
//}
|
||||
|
||||
/*RSRP/RSRQ of the neighbouring cell */
|
||||
Protocol__FlexEutraRefSignalMeas *meas_result;
|
||||
meas_result = malloc(sizeof(Protocol__FlexEutraRefSignalMeas));
|
||||
|
||||
if (meas_result) {
|
||||
protocol__flex_eutra_ref_signal_meas__init(meas_result);
|
||||
|
||||
meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, rnti, j);
|
||||
meas_result->has_rsrp = 1;
|
||||
|
||||
meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, rnti, eutra_meas[j]->phys_cell_id);
|
||||
meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, rnti, j);
|
||||
meas_result->has_rsrq = 1;
|
||||
|
||||
eutra_meas[j]->meas_result = meas_result;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
neigh_meas->eutra_meas = eutra_meas;
|
||||
neigh_meas->eutra_meas = eutra_meas;
|
||||
|
||||
rrc_measurements->neigh_meas = neigh_meas;
|
||||
|
||||
rrc_measurements->neigh_meas = neigh_meas;
|
||||
} else {
|
||||
free(neigh_meas);
|
||||
}
|
||||
|
||||
ue_report[i]->rrc_measurements = rrc_measurements;
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS;
|
||||
|
||||
ue_report[i]->rrc_measurements = rrc_measurements;
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* To be considered for RRC signaling of cell*/
|
||||
// if (report_config->nr_cc > 0) {
|
||||
|
||||
|
||||
// // Fill in the Cell reports
|
||||
// for (i = 0; i < report_config->nr_cc; i++) {
|
||||
|
||||
|
||||
// /* Check flag for creation of noise and interference report */
|
||||
// if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) {
|
||||
// // TODO: Fill in the actual noise and interference report for this cell
|
||||
// Protocol__FlexNoiseInterferenceReport *ni_report;
|
||||
// ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport));
|
||||
// if(ni_report == NULL)
|
||||
// goto error;
|
||||
// protocol__flex_noise_interference_report__init(ni_report);
|
||||
// // Current frame and subframe number
|
||||
// ni_report->sfn_sf = flexran_get_sfn_sf(enb_id);
|
||||
// ni_report->has_sfn_sf = 1;
|
||||
// //TODO:Received interference power in dbm
|
||||
// ni_report->rip = 0;
|
||||
// ni_report->has_rip = 1;
|
||||
// //TODO:Thermal noise power in dbm
|
||||
// ni_report->tnp = 0;
|
||||
// ni_report->has_tnp = 1;
|
||||
|
||||
// ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0);
|
||||
// ni_report->has_p0_nominal_pucch = 1;
|
||||
// cell_report[i]->noise_inter_report = ni_report;
|
||||
// cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
||||
for (int i = 0; i < report_config->nr_ue; i++){
|
||||
|
||||
if (ue_report[i]->rrc_measurements && ue_report[i]->rrc_measurements->neigh_meas != NULL){
|
||||
for (int j = 0; j < ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++){
|
||||
|
||||
free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
|
||||
}
|
||||
free(ue_report[i]->rrc_measurements->neigh_meas);
|
||||
for (int i = 0; i < report_config->nr_ue; i++) {
|
||||
if (ue_report[i]->rrc_measurements && ue_report[i]->rrc_measurements->neigh_meas != NULL) {
|
||||
for (int j = 0; j < ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++) {
|
||||
free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
|
||||
}
|
||||
free(ue_report[i]->rrc_measurements->neigh_meas);
|
||||
}
|
||||
}
|
||||
|
||||
if (cell_report != NULL)
|
||||
free(cell_report);
|
||||
free(cell_report);
|
||||
if (ue_report != NULL)
|
||||
free(ue_report);
|
||||
|
||||
free(ue_report);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply)
|
||||
{
|
||||
for (int i = 0; i < reply->n_ue_report; i++){
|
||||
if (reply->ue_report[i]->rrc_measurements && reply->ue_report[i]->rrc_measurements->neigh_meas){
|
||||
for (int j = 0; j < reply->ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++){
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result);
|
||||
if (reply->ue_report[i]->rrc_measurements && reply->ue_report[i]->rrc_measurements->neigh_meas) {
|
||||
for (int j = 0; j < reply->ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++) {
|
||||
//if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas) {
|
||||
// if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->cgi) {
|
||||
// if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->plmn_id) {
|
||||
// free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->cgi->plmn_id);
|
||||
// }
|
||||
// free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas->cgi);
|
||||
// }
|
||||
// free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->cgi_meas);
|
||||
//}
|
||||
if (reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result) {
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result);
|
||||
}
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
|
||||
}
|
||||
free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas);
|
||||
@@ -553,6 +574,79 @@ int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id,
|
||||
const report_config_t *report_config,
|
||||
Protocol__FlexUeStatsReport **ue_report,
|
||||
Protocol__FlexCellStatsReport **cell_report) {
|
||||
/* This function fills the GTP part of the statistics. The necessary
|
||||
* information is, for our purposes, completely maintained in the RRC layer.
|
||||
* It would be possible to add a GTP module that handles this, though. */
|
||||
if (report_config->nr_ue > 0) {
|
||||
rnti_t rntis[report_config->nr_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, report_config->nr_ue);
|
||||
for (int i = 0; i < report_config->nr_ue; i++) {
|
||||
const rnti_t rnti = rntis[i];
|
||||
|
||||
/* Check flag for creation of buffer status report */
|
||||
if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_GTP_STATS) {
|
||||
|
||||
/* get number of rabs for this UE */
|
||||
const int num_e_rab = flexran_agent_rrc_gtp_num_e_rab(mod_id, rnti);
|
||||
Protocol__FlexGtpStats **gtp_stats = NULL;
|
||||
if (num_e_rab > 0) {
|
||||
gtp_stats = calloc(num_e_rab, sizeof(Protocol__FlexGtpStats *));
|
||||
if (!gtp_stats) goto error;
|
||||
for (int r = 0; r < num_e_rab; ++r) {
|
||||
gtp_stats[r] = malloc(sizeof(Protocol__FlexGtpStats));
|
||||
if (!gtp_stats[r]) goto error;
|
||||
protocol__flex_gtp_stats__init(gtp_stats[r]);
|
||||
gtp_stats[r]->e_rab_id = flexran_agent_rrc_gtp_get_e_rab_id(mod_id, rnti, r);
|
||||
gtp_stats[r]->has_e_rab_id = 1;
|
||||
gtp_stats[r]->teid_enb = flexran_agent_rrc_gtp_get_teid_enb(mod_id, rnti, r);
|
||||
gtp_stats[r]->has_teid_enb = 1;
|
||||
gtp_stats[r]->addr_enb = NULL;
|
||||
gtp_stats[r]->teid_sgw = flexran_agent_rrc_gtp_get_teid_sgw(mod_id, rnti, r);
|
||||
gtp_stats[r]->has_teid_sgw = 1;
|
||||
gtp_stats[r]->addr_sgw = NULL;
|
||||
}
|
||||
}
|
||||
ue_report[i]->n_gtp_stats = num_e_rab;
|
||||
ue_report[i]->gtp_stats = gtp_stats;
|
||||
ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_GTP_STATS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
for (int i = 0; i < report_config->nr_ue; i++) {
|
||||
if (!ue_report[i]->gtp_stats) continue;
|
||||
for (int r = 0; r < ue_report[i]->n_gtp_stats; ++r) {
|
||||
if (ue_report[i]->gtp_stats[r]) {
|
||||
free(ue_report[i]->gtp_stats[r]);
|
||||
ue_report[i]->gtp_stats[r] = NULL;
|
||||
}
|
||||
}
|
||||
free(ue_report[i]->gtp_stats);
|
||||
ue_report[i]->gtp_stats = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_destroy_stats_reply(Protocol__FlexStatsReply *reply) {
|
||||
for (int i = 0; i < reply->n_ue_report; ++i) {
|
||||
if (!reply->ue_report[i]->n_gtp_stats == 0) continue;
|
||||
|
||||
for (int r = 0; r < reply->ue_report[i]->n_gtp_stats; ++r) {
|
||||
//if (reply->ue_report[i]->gtp_stats[r]->addr_enb)
|
||||
// free(reply->ue_report[i]->gtp_stats[r]->addr_enb);
|
||||
//if (reply->ue_report[i]->gtp_stats[r]->addr_sgw)
|
||||
// free(reply->ue_report[i]->gtp_stats[r]->addr_sgw);
|
||||
free(reply->ue_report[i]->gtp_stats[r]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
|
||||
Protocol__FlexUeConfig *ue_conf)
|
||||
{
|
||||
@@ -651,6 +745,76 @@ void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
|
||||
|
||||
ue_conf->has_extended_bsr_size = 1;
|
||||
ue_conf->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, rnti);
|
||||
|
||||
Protocol__FlexMeasurementInfo *meas_info;
|
||||
meas_info = malloc(sizeof(Protocol__FlexMeasurementInfo));
|
||||
|
||||
if (meas_info) {
|
||||
protocol__flex_measurement_info__init(meas_info);
|
||||
|
||||
meas_info->has_offset_freq_serving = 1;
|
||||
meas_info->offset_freq_serving = flexran_get_rrc_ofp(mod_id, rnti);
|
||||
|
||||
meas_info->has_offset_freq_neighbouring = 1;
|
||||
meas_info->offset_freq_neighbouring = flexran_get_rrc_ofn(mod_id, rnti);
|
||||
|
||||
int num_adj_cells = flexran_get_rrc_num_adj_cells(mod_id);
|
||||
meas_info->n_cell_individual_offset = num_adj_cells + 1;
|
||||
|
||||
int64_t *cell_individual_offset;
|
||||
if (num_adj_cells > 0) {
|
||||
cell_individual_offset = malloc(sizeof(int64_t)*(num_adj_cells+1));
|
||||
if (cell_individual_offset) {
|
||||
cell_individual_offset[0] = flexran_get_rrc_ocp(mod_id, rnti);
|
||||
for (int i=0; i < num_adj_cells; i++) {
|
||||
cell_individual_offset[i+1] = flexran_get_rrc_ocn(mod_id, rnti,i);
|
||||
}
|
||||
meas_info->cell_individual_offset = cell_individual_offset;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cell_individual_offset = malloc(sizeof(int64_t));
|
||||
if (cell_individual_offset) {
|
||||
*cell_individual_offset = flexran_get_rrc_ocp(mod_id, rnti);
|
||||
meas_info->cell_individual_offset = cell_individual_offset;
|
||||
}
|
||||
}
|
||||
|
||||
meas_info->has_filter_coefficient_rsrp = 1;
|
||||
meas_info->filter_coefficient_rsrp = flexran_get_filter_coeff_rsrp(mod_id, rnti);
|
||||
|
||||
meas_info->has_filter_coefficient_rsrq = 1;
|
||||
meas_info->filter_coefficient_rsrq = flexran_get_filter_coeff_rsrq(mod_id, rnti);
|
||||
|
||||
Protocol__FlexMeasurementEvent *event;
|
||||
event = malloc(sizeof(Protocol__FlexMeasurementEvent));
|
||||
|
||||
if (event) {
|
||||
protocol__flex_measurement_event__init(event);
|
||||
Protocol__FlexA3Event *a3_event;
|
||||
a3_event = malloc(sizeof(Protocol__FlexA3Event));
|
||||
if (a3_event) {
|
||||
protocol__flex_a3_event__init(a3_event);
|
||||
a3_event->has_a3_offset = 1;
|
||||
a3_event->a3_offset = flexran_get_rrc_a3_event_a3_offset(mod_id, rnti);
|
||||
|
||||
a3_event->has_report_on_leave = 1;
|
||||
a3_event->report_on_leave = flexran_get_rrc_a3_event_reportOnLeave(mod_id, rnti);
|
||||
|
||||
a3_event->has_hysteresis = 1;
|
||||
a3_event->hysteresis = flexran_get_rrc_a3_event_hysteresis(mod_id, rnti);
|
||||
|
||||
a3_event->has_time_to_trigger = 1;
|
||||
a3_event->time_to_trigger = flexran_get_rrc_a3_event_timeToTrigger(mod_id, rnti);
|
||||
|
||||
a3_event->has_max_report_cells = 1;
|
||||
a3_event->max_report_cells = flexran_get_rrc_a3_event_maxReportCells(mod_id, rnti);
|
||||
event->a3 = a3_event;
|
||||
}
|
||||
meas_info->event = event;
|
||||
}
|
||||
ue_conf->info = meas_info;
|
||||
}
|
||||
}
|
||||
|
||||
int flexran_agent_register_rrc_xface(mid_t mod_id)
|
||||
@@ -742,6 +906,9 @@ void flexran_agent_fill_rrc_cell_config(mid_t mod_id, uint8_t cc_id,
|
||||
} else {
|
||||
conf->n_plmn_id = 0;
|
||||
}
|
||||
|
||||
conf->x2_ho_net_control = flexran_get_x2_ho_net_control(mod_id);
|
||||
conf->has_x2_ho_net_control = 1;
|
||||
}
|
||||
|
||||
int flexran_agent_unregister_rrc_xface(mid_t mod_id)
|
||||
|
||||
@@ -60,6 +60,11 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t *);
|
||||
int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report);
|
||||
int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply);
|
||||
|
||||
/* Statistic reply for GTP statistics which OAI stores also in the RRC layer.
|
||||
* This might be moved to a separate GTP module in the future */
|
||||
int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report);
|
||||
int flexran_agent_rrc_gtp_destroy_stats_reply(Protocol__FlexStatsReply *reply);
|
||||
|
||||
/* Fill the RRC part of a ue_config message */
|
||||
void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
|
||||
Protocol__FlexUeConfig *ue_conf);
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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 "flexran_agent_rrc_internal.h"
|
||||
#include "flexran_agent_ran_api.h"
|
||||
|
||||
int update_rrc_reconfig(mid_t mod_id, rnti_t rnti, Protocol__FlexRrcTriggering *trigg) {
|
||||
|
||||
// Measurement info reconfiguration
|
||||
|
||||
if (trigg->meas_info) {
|
||||
|
||||
/* Set serving cell frequency offset */
|
||||
if (trigg->meas_info->has_offset_freq_serving) {
|
||||
if (flexran_set_rrc_ofp(mod_id, rnti, trigg->meas_info->offset_freq_serving) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Serving cell frequency offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set neighbouring cell frequency offset */
|
||||
if (trigg->meas_info->has_offset_freq_neighbouring) {
|
||||
if (flexran_set_rrc_ofn(mod_id, rnti, trigg->meas_info->offset_freq_neighbouring) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Neighbouring cell frequency offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (trigg->meas_info->n_cell_individual_offset > 0) {
|
||||
/* Set the serving cell offset */
|
||||
if (flexran_set_rrc_ocp(mod_id, rnti, trigg->meas_info->cell_individual_offset[0]) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Serving cell offset\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the neighbouring cell offset */
|
||||
for (int i=0; i<(trigg->meas_info->n_cell_individual_offset-1); i++) {
|
||||
if (flexran_set_rrc_ocn(mod_id, rnti, i, trigg->meas_info->cell_individual_offset[i+1]) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Neighbouring cell offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trigg->meas_info->has_offset_freq_neighbouring) {
|
||||
if (flexran_set_rrc_ofn(mod_id, rnti, trigg->meas_info->offset_freq_neighbouring) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Neighbouring cell frequency offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set rsrp filter coefficient */
|
||||
if (trigg->meas_info->has_filter_coefficient_rsrp) {
|
||||
if (flexran_set_filter_coeff_rsrp(mod_id, rnti, trigg->meas_info->filter_coefficient_rsrp) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set RSRP filter coefficient\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set rsrq filter coefficient */
|
||||
if (trigg->meas_info->has_filter_coefficient_rsrq) {
|
||||
if (flexran_set_filter_coeff_rsrq(mod_id, rnti, trigg->meas_info->filter_coefficient_rsrq) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set RSRQ filter coefficient\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (trigg->meas_info->event) {
|
||||
|
||||
/* Set Periodic event parameters */
|
||||
if (trigg->meas_info->event->periodical) {
|
||||
|
||||
/* Set Periodic event maximum number of reported cells */
|
||||
if (trigg->meas_info->event->periodical->has_max_report_cells) {
|
||||
if (flexran_set_rrc_per_event_maxReportCells(mod_id, rnti, trigg->meas_info->event->periodical->max_report_cells) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set Periodic event max\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event parameters */
|
||||
if (trigg->meas_info->event->a3) {
|
||||
|
||||
/* Set A3 event a3 offset */
|
||||
if (trigg->meas_info->event->a3->has_a3_offset) {
|
||||
if (flexran_set_rrc_a3_event_a3_offset(mod_id, rnti, trigg->meas_info->event->a3->a3_offset) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event offset\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event report on leave */
|
||||
if (trigg->meas_info->event->a3->has_report_on_leave) {
|
||||
if (flexran_set_rrc_a3_event_reportOnLeave(mod_id, rnti, trigg->meas_info->event->a3->report_on_leave) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event report on leave\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event hysteresis */
|
||||
if (trigg->meas_info->event->a3->has_hysteresis) {
|
||||
if (flexran_set_rrc_a3_event_hysteresis(mod_id, rnti, trigg->meas_info->event->a3->hysteresis) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event hysteresis\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event time to trigger */
|
||||
if (trigg->meas_info->event->a3->has_time_to_trigger) {
|
||||
if (flexran_set_rrc_a3_event_timeToTrigger(mod_id, rnti, trigg->meas_info->event->a3->time_to_trigger) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event time to trigger\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set A3 event maximum number of reported cells */
|
||||
if (trigg->meas_info->event->a3->has_max_report_cells) {
|
||||
if (flexran_set_rrc_a3_event_maxReportCells(mod_id, rnti, trigg->meas_info->event->a3->max_report_cells) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Cannot set A3 event max report cells\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 FLEXRAN_AGENT_RRC_INTERNAL_H_
|
||||
#define FLEXRAN_AGENT_RRC_INTERNAL_H_
|
||||
|
||||
#include "flexran_agent_rrc_internal.h"
|
||||
#include "flexran_agent_ran_api.h"
|
||||
|
||||
int update_rrc_reconfig(mid_t mod_id, rnti_t rnti, Protocol__FlexRrcTriggering *trigg);
|
||||
|
||||
#endif /*FLEXRAN_AGENT_RRC_INTERNAL_H_*/
|
||||
|
||||
@@ -268,3 +268,71 @@ message flex_plmn {
|
||||
optional uint32 mnc = 2;
|
||||
optional uint32 mnc_length = 3;
|
||||
}
|
||||
|
||||
//
|
||||
// UE-related RRC configuration
|
||||
|
||||
message flex_measurement_info {
|
||||
// arbitrary offset OFS, from TS
|
||||
optional int64 offset_freq_serving = 1;
|
||||
// arbitrary offset OFN
|
||||
optional int64 offset_freq_neighbouring = 2;
|
||||
// arbitrary offset OCS + OCN
|
||||
repeated int64 cell_individual_offset = 3;
|
||||
// Parameter k for exponential moving average calculation coefficient
|
||||
// a = 1/2^(k/4) of all measured RSRPs
|
||||
optional int64 filter_coefficient_rsrp = 4;
|
||||
// Parameter k for RSRQ filtering
|
||||
optional int64 filter_coefficient_rsrq = 5;
|
||||
optional flex_measurement_event event = 6;
|
||||
}
|
||||
|
||||
message flex_measurement_event {
|
||||
optional flex_per_event periodical = 1;
|
||||
optional flex_a1_event a1 = 2;
|
||||
optional flex_a2_event a2 = 3;
|
||||
optional flex_a3_event a3 = 4;
|
||||
optional flex_a4_event a4 = 5;
|
||||
optional flex_a5_event a5 = 6;
|
||||
}
|
||||
|
||||
message flex_per_event {
|
||||
optional int64 max_report_cells = 1;
|
||||
}
|
||||
|
||||
message flex_a1_event {
|
||||
optional int64 threshold_rsrp = 1;
|
||||
optional int64 hysteresis = 2;
|
||||
optional int64 time_to_trigger = 3;
|
||||
optional int64 max_report_cells = 4;
|
||||
}
|
||||
|
||||
message flex_a2_event {
|
||||
optional int64 threshold_rsrp = 1;
|
||||
optional int64 hysteresis = 2;
|
||||
optional int64 time_to_trigger = 3;
|
||||
optional int64 max_report_cells = 4;
|
||||
}
|
||||
|
||||
message flex_a3_event {
|
||||
optional int64 a3_offset = 1;
|
||||
optional int32 report_on_leave = 2;
|
||||
optional int64 hysteresis = 3;
|
||||
optional int64 time_to_trigger = 4;
|
||||
optional int64 max_report_cells = 5;
|
||||
}
|
||||
|
||||
message flex_a4_event {
|
||||
optional int64 threshold_rsrp = 1;
|
||||
optional int64 hysteresis = 2;
|
||||
optional int64 time_to_trigger = 3;
|
||||
optional int64 max_report_cells = 4;
|
||||
}
|
||||
|
||||
message flex_a5_event {
|
||||
optional int64 threshold_rsrp_1 = 1;
|
||||
optional int64 threshold_rsrp_2 = 2;
|
||||
optional int64 hysteresis = 3;
|
||||
optional int64 time_to_trigger = 4;
|
||||
optional int64 max_report_cells = 5;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ message flex_cell_config {
|
||||
repeated flex_plmn plmn_id = 40; // The PLMN cell id of this cell
|
||||
|
||||
optional flex_slice_config slice_config = 42;
|
||||
optional bool x2_ho_net_control = 43;
|
||||
}
|
||||
|
||||
message flex_slice_config {
|
||||
@@ -97,6 +98,8 @@ message flex_ue_config {
|
||||
optional uint64 imsi = 30;
|
||||
optional uint32 dl_slice_id = 31;
|
||||
optional uint32 ul_slice_id = 32;
|
||||
// Configuration about RRC measurements
|
||||
optional flex_measurement_info info = 33;
|
||||
}
|
||||
|
||||
message flex_lc_ue_config {
|
||||
|
||||
@@ -7,7 +7,7 @@ import "time_common.proto";
|
||||
import "config_messages.proto";
|
||||
import "controller_commands.proto";
|
||||
import "control_delegation.proto";
|
||||
|
||||
import "config_common.proto";
|
||||
|
||||
message flexran_message {
|
||||
optional flexran_direction msg_dir = 100;
|
||||
@@ -32,6 +32,7 @@ message flexran_message {
|
||||
flex_rrc_triggering rrc_triggering = 18;
|
||||
flex_ul_mac_config ul_mac_config_msg = 19;
|
||||
flex_disconnect disconnect_msg = 20;
|
||||
flex_ho_command ho_command_msg = 21;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +189,14 @@ message flex_ul_mac_config {
|
||||
message flex_rrc_triggering {
|
||||
|
||||
optional flex_header header = 1;
|
||||
optional string rrc_trigger = 2;
|
||||
optional string rrc_trigger = 2;
|
||||
optional flex_measurement_info meas_info = 3;
|
||||
}
|
||||
|
||||
message flex_ho_command {
|
||||
optional flex_header header = 1;
|
||||
optional uint32 rnti = 2;
|
||||
optional uint32 target_phy_cell_id = 3;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -34,6 +34,7 @@ enum flex_type {
|
||||
|
||||
//Controller command messages
|
||||
FLPT_DL_MAC_CONFIG = 13;
|
||||
FLPT_HO_COMMAND = 21;
|
||||
|
||||
// UE state change messages
|
||||
FLPT_UE_STATE_CHANGE = 14;
|
||||
|
||||
@@ -305,3 +305,15 @@ message flex_mac_sdus_dl {
|
||||
optional uint32 sdu_length = 1;
|
||||
optional uint32 lcid = 2;
|
||||
}
|
||||
|
||||
//
|
||||
// GTP stats
|
||||
//
|
||||
|
||||
message flex_gtp_stats {
|
||||
optional uint32 e_rab_id = 1;
|
||||
optional uint32 teid_enb = 2;
|
||||
optional string addr_enb = 3;
|
||||
optional uint32 teid_sgw = 4;
|
||||
optional string addr_sgw = 5;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ message flex_ue_stats_report {
|
||||
optional flex_rrc_measurements rrc_measurements = 10;
|
||||
optional flex_pdcp_stats pdcp_stats = 11;
|
||||
optional flex_mac_stats mac_stats = 12;
|
||||
repeated flex_gtp_stats gtp_stats = 13;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -89,6 +90,7 @@ enum flex_ue_stats_type {
|
||||
FLUST_MAC_STATS = 128;
|
||||
|
||||
FLUST_PDCP_STATS = 1024;
|
||||
FLUST_GTP_STATS = 2048;
|
||||
FLUST_RRC_MEASUREMENTS = 65536;
|
||||
// To be extended with more types of stats
|
||||
|
||||
|
||||
@@ -449,98 +449,96 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) {
|
||||
//printf("Component carrier %d\n",component_carrier);
|
||||
nb_cc++;
|
||||
|
||||
if (1 || !NODE_IS_CU(rrc->node_type)) {
|
||||
// Cell params, MIB/SIB1 in DU
|
||||
RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = ccparams_lte.tdd_config;
|
||||
AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6,
|
||||
"Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!",
|
||||
RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6);
|
||||
RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = ccparams_lte.tdd_config_s;
|
||||
AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8,
|
||||
"Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!",
|
||||
RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8);
|
||||
// Cell params, MIB/SIB1 in DU
|
||||
RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = ccparams_lte.tdd_config;
|
||||
AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6,
|
||||
"Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!",
|
||||
RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6);
|
||||
RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = ccparams_lte.tdd_config_s;
|
||||
AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8,
|
||||
"Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!",
|
||||
RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8);
|
||||
|
||||
if (!ccparams_lte.prefix_type)
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n",
|
||||
RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE);
|
||||
else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL;
|
||||
} else if (strcmp(ccparams_lte.prefix_type, "EXTENDED") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
|
||||
RC.config_file_name, i, ccparams_lte.prefix_type);
|
||||
}
|
||||
if (!ccparams_lte.prefix_type)
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n",
|
||||
RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE);
|
||||
else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL;
|
||||
} else if (strcmp(ccparams_lte.prefix_type, "EXTENDED") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
|
||||
RC.config_file_name, i, ccparams_lte.prefix_type);
|
||||
}
|
||||
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
|
||||
if (!ccparams_lte.pbch_repetition)
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n",
|
||||
RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION);
|
||||
else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1;
|
||||
} else if (strcmp(ccparams_lte.pbch_repetition, "FALSE") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n",
|
||||
RC.config_file_name, i, ccparams_lte.pbch_repetition);
|
||||
}
|
||||
if (!ccparams_lte.pbch_repetition)
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n",
|
||||
RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION);
|
||||
else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1;
|
||||
} else if (strcmp(ccparams_lte.pbch_repetition, "FALSE") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n",
|
||||
RC.config_file_name, i, ccparams_lte.pbch_repetition);
|
||||
}
|
||||
|
||||
#endif
|
||||
RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = ccparams_lte.eutra_band;
|
||||
RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) ccparams_lte.downlink_frequency;
|
||||
RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) ccparams_lte.uplink_frequency_offset;
|
||||
RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= ccparams_lte.Nid_cell;
|
||||
RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = ccparams_lte.eutra_band;
|
||||
RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) ccparams_lte.downlink_frequency;
|
||||
RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) ccparams_lte.uplink_frequency_offset;
|
||||
RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= ccparams_lte.Nid_cell;
|
||||
|
||||
if (ccparams_lte.Nid_cell>503) {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
|
||||
RC.config_file_name, i, ccparams_lte.Nid_cell);
|
||||
}
|
||||
|
||||
RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= ccparams_lte.N_RB_DL;
|
||||
|
||||
if ((ccparams_lte.N_RB_DL!=6) &&
|
||||
(ccparams_lte.N_RB_DL!=15) &&
|
||||
(ccparams_lte.N_RB_DL!=25) &&
|
||||
(ccparams_lte.N_RB_DL!=50) &&
|
||||
(ccparams_lte.N_RB_DL!=75) &&
|
||||
(ccparams_lte.N_RB_DL!=100)) {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
|
||||
RC.config_file_name, i, ccparams_lte.N_RB_DL);
|
||||
}
|
||||
|
||||
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD;
|
||||
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
|
||||
RC.config_file_name, i, ccparams_lte.frame_type);
|
||||
}
|
||||
|
||||
if (config_check_band_frequencies(j,
|
||||
RRC_CONFIGURATION_REQ (msg_p).eutra_band[j],
|
||||
RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j],
|
||||
RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j],
|
||||
RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) {
|
||||
AssertFatal(0, "error calling enb_check_band_frequencies\n");
|
||||
}
|
||||
|
||||
if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2))
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n",
|
||||
RC.config_file_name, i, ccparams_lte.nb_antenna_ports);
|
||||
|
||||
RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports;
|
||||
if (ccparams_lte.Nid_cell>503) {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
|
||||
RC.config_file_name, i, ccparams_lte.Nid_cell);
|
||||
}
|
||||
|
||||
RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= ccparams_lte.N_RB_DL;
|
||||
|
||||
if ((ccparams_lte.N_RB_DL!=6) &&
|
||||
(ccparams_lte.N_RB_DL!=15) &&
|
||||
(ccparams_lte.N_RB_DL!=25) &&
|
||||
(ccparams_lte.N_RB_DL!=50) &&
|
||||
(ccparams_lte.N_RB_DL!=75) &&
|
||||
(ccparams_lte.N_RB_DL!=100)) {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
|
||||
RC.config_file_name, i, ccparams_lte.N_RB_DL);
|
||||
}
|
||||
|
||||
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD;
|
||||
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
|
||||
RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
|
||||
RC.config_file_name, i, ccparams_lte.frame_type);
|
||||
}
|
||||
|
||||
if (config_check_band_frequencies(j,
|
||||
RRC_CONFIGURATION_REQ (msg_p).eutra_band[j],
|
||||
RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j],
|
||||
RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j],
|
||||
RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) {
|
||||
AssertFatal(0, "error calling enb_check_band_frequencies\n");
|
||||
}
|
||||
|
||||
if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2))
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n",
|
||||
RC.config_file_name, i, ccparams_lte.nb_antenna_ports);
|
||||
|
||||
RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports;
|
||||
|
||||
if (!NODE_IS_DU(rrc->node_type)) { //this is CU or eNB, SIB2-20 in CU
|
||||
// Radio Resource Configuration (SIB2)
|
||||
RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_root = ccparams_lte.prach_root;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
//#include "PHY/extern.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "flexran_agent_mac_internal.h"
|
||||
#include "flexran_agent_rrc_internal.h"
|
||||
|
||||
//#include "SCHED/defs.h"
|
||||
#include "RRC/LTE/rrc_extern.h"
|
||||
@@ -804,27 +805,91 @@ error:
|
||||
}
|
||||
|
||||
|
||||
int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
protocol_ctxt_t ctxt;
|
||||
int flexran_agent_rrc_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
|
||||
Protocol__FlexRrcTriggering *triggering = input->rrc_triggering;
|
||||
agent_reconf_rrc *reconf_param = malloc(sizeof(agent_reconf_rrc));
|
||||
reconf_param->trigger_policy = triggering->rrc_trigger;
|
||||
reconf_param->report_interval = 0;
|
||||
reconf_param->report_amount = 0;
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[mod_id]->rrc_ue_head)) {
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id);
|
||||
flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0, reconf_param);
|
||||
// Set the proper values using FlexRAN API (protected with mutex ?)
|
||||
if (!flexran_agent_get_rrc_xface(mod_id)) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no RRC present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int num_ue = flexran_get_rrc_num_ues(mod_id);
|
||||
if (num_ue == 0)
|
||||
return 0;
|
||||
|
||||
rnti_t rntis[num_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, num_ue);
|
||||
for (int i = 0; i < num_ue; i++) {
|
||||
const rnti_t rnti = rntis[i];
|
||||
const int error = update_rrc_reconfig(mod_id, rnti, triggering);
|
||||
if (error < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in updating user %d\n", i);
|
||||
continue;
|
||||
}
|
||||
// Call the proper wrapper in FlexRAN API
|
||||
if (flexran_call_rrc_reconfiguration (mod_id, rnti) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in reconfiguring user %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
*msg = NULL;
|
||||
free(reconf_param);
|
||||
reconf_param = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_trigger_handover(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
|
||||
Protocol__FlexHoCommand *ho_command = input->ho_command_msg;
|
||||
|
||||
int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg) {
|
||||
int rnti_found = 0;
|
||||
|
||||
// Set the proper values using FlexRAN API (protected with mutex ?)
|
||||
if (!flexran_agent_get_rrc_xface(mod_id)) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no RRC present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int num_ue = flexran_get_rrc_num_ues(mod_id);
|
||||
if (num_ue == 0)
|
||||
return 0;
|
||||
|
||||
if (!ho_command->has_rnti) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no UE rnti is present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ho_command->has_target_phy_cell_id) {
|
||||
LOG_E(FLEXRAN_AGENT, "%s(): no target physical cell id is present, aborting\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rnti_t rntis[num_ue];
|
||||
flexran_get_rrc_rnti_list(mod_id, rntis, num_ue);
|
||||
for (int i = 0; i < num_ue; i++) {
|
||||
const rnti_t rnti = rntis[i];
|
||||
if (ho_command->rnti == rnti) {
|
||||
rnti_found = 1;
|
||||
// Call the proper wrapper in FlexRAN API
|
||||
if (flexran_call_rrc_trigger_handover(mod_id, ho_command->rnti, ho_command->target_phy_cell_id) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in handovering user %d/RNTI %x\n", i, rnti);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rnti_found)
|
||||
return -1;
|
||||
|
||||
*msg = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_agent_destroy_rrc_reconfiguration(Protocol__FlexranMessage *msg) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_agent_destroy_rrc_trigger_handover(Protocol__FlexranMessage *msg) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
@@ -849,6 +914,12 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot
|
||||
// initiate_soft_restart(mod_id, enb_config->cell_config[0]);
|
||||
}
|
||||
|
||||
if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->has_x2_ho_net_control) {
|
||||
if (flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control) < 0) {
|
||||
LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network");
|
||||
}
|
||||
}
|
||||
|
||||
*msg = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -137,9 +137,12 @@ int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__Fl
|
||||
int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* rrc triggering measurement message constructor and destructor */
|
||||
int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg);
|
||||
int flexran_agent_rrc_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_rrc_reconfiguration(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* rrc triggering handover command message constructor and destructor */
|
||||
int flexran_agent_rrc_trigger_handover(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg);
|
||||
int flexran_agent_destroy_rrc_trigger_handover(Protocol__FlexranMessage *msg);
|
||||
|
||||
/* FlexRAN protocol message dispatcher function */
|
||||
Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id,
|
||||
|
||||
@@ -55,7 +55,10 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = {
|
||||
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG*/
|
||||
{flexran_agent_control_delegation, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_CONTROL_DELEGATION_MSG*/
|
||||
{flexran_agent_reconfiguration, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_AGENT_RECONFIGURATION_MSG*/
|
||||
{flexran_agent_rrc_measurement, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_RRC_TRIGGERING_MSG*/
|
||||
{flexran_agent_rrc_reconfiguration, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_RRC_TRIGGERING_MSG*/
|
||||
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG*/
|
||||
{0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_DISCONNECT_MSG*/
|
||||
{flexran_agent_rrc_trigger_handover, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_HO_COMMAND_MSG*/
|
||||
};
|
||||
|
||||
flexran_agent_message_destruction_callback message_destruction_callback[] = {
|
||||
@@ -508,7 +511,13 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
/* GTP reply split, currently performed through RRC module */
|
||||
if (flexran_agent_get_rrc_xface(enb_id)
|
||||
&& flexran_agent_rrc_gtp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) {
|
||||
err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
|
||||
goto error;
|
||||
}
|
||||
|
||||
stats_reply_msg->cell_report = cell_report;
|
||||
stats_reply_msg->ue_report = ue_report;
|
||||
|
||||
|
||||
@@ -71,19 +71,10 @@ sub_frame_t flexran_get_current_subframe(mid_t mod_id)
|
||||
return RC.mac[mod_id]->subframe;
|
||||
}
|
||||
|
||||
/* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */
|
||||
uint16_t flexran_get_sfn_sf(mid_t mod_id)
|
||||
uint32_t flexran_get_sfn_sf(mid_t mod_id)
|
||||
{
|
||||
if (!mac_is_present(mod_id)) return 0;
|
||||
frame_t frame = flexran_get_current_system_frame_num(mod_id);
|
||||
sub_frame_t subframe = flexran_get_current_subframe(mod_id);
|
||||
uint16_t sfn_sf, frame_mask, sf_mask;
|
||||
|
||||
frame_mask = (1 << 12) - 1;
|
||||
sf_mask = (1 << 4) - 1;
|
||||
sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
|
||||
|
||||
return sfn_sf;
|
||||
return flexran_get_current_frame(mod_id) * 10 + flexran_get_current_subframe(mod_id);
|
||||
}
|
||||
|
||||
uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time)
|
||||
@@ -1434,9 +1425,31 @@ uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid)
|
||||
}
|
||||
|
||||
/******************** RRC *****************************/
|
||||
/* RRC Wrappers */
|
||||
int flexran_call_rrc_reconfiguration (mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
protocol_ctxt_t ctxt;
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id);
|
||||
flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
int flexran_call_rrc_trigger_handover (mid_t mod_id, rnti_t rnti, int target_cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
protocol_ctxt_t ctxt;
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id);
|
||||
return flexran_rrc_eNB_trigger_handover(mod_id, &ctxt, ue_context_p, target_cell_id);
|
||||
}
|
||||
|
||||
/* RRC Getters */
|
||||
|
||||
LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
@@ -1444,97 +1457,687 @@ LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti)
|
||||
return ue_context_p->ue_context.measResults->measId;
|
||||
}
|
||||
|
||||
float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
|
||||
return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
|
||||
#else
|
||||
return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultServCell.rsrpResult];
|
||||
#endif
|
||||
}
|
||||
|
||||
float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
|
||||
return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
|
||||
#else
|
||||
return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultServCell.rsrqResult];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Number of neighbouring cells for specific UE*/
|
||||
int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti)
|
||||
{
|
||||
int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
if (!ue_context_p->ue_context.measResults) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id)
|
||||
{
|
||||
long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId;
|
||||
}
|
||||
|
||||
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id)
|
||||
{
|
||||
int flexran_get_rrc_neigh_cgi(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
if (!ue_context_p->ue_context.measResults) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return 0;
|
||||
return (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info)?0:1;
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
uint8_t *cId = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.cellIdentity.buf;
|
||||
return ((cId[0] << 20) + (cId[1] << 12) + (cId[2] << 4) + (cId[3] >> 4));
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_tac(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
uint8_t *tac = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->trackingAreaCode.buf;
|
||||
return (tac[0] << 8) + (tac[1]);
|
||||
}
|
||||
|
||||
int flexran_get_rrc_neigh_cgi_num_mnc(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count;
|
||||
}
|
||||
|
||||
int flexran_get_rrc_neigh_cgi_num_mcc(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count;
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mnc(mid_t mod_id, rnti_t rnti, long cell_id, int mnc_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
int num_mnc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count;
|
||||
return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.array[mnc_id]) *
|
||||
((uint32_t) pow(10, num_mnc - mnc_id - 1));
|
||||
}
|
||||
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mcc(mid_t mod_id, rnti_t rnti, long cell_id, int mcc_id) {
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
|
||||
int num_mcc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count;
|
||||
return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.array[mcc_id]) *
|
||||
((uint32_t) pow(10, num_mcc - mcc_id - 1));
|
||||
}
|
||||
|
||||
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return 0;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return -1;
|
||||
return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)];
|
||||
}
|
||||
|
||||
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id)
|
||||
{
|
||||
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measResults) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
|
||||
if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0;
|
||||
//if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
|
||||
if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return -1;
|
||||
return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)];
|
||||
}
|
||||
|
||||
uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id)
|
||||
{
|
||||
/* Measurement offsets */
|
||||
|
||||
long flexran_get_rrc_ofp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->offsetFreq;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_ofn(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->offsetFreq;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_ocp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[0]) {
|
||||
case LTE_Q_OffsetRange_dB_24: return -24;
|
||||
case LTE_Q_OffsetRange_dB_22: return -22;
|
||||
case LTE_Q_OffsetRange_dB_20: return -20;
|
||||
case LTE_Q_OffsetRange_dB_18: return -18;
|
||||
case LTE_Q_OffsetRange_dB_16: return -16;
|
||||
case LTE_Q_OffsetRange_dB_14: return -14;
|
||||
case LTE_Q_OffsetRange_dB_12: return -12;
|
||||
case LTE_Q_OffsetRange_dB_10: return -10;
|
||||
case LTE_Q_OffsetRange_dB_8: return -8;
|
||||
case LTE_Q_OffsetRange_dB_6: return -6;
|
||||
case LTE_Q_OffsetRange_dB_5: return -5;
|
||||
case LTE_Q_OffsetRange_dB_4: return -4;
|
||||
case LTE_Q_OffsetRange_dB_3: return -3;
|
||||
case LTE_Q_OffsetRange_dB_2: return -2;
|
||||
case LTE_Q_OffsetRange_dB_1: return -1;
|
||||
case LTE_Q_OffsetRange_dB0: return 0;
|
||||
case LTE_Q_OffsetRange_dB1: return 1;
|
||||
case LTE_Q_OffsetRange_dB2: return 2;
|
||||
case LTE_Q_OffsetRange_dB3: return 3;
|
||||
case LTE_Q_OffsetRange_dB4: return 4;
|
||||
case LTE_Q_OffsetRange_dB5: return 5;
|
||||
case LTE_Q_OffsetRange_dB6: return 6;
|
||||
case LTE_Q_OffsetRange_dB8: return 8;
|
||||
case LTE_Q_OffsetRange_dB10: return 10;
|
||||
case LTE_Q_OffsetRange_dB12: return 12;
|
||||
case LTE_Q_OffsetRange_dB14: return 14;
|
||||
case LTE_Q_OffsetRange_dB16: return 16;
|
||||
case LTE_Q_OffsetRange_dB18: return 18;
|
||||
case LTE_Q_OffsetRange_dB20: return 20;
|
||||
case LTE_Q_OffsetRange_dB22: return 22;
|
||||
case LTE_Q_OffsetRange_dB24: return 24;
|
||||
default: return -99;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1]) {
|
||||
case LTE_Q_OffsetRange_dB_24: return -24;
|
||||
case LTE_Q_OffsetRange_dB_22: return -22;
|
||||
case LTE_Q_OffsetRange_dB_20: return -20;
|
||||
case LTE_Q_OffsetRange_dB_18: return -18;
|
||||
case LTE_Q_OffsetRange_dB_16: return -16;
|
||||
case LTE_Q_OffsetRange_dB_14: return -14;
|
||||
case LTE_Q_OffsetRange_dB_12: return -12;
|
||||
case LTE_Q_OffsetRange_dB_10: return -10;
|
||||
case LTE_Q_OffsetRange_dB_8: return -8;
|
||||
case LTE_Q_OffsetRange_dB_6: return -6;
|
||||
case LTE_Q_OffsetRange_dB_5: return -5;
|
||||
case LTE_Q_OffsetRange_dB_4: return -4;
|
||||
case LTE_Q_OffsetRange_dB_3: return -3;
|
||||
case LTE_Q_OffsetRange_dB_2: return -2;
|
||||
case LTE_Q_OffsetRange_dB_1: return -1;
|
||||
case LTE_Q_OffsetRange_dB0: return 0;
|
||||
case LTE_Q_OffsetRange_dB1: return 1;
|
||||
case LTE_Q_OffsetRange_dB2: return 2;
|
||||
case LTE_Q_OffsetRange_dB3: return 3;
|
||||
case LTE_Q_OffsetRange_dB4: return 4;
|
||||
case LTE_Q_OffsetRange_dB5: return 5;
|
||||
case LTE_Q_OffsetRange_dB6: return 6;
|
||||
case LTE_Q_OffsetRange_dB8: return 8;
|
||||
case LTE_Q_OffsetRange_dB10: return 10;
|
||||
case LTE_Q_OffsetRange_dB12: return 12;
|
||||
case LTE_Q_OffsetRange_dB14: return 14;
|
||||
case LTE_Q_OffsetRange_dB16: return 16;
|
||||
case LTE_Q_OffsetRange_dB18: return 18;
|
||||
case LTE_Q_OffsetRange_dB20: return 20;
|
||||
case LTE_Q_OffsetRange_dB22: return 22;
|
||||
case LTE_Q_OffsetRange_dB24: return 24;
|
||||
default: return -99;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRP) {
|
||||
case LTE_FilterCoefficient_fc0: return 0;
|
||||
case LTE_FilterCoefficient_fc1: return 1;
|
||||
case LTE_FilterCoefficient_fc2: return 2;
|
||||
case LTE_FilterCoefficient_fc3: return 3;
|
||||
case LTE_FilterCoefficient_fc4: return 4;
|
||||
case LTE_FilterCoefficient_fc5: return 5;
|
||||
case LTE_FilterCoefficient_fc6: return 6;
|
||||
case LTE_FilterCoefficient_fc7: return 7;
|
||||
case LTE_FilterCoefficient_fc8: return 8;
|
||||
case LTE_FilterCoefficient_fc9: return 9;
|
||||
case LTE_FilterCoefficient_fc11: return 11;
|
||||
case LTE_FilterCoefficient_fc13: return 13;
|
||||
case LTE_FilterCoefficient_fc15: return 15;
|
||||
case LTE_FilterCoefficient_fc17: return 17;
|
||||
case LTE_FilterCoefficient_fc19: return 19;
|
||||
case LTE_FilterCoefficient_spare1: return -1; /* spare means no coefficient */
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ) {
|
||||
case LTE_FilterCoefficient_fc0: return 0;
|
||||
case LTE_FilterCoefficient_fc1: return 1;
|
||||
case LTE_FilterCoefficient_fc2: return 2;
|
||||
case LTE_FilterCoefficient_fc3: return 3;
|
||||
case LTE_FilterCoefficient_fc4: return 4;
|
||||
case LTE_FilterCoefficient_fc5: return 5;
|
||||
case LTE_FilterCoefficient_fc6: return 6;
|
||||
case LTE_FilterCoefficient_fc7: return 7;
|
||||
case LTE_FilterCoefficient_fc8: return 8;
|
||||
case LTE_FilterCoefficient_fc9: return 9;
|
||||
case LTE_FilterCoefficient_fc11: return 11;
|
||||
case LTE_FilterCoefficient_fc13: return 13;
|
||||
case LTE_FilterCoefficient_fc15: return 15;
|
||||
case LTE_FilterCoefficient_fc17: return 17;
|
||||
case LTE_FilterCoefficient_fc19: return 19;
|
||||
case LTE_FilterCoefficient_spare1: return -1; /* spare means no coefficient */
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Periodic event */
|
||||
|
||||
long flexran_get_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells;
|
||||
}
|
||||
|
||||
/* A3 event */
|
||||
|
||||
long flexran_get_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
switch (ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger) {
|
||||
case LTE_TimeToTrigger_ms0: return 0;
|
||||
case LTE_TimeToTrigger_ms40: return 40;
|
||||
case LTE_TimeToTrigger_ms64: return 64;
|
||||
case LTE_TimeToTrigger_ms80: return 80;
|
||||
case LTE_TimeToTrigger_ms100: return 100;
|
||||
case LTE_TimeToTrigger_ms128: return 128;
|
||||
case LTE_TimeToTrigger_ms160: return 160;
|
||||
case LTE_TimeToTrigger_ms256: return 256;
|
||||
case LTE_TimeToTrigger_ms320: return 320;
|
||||
case LTE_TimeToTrigger_ms480: return 480;
|
||||
case LTE_TimeToTrigger_ms512: return 512;
|
||||
case LTE_TimeToTrigger_ms640: return 640;
|
||||
case LTE_TimeToTrigger_ms1024: return 1024;
|
||||
case LTE_TimeToTrigger_ms1280: return 1280;
|
||||
case LTE_TimeToTrigger_ms2560: return 2560;
|
||||
case LTE_TimeToTrigger_ms5120: return 5120;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long flexran_get_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells;
|
||||
}
|
||||
|
||||
long flexran_get_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset;
|
||||
}
|
||||
|
||||
int flexran_get_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
return ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave;
|
||||
}
|
||||
|
||||
/* RRC Setters */
|
||||
|
||||
/* Measurement offsets */
|
||||
|
||||
int flexran_set_rrc_ofp(mid_t mod_id, rnti_t rnti, long offsetFreq) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_ofn(mid_t mod_id, rnti_t rnti, long offsetFreq) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_ocp(mid_t mod_id, rnti_t rnti, long cellIndividualOffset) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[0];
|
||||
switch (cellIndividualOffset) {
|
||||
case -24: *cio = LTE_Q_OffsetRange_dB_24; break;
|
||||
case -22: *cio = LTE_Q_OffsetRange_dB_22; break;
|
||||
case -20: *cio = LTE_Q_OffsetRange_dB_20; break;
|
||||
case -18: *cio = LTE_Q_OffsetRange_dB_18; break;
|
||||
case -16: *cio = LTE_Q_OffsetRange_dB_16; break;
|
||||
case -14: *cio = LTE_Q_OffsetRange_dB_14; break;
|
||||
case -12: *cio = LTE_Q_OffsetRange_dB_12; break;
|
||||
case -10: *cio = LTE_Q_OffsetRange_dB_10; break;
|
||||
case -8: *cio = LTE_Q_OffsetRange_dB_8; break;
|
||||
case -6: *cio = LTE_Q_OffsetRange_dB_6; break;
|
||||
case -5: *cio = LTE_Q_OffsetRange_dB_5; break;
|
||||
case -4: *cio = LTE_Q_OffsetRange_dB_4; break;
|
||||
case -3: *cio = LTE_Q_OffsetRange_dB_3; break;
|
||||
case -2: *cio = LTE_Q_OffsetRange_dB_2; break;
|
||||
case -1: *cio = LTE_Q_OffsetRange_dB_1; break;
|
||||
case 0: *cio = LTE_Q_OffsetRange_dB0; break;
|
||||
case 1: *cio = LTE_Q_OffsetRange_dB1; break;
|
||||
case 2: *cio = LTE_Q_OffsetRange_dB2; break;
|
||||
case 3: *cio = LTE_Q_OffsetRange_dB3; break;
|
||||
case 4: *cio = LTE_Q_OffsetRange_dB4; break;
|
||||
case 5: *cio = LTE_Q_OffsetRange_dB5; break;
|
||||
case 6: *cio = LTE_Q_OffsetRange_dB6; break;
|
||||
case 8: *cio = LTE_Q_OffsetRange_dB8; break;
|
||||
case 10: *cio = LTE_Q_OffsetRange_dB10; break;
|
||||
case 12: *cio = LTE_Q_OffsetRange_dB12; break;
|
||||
case 14: *cio = LTE_Q_OffsetRange_dB14; break;
|
||||
case 16: *cio = LTE_Q_OffsetRange_dB16; break;
|
||||
case 18: *cio = LTE_Q_OffsetRange_dB18; break;
|
||||
case 20: *cio = LTE_Q_OffsetRange_dB20; break;
|
||||
case 22: *cio = LTE_Q_OffsetRange_dB22; break;
|
||||
case 24: *cio = LTE_Q_OffsetRange_dB24; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id, long cellIndividualOffset) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1];
|
||||
switch (cellIndividualOffset) {
|
||||
case -24: *cio = LTE_Q_OffsetRange_dB_24; break;
|
||||
case -22: *cio = LTE_Q_OffsetRange_dB_22; break;
|
||||
case -20: *cio = LTE_Q_OffsetRange_dB_20; break;
|
||||
case -18: *cio = LTE_Q_OffsetRange_dB_18; break;
|
||||
case -16: *cio = LTE_Q_OffsetRange_dB_16; break;
|
||||
case -14: *cio = LTE_Q_OffsetRange_dB_14; break;
|
||||
case -12: *cio = LTE_Q_OffsetRange_dB_12; break;
|
||||
case -10: *cio = LTE_Q_OffsetRange_dB_10; break;
|
||||
case -8: *cio = LTE_Q_OffsetRange_dB_8; break;
|
||||
case -6: *cio = LTE_Q_OffsetRange_dB_6; break;
|
||||
case -5: *cio = LTE_Q_OffsetRange_dB_5; break;
|
||||
case -4: *cio = LTE_Q_OffsetRange_dB_4; break;
|
||||
case -3: *cio = LTE_Q_OffsetRange_dB_3; break;
|
||||
case -2: *cio = LTE_Q_OffsetRange_dB_2; break;
|
||||
case -1: *cio = LTE_Q_OffsetRange_dB_1; break;
|
||||
case 0: *cio = LTE_Q_OffsetRange_dB0; break;
|
||||
case 1: *cio = LTE_Q_OffsetRange_dB1; break;
|
||||
case 2: *cio = LTE_Q_OffsetRange_dB2; break;
|
||||
case 3: *cio = LTE_Q_OffsetRange_dB3; break;
|
||||
case 4: *cio = LTE_Q_OffsetRange_dB4; break;
|
||||
case 5: *cio = LTE_Q_OffsetRange_dB5; break;
|
||||
case 6: *cio = LTE_Q_OffsetRange_dB6; break;
|
||||
case 8: *cio = LTE_Q_OffsetRange_dB8; break;
|
||||
case 10: *cio = LTE_Q_OffsetRange_dB10; break;
|
||||
case 12: *cio = LTE_Q_OffsetRange_dB12; break;
|
||||
case 14: *cio = LTE_Q_OffsetRange_dB14; break;
|
||||
case 16: *cio = LTE_Q_OffsetRange_dB16; break;
|
||||
case 18: *cio = LTE_Q_OffsetRange_dB18; break;
|
||||
case 20: *cio = LTE_Q_OffsetRange_dB20; break;
|
||||
case 22: *cio = LTE_Q_OffsetRange_dB22; break;
|
||||
case 24: *cio = LTE_Q_OffsetRange_dB24; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRP) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRP;
|
||||
switch (filterCoefficientRSRP) {
|
||||
case 0: *fc = LTE_FilterCoefficient_fc0; break;
|
||||
case 1: *fc = LTE_FilterCoefficient_fc1; break;
|
||||
case 2: *fc = LTE_FilterCoefficient_fc2; break;
|
||||
case 3: *fc = LTE_FilterCoefficient_fc3; break;
|
||||
case 4: *fc = LTE_FilterCoefficient_fc4; break;
|
||||
case 5: *fc = LTE_FilterCoefficient_fc5; break;
|
||||
case 6: *fc = LTE_FilterCoefficient_fc6; break;
|
||||
case 7: *fc = LTE_FilterCoefficient_fc7; break;
|
||||
case 8: *fc = LTE_FilterCoefficient_fc8; break;
|
||||
case 9: *fc = LTE_FilterCoefficient_fc9; break;
|
||||
case 11: *fc = LTE_FilterCoefficient_fc11; break;
|
||||
case 13: *fc = LTE_FilterCoefficient_fc13; break;
|
||||
case 15: *fc = LTE_FilterCoefficient_fc15; break;
|
||||
case 17: *fc = LTE_FilterCoefficient_fc17; break;
|
||||
case 19: *fc = LTE_FilterCoefficient_fc19; break;
|
||||
case -1: *fc = LTE_FilterCoefficient_spare1; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRQ) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ;
|
||||
switch (filterCoefficientRSRQ) {
|
||||
case 0: *fc = LTE_FilterCoefficient_fc0; break;
|
||||
case 1: *fc = LTE_FilterCoefficient_fc1; break;
|
||||
case 2: *fc = LTE_FilterCoefficient_fc2; break;
|
||||
case 3: *fc = LTE_FilterCoefficient_fc3; break;
|
||||
case 4: *fc = LTE_FilterCoefficient_fc4; break;
|
||||
case 5: *fc = LTE_FilterCoefficient_fc5; break;
|
||||
case 6: *fc = LTE_FilterCoefficient_fc6; break;
|
||||
case 7: *fc = LTE_FilterCoefficient_fc7; break;
|
||||
case 8: *fc = LTE_FilterCoefficient_fc8; break;
|
||||
case 9: *fc = LTE_FilterCoefficient_fc9; break;
|
||||
case 11: *fc = LTE_FilterCoefficient_fc11; break;
|
||||
case 13: *fc = LTE_FilterCoefficient_fc13; break;
|
||||
case 15: *fc = LTE_FilterCoefficient_fc15; break;
|
||||
case 17: *fc = LTE_FilterCoefficient_fc17; break;
|
||||
case 19: *fc = LTE_FilterCoefficient_fc19; break;
|
||||
case -1: *fc = LTE_FilterCoefficient_spare1; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Periodic event */
|
||||
|
||||
int flexran_set_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1;
|
||||
if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells = maxReportCells;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* A3 event */
|
||||
|
||||
int flexran_set_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti, long hysteresis) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((hysteresis >=0) && (hysteresis <= 30))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis = hysteresis;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti, long timeToTrigger) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
LTE_TimeToTrigger_t *ttt = &ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger;
|
||||
switch (timeToTrigger) {
|
||||
case 0: *ttt = LTE_TimeToTrigger_ms0; break;
|
||||
case 40: *ttt = LTE_TimeToTrigger_ms40; break;
|
||||
case 64: *ttt = LTE_TimeToTrigger_ms64; break;
|
||||
case 80: *ttt = LTE_TimeToTrigger_ms80; break;
|
||||
case 100: *ttt = LTE_TimeToTrigger_ms100; break;
|
||||
case 128: *ttt = LTE_TimeToTrigger_ms128; break;
|
||||
case 160: *ttt = LTE_TimeToTrigger_ms160; break;
|
||||
case 256: *ttt = LTE_TimeToTrigger_ms256; break;
|
||||
case 320: *ttt = LTE_TimeToTrigger_ms320; break;
|
||||
case 480: *ttt = LTE_TimeToTrigger_ms480; break;
|
||||
case 512: *ttt = LTE_TimeToTrigger_ms512; break;
|
||||
case 640: *ttt = LTE_TimeToTrigger_ms640; break;
|
||||
case 1024: *ttt = LTE_TimeToTrigger_ms1024; break;
|
||||
case 1280: *ttt = LTE_TimeToTrigger_ms1280; break;
|
||||
case 2560: *ttt = LTE_TimeToTrigger_ms2560; break;
|
||||
case 5120: *ttt = LTE_TimeToTrigger_ms5120; break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells = maxReportCells;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti, long a3_offset) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((a3_offset >= -30) && (a3_offset <= 30))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset = a3_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti, int reportOnLeave) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events) return -1;
|
||||
if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
|
||||
if (!((reportOnLeave == 0) || (reportOnLeave == 1))) return -1;
|
||||
ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave = reportOnLeave;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_set_x2_ho_net_control(mid_t mod_id, int x2_ho_net_control) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
if (!((x2_ho_net_control == 0) || (x2_ho_net_control == 1))) return -1;
|
||||
RC.rrc[mod_id]->x2_ho_net_control = x2_ho_net_control;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flexran_get_x2_ho_net_control(mid_t mod_id) {
|
||||
if (!rrc_is_present(mod_id)) return -1;
|
||||
return RC.rrc[mod_id]->x2_ho_net_control;
|
||||
}
|
||||
|
||||
uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.num_plmn;
|
||||
}
|
||||
|
||||
uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index)
|
||||
{
|
||||
uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.mcc[index];
|
||||
}
|
||||
|
||||
uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index)
|
||||
{
|
||||
uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.mnc[index];
|
||||
}
|
||||
|
||||
uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index)
|
||||
{
|
||||
uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->configuration.mnc_digit_length[index];
|
||||
}
|
||||
|
||||
int flexran_get_rrc_num_adj_cells(mid_t mod_id) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
return RC.rrc[mod_id]->num_neigh_cells;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_num_e_rab(mid_t mod_id, rnti_t rnti) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.setup_e_rabs;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_get_e_rab_id(mid_t mod_id, rnti_t rnti, int index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.e_rab[index].param.e_rab_id;
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.enb_gtp_teid[index];
|
||||
}
|
||||
|
||||
int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index) {
|
||||
if (!rrc_is_present(mod_id)) return 0;
|
||||
struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
|
||||
if (!ue_context_p) return 0;
|
||||
return ue_context_p->ue_context.e_rab[index].param.gtp_teid;
|
||||
}
|
||||
|
||||
/**************************** SLICING ****************************/
|
||||
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,7 @@ sub_frame_t flexran_get_current_subframe(mid_t mod_id);
|
||||
|
||||
/*Return the frame and subframe number in compact 16-bit format.
|
||||
Bits 0-3 subframe, rest for frame. Required by FlexRAN protocol*/
|
||||
uint16_t flexran_get_sfn_sf(mid_t mod_id);
|
||||
uint32_t flexran_get_sfn_sf(mid_t mod_id);
|
||||
|
||||
/* Return a future frame and subframe number that is ahead_of_time
|
||||
subframes later in compact 16-bit format. Bits 0-3 subframe,
|
||||
@@ -498,6 +498,12 @@ uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
|
||||
uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid);
|
||||
|
||||
/*********************RRC**********************/
|
||||
/* Call RRC Reconfiguration wrapper function */
|
||||
int flexran_call_rrc_reconfiguration (mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Call RRC to trigger handover wrapper function */
|
||||
int flexran_call_rrc_trigger_handover (mid_t mod_id, rnti_t rnti, int target_cell_id);
|
||||
|
||||
/*Get primary cell measuremeant id flexRAN*/
|
||||
LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
@@ -510,22 +516,107 @@ float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti);
|
||||
/* Get RRC neighbouring measurement */
|
||||
int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get physical cell id */
|
||||
/* Get neighbouring physical cell id */
|
||||
long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi */
|
||||
int flexran_get_rrc_neigh_cgi(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi info cell id */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_cell_id(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi info tac */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_tac(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get the number of neighbouring cgi mnc */
|
||||
int flexran_get_rrc_neigh_cgi_num_mnc(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get the number of neighbouring cgi mcc */
|
||||
int flexran_get_rrc_neigh_cgi_num_mcc(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get neighbouring cgi mnc */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mnc(mid_t mod_id, rnti_t rnti, long cell_id, int mnc_id);
|
||||
|
||||
/* Get neighbouring cgi mcc */
|
||||
uint32_t flexran_get_rrc_neigh_cgi_mcc(mid_t mod_id, rnti_t rnti, long cell_id, int mcc_id);
|
||||
|
||||
/* Get RSRP of neighbouring Cell */
|
||||
float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get RSRQ of neighbouring Cell */
|
||||
float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/*Get MCC PLMN identity neighbouring Cell*/
|
||||
/* currently not implemented
|
||||
int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, rnti_t rnti, int cell_id); */
|
||||
/* Get ofp offset */
|
||||
long flexran_get_rrc_ofp(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/*Get MNC PLMN identity neighbouring Cell*/
|
||||
/* currently not implemented
|
||||
int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */
|
||||
/* Get ofn offset */
|
||||
long flexran_get_rrc_ofn(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get ocp offset */
|
||||
long flexran_get_rrc_ocp(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get ocn offset */
|
||||
long flexran_get_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id);
|
||||
|
||||
/* Get Periodic Event max reported cells */
|
||||
long flexran_get_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event hysteresis */
|
||||
long flexran_get_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event time to trigger */
|
||||
long flexran_get_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event max reported cells */
|
||||
long flexran_get_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event a3 offset */
|
||||
long flexran_get_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get A3 Event report on leave */
|
||||
int flexran_get_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get filter coefficient for rsrp */
|
||||
long flexran_get_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get filter coefficient for rsrq */
|
||||
long flexran_get_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Set ofp offset */
|
||||
int flexran_set_rrc_ofp(mid_t mod_id, rnti_t rnti, long offsetFreq);
|
||||
|
||||
/* Set ofn offset */
|
||||
int flexran_set_rrc_ofn(mid_t mod_id, rnti_t rnti, long offsetFreq);
|
||||
|
||||
/* Set ocp offset */
|
||||
int flexran_set_rrc_ocp(mid_t mod_id, rnti_t rnti, long cellIndividualOffset);
|
||||
|
||||
/* Set ocn offset */
|
||||
int flexran_set_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id, long cellIndividualOffset);
|
||||
|
||||
/* Set Periodic Event max reported cells */
|
||||
int flexran_set_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells);
|
||||
|
||||
/* Set A3 Event hysteresis */
|
||||
int flexran_set_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti, long hysteresis);
|
||||
|
||||
/* Set A3 Event time to trigger */
|
||||
int flexran_set_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti, long timeToTrigger);
|
||||
|
||||
/* Set A3 Event max reported cells */
|
||||
int flexran_set_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells);
|
||||
|
||||
/* Set A3 Event a3 offset */
|
||||
int flexran_set_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti, long a3_offset);
|
||||
|
||||
/* Set A3 Event report on leave */
|
||||
int flexran_set_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti, int reportOnLeave);
|
||||
|
||||
/* Set filter coefficient for rsrp */
|
||||
int flexran_set_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRP);
|
||||
|
||||
/* Set filter coefficient for rsrq */
|
||||
int flexran_set_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRQ);
|
||||
|
||||
/* Get number of PLMNs that is broadcasted in SIB1 */
|
||||
uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id);
|
||||
@@ -539,6 +630,27 @@ uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index);
|
||||
/* Get index'th MNC's digit length broadcasted in SIB1 */
|
||||
uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index);
|
||||
|
||||
/* Get X2 handover controlled by network */
|
||||
int flexran_get_x2_ho_net_control(mid_t mod_id);
|
||||
|
||||
/* Set X2 handover controlled by network */
|
||||
int flexran_set_x2_ho_net_control(mid_t mod_id, int x2_ho_net_control);
|
||||
|
||||
/* Get number of adjacent cells via X2 interface */
|
||||
int flexran_get_rrc_num_adj_cells(mid_t mod_id);
|
||||
|
||||
/* Get the number of E-RABs for UE */
|
||||
int flexran_agent_rrc_gtp_num_e_rab(mid_t mod_id, rnti_t rnti);
|
||||
|
||||
/* Get the e-RAB ID for UE */
|
||||
int flexran_agent_rrc_gtp_get_e_rab_id(mid_t mod_id, rnti_t rnti, int index);
|
||||
|
||||
/* Get the TEID at the eNB for UE */
|
||||
int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index);
|
||||
|
||||
/* Get the TEID at the SGW for UE */
|
||||
int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index);
|
||||
|
||||
/************************** Slice configuration **************************/
|
||||
|
||||
/* Get the DL slice ID for a UE */
|
||||
|
||||
@@ -1001,7 +1001,7 @@ void eNB_Config_Local_DRX(
|
||||
{
|
||||
UE_list_t *UE_list_mac = NULL;
|
||||
int UE_id = -1;
|
||||
UE_sched_ctrl *UE_scheduling_control = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
|
||||
UE_list_mac = &(RC.mac[Mod_id]->UE_list);
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ void schedule_SRS(module_id_t module_idP,
|
||||
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
||||
UE_list_t *UE_list = &(eNB->UE_list);
|
||||
nfapi_ul_config_request_body_t *ul_req = NULL;
|
||||
UE_sched_ctrl *UE_scheduling_control = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
COMMON_channels_t *cc = eNB->common_channels;
|
||||
LTE_SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon = NULL;
|
||||
struct LTE_SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated = NULL;
|
||||
@@ -198,7 +198,7 @@ void schedule_CSI(module_id_t module_idP,
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
COMMON_channels_t *cc = NULL;
|
||||
nfapi_ul_config_request_body_t *ul_req = NULL;
|
||||
UE_sched_ctrl *UE_scheduling_control = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
cc = &eNB->common_channels[CC_id];
|
||||
@@ -572,7 +572,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
||||
UE_list_t *UE_list = &(eNB->UE_list);
|
||||
COMMON_channels_t *cc = eNB->common_channels;
|
||||
UE_sched_ctrl *UE_scheduling_control = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
|
||||
start_meas(&(eNB->eNB_scheduler));
|
||||
|
||||
|
||||
@@ -480,7 +480,7 @@ schedule_ue_spec(module_id_t module_idP,
|
||||
eNB_UE_STATS *eNB_UE_stats = NULL;
|
||||
UE_TEMPLATE *ue_template = NULL;
|
||||
eNB_STATS *eNB_stats = NULL;
|
||||
RRC_release_ctrl *release_ctrl = NULL;
|
||||
RRC_release_ctrl_t *release_ctrl = NULL;
|
||||
DLSCH_PDU *dlsch_pdu = NULL;
|
||||
RA_t *ra = NULL;
|
||||
int sdu_length_total = 0;
|
||||
@@ -490,7 +490,7 @@ schedule_ue_spec(module_id_t module_idP,
|
||||
int continue_flag = 0;
|
||||
int32_t normalized_rx_power, target_rx_power;
|
||||
int tpc = 1;
|
||||
UE_sched_ctrl *ue_sched_ctrl;
|
||||
UE_sched_ctrl_t *ue_sched_ctrl;
|
||||
int mcs;
|
||||
int i;
|
||||
int min_rb_unit[NFAPI_CC_MAX];
|
||||
@@ -1688,7 +1688,7 @@ dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
|
||||
int nb_mac_CC = RC.nb_mac_CC[Mod_id];
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
slice_info_t *sli = &eNB->slice_info;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
COMMON_channels_t *cc;
|
||||
int N_RBG[NFAPI_CC_MAX];
|
||||
int slice_sorted_list[MAX_NUM_SLICES];
|
||||
@@ -1914,7 +1914,7 @@ schedule_ue_spec_br(module_id_t module_idP,
|
||||
COMMON_channels_t *cc = mac->common_channels;
|
||||
UE_list_t *UE_list = &mac->UE_list;
|
||||
UE_TEMPLATE *UE_template = NULL;
|
||||
UE_sched_ctrl *ue_sched_ctl = NULL;
|
||||
UE_sched_ctrl_t *ue_sched_ctl = NULL;
|
||||
nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL;
|
||||
nfapi_ul_config_request_pdu_t *ul_config_pdu = NULL;
|
||||
nfapi_tx_request_pdu_t *TX_req = NULL;
|
||||
|
||||
@@ -179,7 +179,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
|
||||
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
||||
COMMON_channels_t *cc = eNB->common_channels;
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
uint8_t CC_id;
|
||||
int UE_id;
|
||||
unsigned char round = 0;
|
||||
@@ -585,7 +585,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
|
||||
// uint16_t r1=0;
|
||||
uint8_t CC_id;
|
||||
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
// int rrc_status = RRC_IDLE;
|
||||
COMMON_channels_t *cc;
|
||||
#ifdef TM5
|
||||
@@ -596,7 +596,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
|
||||
rnti_t rnti1, rnti2;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
|
||||
UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
|
||||
UE_sched_ctrl_t *ue_sched_ctl1, *ue_sched_ctl2;
|
||||
#endif
|
||||
memset(rballoc_sub[0],0,(MAX_NUM_CCs)*(N_RBG_MAX)*sizeof(unsigned char));
|
||||
memset(min_rb_unit,0,sizeof(min_rb_unit));
|
||||
@@ -829,7 +829,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
|
||||
int32_t normalized_rx_power, target_rx_power;
|
||||
int32_t tpc = 1;
|
||||
static int32_t tpc_accumulated = 0;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
int mcs;
|
||||
int i;
|
||||
int min_rb_unit[MAX_NUM_CCs];
|
||||
@@ -1970,7 +1970,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
|
||||
uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
|
||||
uint16_t saved_ulsch_dci[MAX_NUM_CCs];
|
||||
rnti_t rnti;
|
||||
UE_sched_ctrl *UE_sched_ctl = NULL;
|
||||
UE_sched_ctrl_t *UE_sched_ctl = NULL;
|
||||
uint8_t cc_id_flag[MAX_NUM_CCs];
|
||||
uint8_t harq_pid = 0,round = 0;
|
||||
UE_list_t *UE_list= &eNB->UE_list;
|
||||
@@ -2629,7 +2629,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
|
||||
COMMON_channels_t *cc;
|
||||
UE_list_t *UE_list=&eNB->UE_list;
|
||||
UE_TEMPLATE *UE_template;
|
||||
UE_sched_ctrl *UE_sched_ctrl;
|
||||
UE_sched_ctrl_t *UE_sched_ctrl;
|
||||
int sched_frame=frameP;
|
||||
int rvidx_tab[4] = {0,2,3,1};
|
||||
uint16_t ul_req_index;
|
||||
|
||||
@@ -208,7 +208,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
|
||||
COMMON_channels_t *cc = &mac->common_channels[0];
|
||||
UE_list_t *UE_list=&mac->UE_list;
|
||||
UE_TEMPLATE *UE_template;
|
||||
UE_sched_ctrl *UE_sched_ctrl;
|
||||
UE_sched_ctrl_t *UE_sched_ctrl;
|
||||
int sched_frame=frameP;
|
||||
int sched_subframe = (subframeP+4)%10;
|
||||
uint16_t ul_req_index;
|
||||
|
||||
@@ -1073,7 +1073,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc,
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t
|
||||
get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,
|
||||
get_rel8_dl_cqi_pmi_size(UE_sched_ctrl_t *sched_ctl,
|
||||
int CC_idP,
|
||||
COMMON_channels_t *cc,
|
||||
uint8_t tmode,
|
||||
@@ -2182,7 +2182,7 @@ add_new_ue(module_id_t mod_idP,
|
||||
#endif
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
|
||||
0,
|
||||
sizeof(UE_sched_ctrl));
|
||||
sizeof(UE_sched_ctrl_t));
|
||||
memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id],
|
||||
0,
|
||||
sizeof(eNB_UE_STATS));
|
||||
@@ -2520,7 +2520,7 @@ UE_is_to_be_scheduled(module_id_t module_idP,
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
UE_TEMPLATE *UE_template = &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id];
|
||||
UE_sched_ctrl *UE_sched_ctl = &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id];
|
||||
UE_sched_ctrl_t *UE_sched_ctl = &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id];
|
||||
|
||||
// do not schedule UE if UL is not working
|
||||
if (UE_sched_ctl->ul_failure_timer > 0 || UE_sched_ctl->ul_out_of_sync > 0)
|
||||
@@ -3928,7 +3928,7 @@ extract_harq(module_id_t mod_idP,
|
||||
{
|
||||
eNB_MAC_INST *eNB = RC.mac[mod_idP];
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
rnti_t rnti = UE_RNTI(mod_idP, UE_id);
|
||||
COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
|
||||
nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd;
|
||||
@@ -4573,7 +4573,7 @@ extract_pucch_csi(module_id_t mod_idP,
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
|
||||
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
|
||||
int no_pmi;
|
||||
uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 };
|
||||
@@ -4685,7 +4685,7 @@ extract_pusch_csi(module_id_t mod_idP,
|
||||
{
|
||||
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
|
||||
COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
|
||||
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
int Ntab[6] = { 0, 4, 7, 9, 10, 13 };
|
||||
int Ntab_uesel[6] = { 0, 8, 13, 17, 19, 25 };
|
||||
int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 };
|
||||
@@ -4980,7 +4980,7 @@ cqi_indication(module_id_t mod_idP,
|
||||
return;
|
||||
}
|
||||
|
||||
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
|
||||
if (UE_id >= 0) {
|
||||
LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n",
|
||||
@@ -5047,7 +5047,7 @@ SR_indication(module_id_t mod_idP,
|
||||
T_INT(rntiP));
|
||||
int UE_id = find_UE_id(mod_idP, rntiP);
|
||||
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
|
||||
UE_sched_ctrl *UE_scheduling_ctrl = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_ctrl = NULL;
|
||||
|
||||
if (UE_id != -1) {
|
||||
UE_scheduling_ctrl = &(UE_list->UE_sched_ctrl[UE_id]);
|
||||
@@ -5178,7 +5178,7 @@ harq_indication(module_id_t mod_idP,
|
||||
}
|
||||
|
||||
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
|
||||
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
|
||||
// extract HARQ Information
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ rx_sdu(const module_id_t enb_mod_idP,
|
||||
eNB_MAC_INST *mac = NULL;
|
||||
UE_list_t *UE_list = NULL;
|
||||
rrc_eNB_ue_context_t *ue_contextP = NULL;
|
||||
UE_sched_ctrl *UE_scheduling_control = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
UE_TEMPLATE *UE_template_ptr = NULL;
|
||||
|
||||
/* Init */
|
||||
@@ -1344,7 +1344,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
|
||||
UE_list_t *UE_list = NULL;
|
||||
slice_info_t *sli = NULL;
|
||||
UE_TEMPLATE *UE_template_ptr = NULL;
|
||||
UE_sched_ctrl *UE_sched_ctrl_ptr = NULL;
|
||||
UE_sched_ctrl_t *UE_sched_ctrl_ptr = NULL;
|
||||
int rvidx_tab[4] = {0, 2, 3, 1};
|
||||
int first_rb_slice[NFAPI_CC_MAX];
|
||||
int n_rb_ul_tab[NFAPI_CC_MAX];
|
||||
@@ -1958,7 +1958,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
|
||||
COMMON_channels_t *cc = eNB->common_channels;
|
||||
UE_list_t *UE_list = &(eNB->UE_list);
|
||||
UE_TEMPLATE *UE_template = NULL;
|
||||
UE_sched_ctrl *UE_sched_ctrl = NULL;
|
||||
UE_sched_ctrl_t *UE_sched_ctrl = NULL;
|
||||
|
||||
if (sched_subframeP < subframeP) {
|
||||
sched_frame++;
|
||||
|
||||
@@ -1070,7 +1070,7 @@ typedef struct {
|
||||
/// DRX UL retransmission timer, one per UL HARQ process
|
||||
/* Not implemented yet */
|
||||
/* End of C-DRX related timers */
|
||||
} UE_sched_ctrl;
|
||||
} UE_sched_ctrl_t;
|
||||
|
||||
/*! \brief eNB template for the Random access information */
|
||||
typedef struct {
|
||||
@@ -1168,7 +1168,7 @@ typedef struct {
|
||||
/// eNB to UE statistics
|
||||
eNB_UE_STATS eNB_UE_stats[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
|
||||
/// scheduling control info
|
||||
UE_sched_ctrl UE_sched_ctrl[MAX_MOBILES_PER_ENB];
|
||||
UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_ENB];
|
||||
int next[MAX_MOBILES_PER_ENB];
|
||||
int head;
|
||||
int next_ul[MAX_MOBILES_PER_ENB];
|
||||
@@ -1191,11 +1191,11 @@ typedef struct {
|
||||
rnti_t rnti;
|
||||
///remove UE context flag
|
||||
boolean_t removeContextFlg;
|
||||
} UE_free_ctrl;
|
||||
} UE_free_ctrl_t;
|
||||
/*! \brief REMOVE UE list used by eNB to order UEs/CC for deleting*/
|
||||
typedef struct {
|
||||
/// deleting control info
|
||||
UE_free_ctrl UE_free_ctrl[NUMBER_OF_UE_MAX+1];
|
||||
UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1];
|
||||
int num_UEs;
|
||||
int head_freelist; ///the head position of the delete list
|
||||
int tail_freelist; ///the tail position of the delete list
|
||||
@@ -1774,11 +1774,11 @@ typedef struct {
|
||||
volatile uint8_t flag;
|
||||
rnti_t rnti;
|
||||
mui_t rrc_eNB_mui;
|
||||
}RRC_release_ctrl;
|
||||
}RRC_release_ctrl_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t num_UEs;
|
||||
RRC_release_ctrl RRC_release_ctrl[NUMBER_OF_UE_MAX];
|
||||
RRC_release_ctrl_t RRC_release_ctrl[NUMBER_OF_UE_MAX];
|
||||
} RRC_release_list_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -1160,7 +1160,7 @@ void get_csi_params(COMMON_channels_t * cc,
|
||||
struct LTE_CQI_ReportPeriodic *cqi_PMI_ConfigIndex,
|
||||
uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H);
|
||||
|
||||
uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP,
|
||||
uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl_t * sched_ctl, int CC_idP,
|
||||
COMMON_channels_t * cc, uint8_t tmode,
|
||||
struct LTE_CQI_ReportPeriodic
|
||||
*cqi_ReportPeriodic);
|
||||
|
||||
@@ -505,7 +505,7 @@ void sort_UEs(module_id_t Mod_idP,
|
||||
int list_size = 0;
|
||||
struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_idx};
|
||||
UE_list_t *UE_list = &(RC.mac[Mod_idP]->UE_list);
|
||||
UE_sched_ctrl *UE_scheduling_control = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
|
||||
@@ -546,7 +546,7 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id,
|
||||
const uint8_t rbs_retx[NFAPI_CC_MAX]) {
|
||||
int UE_id, CC_id, N_RB_DL, i;
|
||||
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
uint16_t available_rbs;
|
||||
|
||||
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
@@ -590,7 +590,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
|
||||
int ue_count_retx[NFAPI_CC_MAX];
|
||||
//uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
|
||||
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
COMMON_channels_t *cc;
|
||||
|
||||
// Reset
|
||||
@@ -1226,7 +1226,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
||||
uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].MIMO_mode_indicator;
|
||||
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
// int rrc_status = RRC_IDLE;
|
||||
#ifdef TM5
|
||||
int harq_pid1 = 0;
|
||||
@@ -1236,7 +1236,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
||||
rnti_t rnti1, rnti2;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
|
||||
UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
|
||||
UE_sched_ctrl_t *ue_sched_ctl1, *ue_sched_ctl2;
|
||||
#endif
|
||||
// Initialize scheduling information for all active UEs
|
||||
memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results[slice_idx]));
|
||||
@@ -1391,7 +1391,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
|
||||
uint8_t CC_id;
|
||||
int i, j;
|
||||
UE_list_t *UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
int N_RB_DL, RBGsize, RBGsize_last;
|
||||
int N_RBG[NFAPI_CC_MAX];
|
||||
#ifdef SF0_LIMIT
|
||||
@@ -1615,7 +1615,7 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
|
||||
int i;
|
||||
int tm = get_tmode(Mod_id, CC_id, UE_id);
|
||||
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
|
||||
|
||||
for (i = 0; i < N_RBG; i++) {
|
||||
@@ -1685,7 +1685,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
slice_info_t *sli = &eNB->slice_info;
|
||||
UE_TEMPLATE *UE_template = 0;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
int N_RB_UL = 0;
|
||||
uint16_t available_rbs, first_rb_offset;
|
||||
rnti_t rntiTable[MAX_MOBILES_PER_ENB];
|
||||
@@ -1865,7 +1865,7 @@ assign_max_mcs_min_rb(module_id_t module_idP,
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
slice_info_t *sli = &eNB->slice_info;
|
||||
UE_TEMPLATE *UE_template;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
UE_sched_ctrl_t *ue_sched_ctl;
|
||||
int Ncp;
|
||||
int N_RB_UL;
|
||||
int first_rb_offset, available_rbs;
|
||||
@@ -2042,7 +2042,7 @@ void sort_ue_ul(module_id_t module_idP,
|
||||
int list_size = 0;
|
||||
struct sort_ue_ul_params params = { module_idP, sched_frameP, sched_subframeP };
|
||||
UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
|
||||
UE_sched_ctrl *UE_scheduling_control = NULL;
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ rlc_am_receive_process_control_pdu(
|
||||
rlc_sn_t ack_sn = RLC_AM_NEXT_SN(rlc_pP->vt_a);
|
||||
rlc_sn_t sn_cursor = rlc_pP->vt_a;
|
||||
rlc_sn_t vt_a_new = rlc_pP->vt_a;
|
||||
rlc_sn_t sn_data_cnf;
|
||||
rlc_sn_t sn_data_cnf = (rlc_sn_t) 0;
|
||||
rlc_sn_t nack_sn,prev_nack_sn;
|
||||
sdu_size_t data_cnf_so_stop = 0x7FFF;
|
||||
unsigned int nack_index;
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
|
||||
#define MAX_PAYLOAD 1024 /* maximum payload size*/
|
||||
|
||||
#define MAX_NUM_NEIGH_CELLs 6 /* maximum neighbouring cells number */
|
||||
|
||||
#define UE_STATE_NOTIFICATION_INTERVAL 50
|
||||
|
||||
#define IPV4_ADDR "%u.%u.%u.%u"
|
||||
@@ -477,6 +479,73 @@ typedef struct HANDOVER_INFO_s {
|
||||
int x2_id; /* X2AP UE ID in the target eNB */
|
||||
} HANDOVER_INFO;
|
||||
|
||||
typedef struct PER_EVENT_s {
|
||||
long maxReportCells;
|
||||
} PER_EVENT_t;
|
||||
|
||||
typedef struct A1_EVENT_s {
|
||||
long threshold_RSRP;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A1_EVENT_t;
|
||||
|
||||
typedef struct A2_EVENT_s {
|
||||
long threshold_RSRP;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A2_EVENT_t;
|
||||
|
||||
typedef struct A3_EVENT_s {
|
||||
long a3_offset;
|
||||
int reportOnLeave;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A3_EVENT_t;
|
||||
|
||||
|
||||
typedef struct A4_EVENT_s {
|
||||
long threshold_RSRP;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A4_EVENT_t;
|
||||
|
||||
typedef struct A5_EVENT_s {
|
||||
long threshold_RSRP_1;
|
||||
long threshold_RSRP_2;
|
||||
long hysteresis;
|
||||
long timeToTrigger;
|
||||
long maxReportCells;
|
||||
} A5_EVENT_t;
|
||||
|
||||
typedef struct EVENTS_s {
|
||||
PER_EVENT_t *per_event;
|
||||
|
||||
A1_EVENT_t *a1_event;
|
||||
|
||||
A2_EVENT_t *a2_event;
|
||||
|
||||
A3_EVENT_t *a3_event;
|
||||
|
||||
A4_EVENT_t *a4_event;
|
||||
|
||||
A5_EVENT_t *a5_event;
|
||||
} EVENTS_t;
|
||||
|
||||
typedef struct MEASUREMENT_INFO_s {
|
||||
//TODO: Extend to multiple meas objects for OFP/OFN offsets
|
||||
long offsetFreq;
|
||||
//TODO: extend to multiple carriers for OCP/OCN offsets
|
||||
long cellIndividualOffset[MAX_NUM_NEIGH_CELLs+1];
|
||||
long filterCoefficientRSRP;
|
||||
long filterCoefficientRSRQ;
|
||||
EVENTS_t *events;
|
||||
} MEASUREMENT_INFO;
|
||||
|
||||
|
||||
#define RRC_HEADER_SIZE_MAX 64
|
||||
#define RRC_BUFFER_SIZE_MAX 1024
|
||||
typedef struct {
|
||||
@@ -559,6 +628,7 @@ typedef struct eNB_RRC_UE_s {
|
||||
SRB_INFO_TABLE_ENTRY Srb2;
|
||||
LTE_MeasConfig_t *measConfig;
|
||||
HANDOVER_INFO *handover_info;
|
||||
MEASUREMENT_INFO *measurement_info;
|
||||
LTE_MeasResults_t *measResults;
|
||||
LTE_MobilityControlInfo_t *mobilityInfo;
|
||||
|
||||
@@ -756,6 +826,14 @@ typedef struct eNB_RRC_INST_s {
|
||||
/// NR cell id
|
||||
uint64_t nr_cellid;
|
||||
|
||||
// X2 handover controlled by network
|
||||
int x2_ho_net_control;
|
||||
|
||||
// Neighborouring cells id
|
||||
int num_neigh_cells;
|
||||
int num_neigh_cells_cc[MAX_NUM_CCs];
|
||||
uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
|
||||
|
||||
// other RAN parameters
|
||||
int srb1_timer_poll_retransmit;
|
||||
int srb1_poll_pdu;
|
||||
|
||||
+657
-212
File diff suppressed because it is too large
Load Diff
@@ -306,8 +306,7 @@ void
|
||||
flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *const ue_context_pP,
|
||||
const uint8_t ho_state,
|
||||
agent_reconf_rrc *trig_param
|
||||
const uint8_t ho_state
|
||||
);
|
||||
void
|
||||
rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -357,6 +356,9 @@ void *rrc_enb_task(void *args_p);
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
void *rrc_ue_task(void *args_p);
|
||||
|
||||
void rrc_eNB_process_x2_setup_request(int mod_id, x2ap_setup_req_t *m);
|
||||
|
||||
void rrc_eNB_process_x2_setup_response(int mod_id, x2ap_setup_resp_t *m);
|
||||
|
||||
void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m);
|
||||
|
||||
@@ -610,6 +612,12 @@ rrc_eNB_generate_HandoverPreparationInformation(
|
||||
//LTE_PhysCellId_t targetPhyId
|
||||
);
|
||||
|
||||
int
|
||||
flexran_rrc_eNB_trigger_handover (int mod_id,
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *ue_context_pP,
|
||||
int target_cell_id);
|
||||
|
||||
void
|
||||
check_handovers(
|
||||
protocol_ctxt_t *const ctxt_pP
|
||||
|
||||
@@ -291,6 +291,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
uint32_t eNB_id = 0;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
@@ -391,17 +392,25 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_SETUP_REQ);
|
||||
|
||||
X2AP_SETUP_REQ(msg).num_cc = ie->value.choice.ServedCells.list.count;
|
||||
|
||||
if (ie->value.choice.ServedCells.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count;
|
||||
for (int i=0; i<ie->value.choice.ServedCells.list.count;i++) {
|
||||
servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI;
|
||||
X2AP_SETUP_REQ(msg).Nid_cell[i] = x2ap_eNB_data->Nid_cell[i];
|
||||
}
|
||||
}
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
|
||||
}
|
||||
|
||||
@@ -418,6 +427,7 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
uint32_t eNB_id = 0;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
@@ -500,11 +510,16 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_SETUP_RESP);
|
||||
|
||||
X2AP_SETUP_RESP(msg).num_cc = ie->value.choice.ServedCells.list.count;
|
||||
|
||||
if (ie->value.choice.ServedCells.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count;
|
||||
for (int i=0; i<ie->value.choice.ServedCells.list.count;i++) {
|
||||
servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI;
|
||||
X2AP_SETUP_RESP(msg).Nid_cell[i] = x2ap_eNB_data->Nid_cell[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,6 +536,8 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
|
||||
instance_p->x2_target_enb_associated_nb ++;
|
||||
x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -267,7 +267,7 @@ int nas_message_decrypt(
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
int bytes = length;
|
||||
|
||||
/* Decode the header */
|
||||
@@ -277,7 +277,8 @@ int nas_message_decrypt(
|
||||
LOG_TRACE(DEBUG, "MESSAGE TOO SHORT");
|
||||
LOG_FUNC_RETURN (TLV_DECODE_BUFFER_TOO_SHORT);
|
||||
} else if (size > 1) {
|
||||
if (emm_security_context) {
|
||||
if (security) {
|
||||
emm_security_context = (emm_security_context_t*)security;
|
||||
#if defined(NAS_MME)
|
||||
|
||||
if (emm_security_context->ul_count.seq_num > header->sequence_number) {
|
||||
@@ -376,7 +377,7 @@ int nas_message_decode(
|
||||
void *security)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
int bytes;
|
||||
|
||||
/* Decode the header */
|
||||
@@ -385,7 +386,8 @@ int nas_message_decode(
|
||||
if (size < 0) {
|
||||
LOG_FUNC_RETURN (TLV_DECODE_BUFFER_TOO_SHORT);
|
||||
} else if (size > 1) {
|
||||
if (emm_security_context) {
|
||||
if (security) {
|
||||
emm_security_context = (emm_security_context_t*)security;
|
||||
#if defined(NAS_MME)
|
||||
|
||||
if (emm_security_context->ul_count.seq_num > msg->header.sequence_number) {
|
||||
@@ -971,6 +973,8 @@ static int _nas_message_decrypt(
|
||||
#else
|
||||
direction = SECU_DIRECTION_DOWNLINK;
|
||||
#endif
|
||||
if (emm_security_context == NULL)
|
||||
LOG_FUNC_RETURN (0);
|
||||
|
||||
switch (security_header_type) {
|
||||
case SECURITY_HEADER_TYPE_NOT_PROTECTED:
|
||||
|
||||
@@ -42,35 +42,35 @@
|
||||
int set_device(openair0_device *device) {
|
||||
switch (device->type) {
|
||||
case EXMIMO_DEV:
|
||||
printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
break;
|
||||
|
||||
case USRP_B200_DEV:
|
||||
printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
break;
|
||||
|
||||
case USRP_X300_DEV:
|
||||
printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
break;
|
||||
|
||||
case BLADERF_DEV:
|
||||
printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
break;
|
||||
|
||||
case LMSSDR_DEV:
|
||||
printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
break;
|
||||
|
||||
case IRIS_DEV:
|
||||
printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
break;
|
||||
|
||||
case NONE_DEV:
|
||||
printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_E(HW,"[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -80,17 +80,17 @@ int set_device(openair0_device *device) {
|
||||
int set_transport(openair0_device *device) {
|
||||
switch (device->transp_type) {
|
||||
case ETHERNET_TP:
|
||||
printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case NONE_TP:
|
||||
printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_I(HW,"[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
LOG_E(HW,"[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
@@ -119,7 +119,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
|
||||
ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,"Library %s couldn't be loaded\n",libname);
|
||||
LOG_E(HW,"Library %s couldn't be loaded\n",libname);
|
||||
} else {
|
||||
ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cf
|
||||
|
||||
if ( rc >= 0) {
|
||||
if ( set_device(device) < 0) {
|
||||
fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__);
|
||||
LOG_E(HW, "%s %d:Unsupported radio head\n",__FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ int openair0_transport_load(openair0_device *device, openair0_config_t *openair0
|
||||
|
||||
if ( rc >= 0) {
|
||||
if ( set_transport(device) < 0) {
|
||||
fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__);
|
||||
LOG_E(HW, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define COMMON_LIB_H
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <openair1/PHY/TOOLS/tools_defs.h>
|
||||
|
||||
/* name of shared library implementing the radio front end */
|
||||
#define OAI_RF_LIBNAME "oai_device"
|
||||
@@ -83,9 +84,6 @@ typedef enum {
|
||||
*/
|
||||
/*!\brief RF device types
|
||||
*/
|
||||
#ifdef OCP_FRAMEWORK
|
||||
#include <enums.h>
|
||||
#else
|
||||
typedef enum {
|
||||
MIN_RF_DEV_TYPE = 0,
|
||||
/*!\brief device is ExpressMIMO */
|
||||
@@ -102,10 +100,13 @@ typedef enum {
|
||||
IRIS_DEV,
|
||||
/*!\brief device is NONE*/
|
||||
NONE_DEV,
|
||||
/*!\brief device is ADRV9371_ZC706 */
|
||||
ADRV9371_ZC706_DEV,
|
||||
/*!\brief device is UEDv2 */
|
||||
UEDv2_DEV,
|
||||
MAX_RF_DEV_TYPE
|
||||
|
||||
} dev_type_t;
|
||||
#endif
|
||||
|
||||
/*!\brief transport protocol types
|
||||
*/
|
||||
@@ -397,6 +398,31 @@ struct openair0_device_t {
|
||||
typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
|
||||
/* type of transport init function, implemented in shared lib */
|
||||
typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
|
||||
#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record
|
||||
#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record
|
||||
#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record
|
||||
#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record
|
||||
|
||||
#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record
|
||||
#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record
|
||||
#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record
|
||||
#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record
|
||||
|
||||
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
|
||||
|
||||
#define sample_t struct complex16 // 2*16 bits complex number
|
||||
|
||||
typedef struct {
|
||||
uint64_t magic; // Magic value (see defines above)
|
||||
uint32_t size; // Number of samples per antenna to follow this header
|
||||
uint32_t nbAnt; // Total number of antennas following this header
|
||||
// Samples per antenna follow this header,
|
||||
// i.e. nbAnt = 2 => this header+samples_antenna_0+samples_antenna_1
|
||||
// data following this header in bytes is nbAnt*size*sizeof(sample_t)
|
||||
uint64_t timestamp; // Timestamp value of first sample
|
||||
uint32_t option_value; // Option value
|
||||
uint32_t option_flag; // Option flag
|
||||
} samplesBlockHeader_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
||||
@@ -539,7 +539,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
|
||||
*/
|
||||
static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
|
||||
usrp_state_t *s = (usrp_state_t *)device->priv;
|
||||
int samples_received=0,i,j;
|
||||
int samples_received=0;
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
#if defined(USRP_REC_PLAY)
|
||||
|
||||
@@ -760,12 +760,9 @@ int trx_usrp_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,
|
||||
*/
|
||||
int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
usrp_state_t *s = (usrp_state_t *)device->priv;
|
||||
static int first_call=1;
|
||||
static double rf_freq,diff;
|
||||
uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]);
|
||||
rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
|
||||
rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0];
|
||||
rf_freq=openair0_cfg[0].rx_freq[0];
|
||||
s->usrp->set_rx_freq(rx_tune_req);
|
||||
return(0);
|
||||
}
|
||||
@@ -1248,7 +1245,7 @@ extern "C" {
|
||||
openair0_cfg[0].iq_txshift = 4;//shift
|
||||
openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
|
||||
|
||||
for(int i=0; i<s->usrp->get_rx_num_channels(); i++) {
|
||||
for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) {
|
||||
if (i<openair0_cfg[0].rx_num_channels) {
|
||||
s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i);
|
||||
s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i);
|
||||
@@ -1268,7 +1265,7 @@ extern "C" {
|
||||
LOG_D(PHY, "usrp->get_tx_num_channels() == %zd\n", s->usrp->get_tx_num_channels());
|
||||
LOG_D(PHY, "openair0_cfg[0].tx_num_channels == %d\n", openair0_cfg[0].tx_num_channels);
|
||||
|
||||
for(int i=0; i<s->usrp->get_tx_num_channels(); i++) {
|
||||
for(int i=0; i<((int) s->usrp->get_tx_num_channels()); i++) {
|
||||
::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i);
|
||||
|
||||
if (i<openair0_cfg[0].tx_num_channels) {
|
||||
@@ -1310,10 +1307,10 @@ extern "C" {
|
||||
s->tx_stream = s->usrp->get_tx_stream(stream_args_tx);
|
||||
|
||||
/* Setting TX/RX BW after streamers are created due to USRP calibration issue */
|
||||
for(int i=0; i<s->usrp->get_tx_num_channels() && i<openair0_cfg[0].tx_num_channels; i++)
|
||||
for(int i=0; i<((int) s->usrp->get_tx_num_channels()) && i<openair0_cfg[0].tx_num_channels; i++)
|
||||
s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i);
|
||||
|
||||
for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++)
|
||||
for(int i=0; i<((int) s->usrp->get_rx_num_channels()) && i<openair0_cfg[0].rx_num_channels; i++)
|
||||
s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i);
|
||||
|
||||
for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) {
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
## General
|
||||
|
||||
#General
|
||||
This is a RF simulator that allows to test OAI without a RF board.
|
||||
It replaces a actual RF board driver.
|
||||
|
||||
As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound)
|
||||
|
||||
## build
|
||||
#build
|
||||
|
||||
No specific build is required, use the [oai softmodem build procedure](../../../doc/BUILD.md)
|
||||
## From build_oai
|
||||
You can build it the same way, and together with actual RF driver
|
||||
|
||||
Example:
|
||||
```bash
|
||||
./build_oai --ue-nas-use-tun --UE --eNB -w SIMU
|
||||
```
|
||||
It is also possible to build actual RF and use choose on each run:
|
||||
```bash
|
||||
./build_oai --ue-nas-use-tun --UE --eNB -w USRP --rfsimulator
|
||||
```
|
||||
Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem)
|
||||
We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver.
|
||||
|
||||
## Add the rfsimulator after initial build
|
||||
After any regular build, you can compile the driver
|
||||
```bash
|
||||
cd <the_compilation_dir_from_bouild_oai_script>/build
|
||||
@@ -18,35 +30,21 @@ Then, you can use it freely
|
||||
|
||||
# Usage
|
||||
Setting the env variable RFSIMULATOR enables the RF board simulator
|
||||
It should the set to "enb" in the eNB
|
||||
It should the set to "server" in the eNB or gNB
|
||||
|
||||
## 4G case
|
||||
For the UE, it should be set to the IP address of the eNB
|
||||
example:
|
||||
|
||||
```bash
|
||||
sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 --rfsim
|
||||
sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50
|
||||
```
|
||||
For the eNodeB, use a valid configuration file setup for USRP board tests and start the softmodem as usual, but adding the `--rfsim` option.
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
sudo RFSIMULATOR=enb ./lte-softmodem -O <config file> --rfsim
|
||||
```
|
||||
|
||||
|
||||
|
||||
Except this, the UE and the eNB can be used as it the RF is real
|
||||
|
||||
If you reach 'RA not active' on UE, be careful to generate a valid SIM
|
||||
```bash
|
||||
$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
|
||||
```
|
||||
This simulator can also be used with the `--noS1` option, in this case you must run the eNodeB and the UE on different PCs.
|
||||
|
||||
## 5G case
|
||||
|
||||
After regular build, add the simulation driver
|
||||
(don't use ./build_oai -w SIMU until we merge 4G and 5G branches)
|
||||
```bash
|
||||
@@ -55,7 +53,7 @@ make rfsimulator
|
||||
```
|
||||
### Launch gNB in one window
|
||||
```bash
|
||||
sudo RFSIMULATOR=enb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD
|
||||
sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD
|
||||
```
|
||||
### Launch UE in another window
|
||||
```bash
|
||||
@@ -64,8 +62,40 @@ sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000
|
||||
Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
|
||||
In UE, you can add "-d" to get the softscope
|
||||
|
||||
## Caveacts
|
||||
### store and replay
|
||||
|
||||
You can store emitted I/Q samples:
|
||||
|
||||
If you set the environment variable: saveIQfile to a file name
|
||||
The simulator will write all IQ samples into this file
|
||||
|
||||
Then, you can replay with the executable "replay_node"
|
||||
|
||||
First compile it, as the other binaries
|
||||
```
|
||||
make replay_node
|
||||
```
|
||||
You can use this binary as I/Q data source to feed whatever UE or NB with recorded I/Q samples.
|
||||
|
||||
The file format is successive blocks of a header followed by the I/Q array.
|
||||
If you have existing stored I/Q, you can adpat the tool "replay_node" to convert your format to the rfsimulator format.
|
||||
|
||||
The format intend to be compatible with the OAI store/replay feature on USRP
|
||||
|
||||
### Channel simulation
|
||||
The RF channel simulator is called.
|
||||
In current version all channel paramters are hard coded in the call to:
|
||||
```
|
||||
new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
|
||||
AWGN,
|
||||
bridge->sample_rate,
|
||||
bridge->tx_bw,
|
||||
0.0, // forgetting_factor
|
||||
0, // maybe used for TA
|
||||
0); // path_loss in dB
|
||||
```
|
||||
Only the input noise can be changed on command line with -s parameter.
|
||||
With path loss = 0 set "-s 5" to see a little noise
|
||||
|
||||
#Caveacts
|
||||
Still issues in power control: txgain, rxgain are not used
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
||||
*/
|
||||
|
||||
/*
|
||||
* Open issues and limitations
|
||||
* The read and write should be called in the same thread, that is not new USRP UHD design
|
||||
* When the opposite side switch from passive reading to active R+Write, the synchro is not fully deterministic
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
@@ -21,63 +27,175 @@
|
||||
#include "common_lib.h"
|
||||
#include <openair1/PHY/defs_eNB.h>
|
||||
#include "openair1/PHY/defs_UE.h"
|
||||
#include <openair1/SIMULATION/TOOLS/sim.h>
|
||||
|
||||
#define PORT 4043 //TCP port for this simulator
|
||||
#define CirSize 3072000 // 100ms is enough
|
||||
#define sample_t uint32_t // 2*16 bits complex number
|
||||
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
|
||||
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
|
||||
#define MAGICeNB 0xA5A5A5A5A5A5A5A5
|
||||
#define MAGICUE 0x5A5A5A5A5A5A5A5A
|
||||
|
||||
typedef struct {
|
||||
uint64_t magic;
|
||||
uint32_t size;
|
||||
uint32_t nbAnt;
|
||||
uint64_t timestamp;
|
||||
} transferHeader;
|
||||
#define MAX_SIMULATION_CONNECTED_NODES 5
|
||||
#define GENERATE_CHANNEL 10 //each frame in DL
|
||||
|
||||
// Fixme: datamodel, external variables in .h files, ...
|
||||
#include <common/ran_context.h>
|
||||
extern double snr_dB;
|
||||
extern RAN_CONTEXT_t RC;
|
||||
//
|
||||
|
||||
pthread_mutex_t Sockmutex;
|
||||
|
||||
typedef struct buffer_s {
|
||||
int conn_sock;
|
||||
bool alreadyRead;
|
||||
uint64_t lastReceivedTS;
|
||||
bool headerMode;
|
||||
transferHeader th;
|
||||
samplesBlockHeader_t th;
|
||||
char *transferPtr;
|
||||
uint64_t remainToTransfer;
|
||||
char *circularBufEnd;
|
||||
sample_t *circularBuf;
|
||||
channel_desc_t *channel_model;
|
||||
} buffer_t;
|
||||
|
||||
typedef struct {
|
||||
int listen_sock, epollfd;
|
||||
uint64_t nextTimestamp;
|
||||
uint64_t typeStamp;
|
||||
uint64_t initialAhead;
|
||||
char *ip;
|
||||
int saveIQfile;
|
||||
buffer_t buf[FD_SETSIZE];
|
||||
int rx_num_channels;
|
||||
int tx_num_channels;
|
||||
double sample_rate;
|
||||
double tx_bw;
|
||||
} rfsimulator_state_t;
|
||||
|
||||
/*
|
||||
Legacy study:
|
||||
The parameters are:
|
||||
gain&loss (decay, signal power, ...)
|
||||
either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average
|
||||
=> don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE
|
||||
will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop)
|
||||
lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas);
|
||||
a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain
|
||||
|
||||
multi_path (auto convolution, ISI, ...)
|
||||
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
|
||||
legacy: we regenerate each sub frame in UL, and each frame only in DL
|
||||
*/
|
||||
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
|
||||
int rxAnt,
|
||||
channel_desc_t *channelDesc,
|
||||
int nbSamples,
|
||||
uint64_t TS
|
||||
) {
|
||||
// channelDesc->path_loss_dB should contain the total path gain
|
||||
// so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...)
|
||||
// UE and NB gain control to be added
|
||||
// Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
|
||||
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
|
||||
// Energy in one sample to calibrate input noise
|
||||
//Fixme: modified the N0W computation, not understand the origin value
|
||||
const double KT=1.38e-23*290; //Boltzman*temperature
|
||||
// sampling rate is linked to acquisition band (the input pass band filter)
|
||||
const double noise_figure_watt = KT*channelDesc->sampling_rate;
|
||||
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
|
||||
// the parameter "-s" is declared as SNR, but the input power is not well defined
|
||||
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
|
||||
const double rxGain= 132.24 - snr_dB;
|
||||
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
|
||||
// fixme: the last constant is pure trial results to make decent noise
|
||||
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
|
||||
// Fixme: we don't fill the offset length samples at begining ?
|
||||
// anyway, in today code, channel_offset=0
|
||||
const int dd = abs(channelDesc->channel_offset);
|
||||
const int nbTx=channelDesc->nb_tx;
|
||||
|
||||
for (int i=0; i<((int)nbSamples-dd); i++) {
|
||||
struct complex16 *out_ptr=after_channel_sig+dd+i;
|
||||
struct complex rx_tmp= {0};
|
||||
|
||||
for (int txAnt=0; txAnt < nbTx; txAnt++) {
|
||||
const struct complex *channelModel= channelDesc->ch[rxAnt+(txAnt*channelDesc->nb_rx)];
|
||||
|
||||
//const struct complex *channelModelEnd=channelModel+channelDesc->channel_length;
|
||||
for (int l = 0; l<(int)channelDesc->channel_length; l++) {
|
||||
// let's assume TS+i >= l
|
||||
// fixme: the rfsimulator current structure is interleaved antennas
|
||||
// this has been designed to not have to wait a full block transmission
|
||||
// but it is not very usefull
|
||||
// it would be better to split out each antenna in a separate flow
|
||||
// that will allow to mix ru antennas freely
|
||||
struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
|
||||
rx_tmp.x += tx16.r * channelModel[l].x - tx16.i * channelModel[l].y;
|
||||
rx_tmp.y += tx16.i * channelModel[l].x + tx16.r * channelModel[l].y;
|
||||
} //l
|
||||
}
|
||||
|
||||
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||
printf("in: %d, out %d= %f*%f + %f*%f\n",
|
||||
input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , rx_tmp.x,
|
||||
pathLossLinear, noise_per_sample,gaussdouble(0.0,1.0));
|
||||
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||
out_ptr++;
|
||||
}
|
||||
|
||||
if ( (TS*nbTx)%CirSize+nbSamples <= CirSize )
|
||||
// Cast to a wrong type for compatibility !
|
||||
LOG_D(HW,"Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n",
|
||||
10*log10((double)signal_energy((int32_t *)&input_sig[(TS*nbTx)%CirSize], nbSamples)),
|
||||
10*log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)),
|
||||
channelDesc->path_loss_dB,
|
||||
10*log10(noise_per_sample));
|
||||
}
|
||||
|
||||
void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
buffer_t *ptr=&bridge->buf[sock];
|
||||
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
|
||||
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
|
||||
ptr->conn_sock=sock;
|
||||
ptr->alreadyRead=false;
|
||||
ptr->lastReceivedTS=0;
|
||||
ptr->headerMode=true;
|
||||
ptr->transferPtr=(char *)&ptr->th;
|
||||
ptr->remainToTransfer=sizeof(transferHeader);
|
||||
ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
|
||||
int sendbuff=1000*1000*10;
|
||||
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
|
||||
struct epoll_event ev= {0};
|
||||
ev.events = EPOLLIN | EPOLLRDHUP;
|
||||
ev.data.fd = sock;
|
||||
AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, "");
|
||||
// create channel simulation model for this mode reception
|
||||
// snr_dB is pure global, coming from configuration paramter "-s"
|
||||
// Fixme: referenceSignalPower should come from the right place
|
||||
// but the datamodel is inconsistant
|
||||
// legacy: RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower
|
||||
// (must not come from ru[]->frame_parms as it doesn't belong to ru !!!)
|
||||
// Legacy sets it as:
|
||||
// ptr->channel_model->path_loss_dB = -132.24 + snr_dB - RC.ru[0]->frame_parms->pdsch_config_common.referenceSignalPower;
|
||||
// we use directly the paramter passed on the command line ("-s")
|
||||
// the value channel_model->path_loss_dB seems only a storage place (new_channel_desc_scm() only copy the passed value)
|
||||
// Legacy changes directlty the variable channel_model->path_loss_dB place to place
|
||||
// while calling new_channel_desc_scm() with path losses = 0
|
||||
ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
|
||||
AWGN,
|
||||
bridge->sample_rate,
|
||||
bridge->tx_bw,
|
||||
0.0, // forgetting_factor
|
||||
0, // maybe used for TA
|
||||
0); // path_loss in dB
|
||||
random_channel(ptr->channel_model,false);
|
||||
}
|
||||
|
||||
void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
|
||||
close(sock);
|
||||
free(bridge->buf[sock].circularBuf);
|
||||
// Fixme: no free_channel_desc_scm(bridge->buf[sock].channel_model) implemented
|
||||
// a lot of mem leaks
|
||||
free(bridge->buf[sock].channel_model);
|
||||
memset(&bridge->buf[sock], 0, sizeof(buffer_t));
|
||||
bridge->buf[sock].conn_sock=-1;
|
||||
}
|
||||
@@ -87,12 +205,11 @@ void socketError(rfsimulator_state_t *bridge, int sock) {
|
||||
LOG_W(HW,"Lost socket \n");
|
||||
removeCirBuf(bridge, sock);
|
||||
|
||||
if (bridge->typeStamp==MAGICUE)
|
||||
if (bridge->typeStamp==UE_MAGICDL_FDD)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define helpTxt "\
|
||||
\x1b[31m\
|
||||
rfsimulator: error: you have to run one UE and one eNB\n\
|
||||
@@ -117,11 +234,18 @@ void setblocking(int sock, enum blocking_t active) {
|
||||
AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, "");
|
||||
}
|
||||
|
||||
static bool flushInput(rfsimulator_state_t *t);
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout);
|
||||
|
||||
void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
|
||||
void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
||||
if (t->saveIQfile != -1) {
|
||||
if (write(t->saveIQfile, _buf, count) != count )
|
||||
LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno));
|
||||
}
|
||||
|
||||
AssertFatal(fd>=0 && _buf && count >0 && t,
|
||||
"Bug: %d/%p/%zd/%p", fd, _buf, count, t);
|
||||
char *buf = _buf;
|
||||
int l;
|
||||
ssize_t l;
|
||||
setblocking(fd, notBlocking);
|
||||
|
||||
while (count) {
|
||||
@@ -132,7 +256,9 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
|
||||
continue;
|
||||
|
||||
if(errno==EAGAIN) {
|
||||
flushInput(t);
|
||||
// The opposite side is saturated
|
||||
// we read incoming sockets meawhile waiting
|
||||
flushInput(t, 5);
|
||||
continue;
|
||||
} else
|
||||
return;
|
||||
@@ -145,7 +271,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
|
||||
|
||||
int server_start(openair0_device *device) {
|
||||
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
|
||||
t->typeStamp=MAGICeNB;
|
||||
t->typeStamp=ENB_MAGICDL_FDD;
|
||||
AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
|
||||
int enable = 1;
|
||||
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
|
||||
@@ -168,7 +294,7 @@ sin_addr:
|
||||
|
||||
int start_ue(openair0_device *device) {
|
||||
rfsimulator_state_t *t = device->priv;
|
||||
t->typeStamp=MAGICUE;
|
||||
t->typeStamp=UE_MAGICDL_FDD;
|
||||
int sock;
|
||||
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
|
||||
struct sockaddr_in addr = {
|
||||
@@ -200,14 +326,16 @@ sin_addr:
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t lastW=-1;
|
||||
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
||||
rfsimulator_state_t *t = device->priv;
|
||||
LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
|
||||
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
buffer_t *ptr=&t->buf[i];
|
||||
|
||||
if (ptr->conn_sock >= 0 ) {
|
||||
transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp};
|
||||
samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
|
||||
fullwrite(ptr->conn_sock,&header, sizeof(header), t);
|
||||
sample_t tmpSamples[nsamps][nbAnt];
|
||||
|
||||
@@ -223,21 +351,27 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
|
||||
}
|
||||
}
|
||||
|
||||
lastW=timestamp;
|
||||
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
|
||||
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
|
||||
// Let's verify we don't have incoming data
|
||||
// This is mandatory when the opposite side don't transmit
|
||||
// This is mandatory when the opposite side don't transmit
|
||||
flushInput(t, 0);
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
static bool flushInput(rfsimulator_state_t *t) {
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
||||
// Process all incoming events on sockets
|
||||
// store the data in lists
|
||||
struct epoll_event events[FD_SETSIZE]= {0};
|
||||
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 200);
|
||||
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout);
|
||||
|
||||
if ( nfds==-1 ) {
|
||||
if ( errno==EINTR || errno==EAGAIN )
|
||||
if ( errno==EINTR || errno==EAGAIN ) {
|
||||
return false;
|
||||
else
|
||||
} else
|
||||
AssertFatal(false,"error in epoll_wait\n");
|
||||
}
|
||||
|
||||
@@ -263,7 +397,7 @@ static bool flushInput(rfsimulator_state_t *t) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int blockSz;
|
||||
ssize_t blockSz;
|
||||
|
||||
if ( b->headerMode)
|
||||
blockSz=b->remainToTransfer;
|
||||
@@ -272,7 +406,7 @@ static bool flushInput(rfsimulator_state_t *t) {
|
||||
b->remainToTransfer :
|
||||
b->circularBufEnd - 1 - b->transferPtr ;
|
||||
|
||||
int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT);
|
||||
ssize_t sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT);
|
||||
|
||||
if ( sz < 0 ) {
|
||||
if ( errno != EAGAIN ) {
|
||||
@@ -282,6 +416,7 @@ static bool flushInput(rfsimulator_state_t *t) {
|
||||
} else if ( sz == 0 )
|
||||
continue;
|
||||
|
||||
LOG_D(HW, "Socket rcv %zd bytes\n", sz);
|
||||
AssertFatal((b->remainToTransfer-=sz) >= 0, "");
|
||||
b->transferPtr+=sz;
|
||||
|
||||
@@ -290,39 +425,44 @@ static bool flushInput(rfsimulator_state_t *t) {
|
||||
|
||||
// check the header and start block transfer
|
||||
if ( b->headerMode==true && b->remainToTransfer==0) {
|
||||
AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) ||
|
||||
(t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol");
|
||||
AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
|
||||
(t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
|
||||
b->headerMode=false;
|
||||
b->alreadyRead=true;
|
||||
|
||||
if ( b->lastReceivedTS != b->th.timestamp) {
|
||||
int nbAnt= b->th.nbAnt;
|
||||
|
||||
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ )
|
||||
for (int a=0; a < nbAnt; a++)
|
||||
b->circularBuf[(index*nbAnt+a)%CirSize]=0;
|
||||
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) {
|
||||
for (int a=0; a < nbAnt; a++) {
|
||||
b->circularBuf[(index*nbAnt+a)%CirSize].r=0;
|
||||
b->circularBuf[(index*nbAnt+a)%CirSize].i=0;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
|
||||
}
|
||||
|
||||
b->lastReceivedTS=b->th.timestamp;
|
||||
AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize),
|
||||
"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS);
|
||||
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
|
||||
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
|
||||
}
|
||||
|
||||
if ( b->headerMode==false ) {
|
||||
LOG_D(HW,"Set b->lastReceivedTS %ld\n", b->lastReceivedTS);
|
||||
b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt);
|
||||
|
||||
// First block in UE, resync with the eNB current TS
|
||||
if ( t->nextTimestamp == 0 )
|
||||
t->nextTimestamp=b->lastReceivedTS-b->th.size;
|
||||
|
||||
if ( b->remainToTransfer==0) {
|
||||
LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
|
||||
|
||||
// First block in UE, resync with the eNB current TS
|
||||
if ( t->nextTimestamp == 0 )
|
||||
t->nextTimestamp=b->lastReceivedTS-b->th.size;
|
||||
|
||||
b->headerMode=true;
|
||||
b->transferPtr=(char *)&b->th;
|
||||
b->remainToTransfer=sizeof(transferHeader);
|
||||
b->remainToTransfer=sizeof(samplesBlockHeader_t);
|
||||
b->th.magic=-1;
|
||||
}
|
||||
}
|
||||
@@ -334,10 +474,10 @@ static bool flushInput(rfsimulator_state_t *t) {
|
||||
|
||||
int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
|
||||
if (nbAnt != 1) {
|
||||
LOG_E(HW, "rfsimulator: only 1 antenna tested\n");
|
||||
exit(1);
|
||||
LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&Sockmutex);
|
||||
rfsimulator_state_t *t = device->priv;
|
||||
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
|
||||
// deliver data from received data
|
||||
@@ -350,13 +490,14 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
|
||||
if ( first_sock == FD_SETSIZE ) {
|
||||
// no connected device (we are eNB, no UE is connected)
|
||||
if (!flushInput(t)) {
|
||||
if (!flushInput(t, 10)) {
|
||||
for (int x=0; x < nbAnt; x++)
|
||||
memset(samplesVoid[x],0,sampleToByte(nsamps,1));
|
||||
|
||||
t->nextTimestamp+=nsamps;
|
||||
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
|
||||
*ptimestamp = t->nextTimestamp-nsamps;
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
return nsamps;
|
||||
}
|
||||
} else {
|
||||
@@ -365,20 +506,21 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
do {
|
||||
have_to_wait=false;
|
||||
|
||||
for ( int sock=0; sock<FD_SETSIZE; sock++)
|
||||
if ( t->buf[sock].circularBuf &&
|
||||
t->buf[sock].alreadyRead && //>= t->initialAhead &&
|
||||
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
|
||||
have_to_wait=true;
|
||||
break;
|
||||
}
|
||||
for ( int sock=0; sock<FD_SETSIZE; sock++) {
|
||||
if ( t->buf[sock].circularBuf && t->buf[sock].alreadyRead )
|
||||
if ( t->buf[sock].lastReceivedTS == 0 ||
|
||||
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
|
||||
have_to_wait=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_to_wait)
|
||||
/*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n",
|
||||
ptr->lastReceivedTS,
|
||||
t->nextTimestamp+nsamps);
|
||||
*/
|
||||
flushInput(t);
|
||||
flushInput(t, 3);
|
||||
} while (have_to_wait);
|
||||
}
|
||||
|
||||
@@ -386,17 +528,25 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
for (int a=0; a<nbAnt; a++)
|
||||
memset(samplesVoid[a],0,sampleToByte(nsamps,1));
|
||||
|
||||
// Add all input signal in the output buffer
|
||||
// Add all input nodes signal in the output buffer
|
||||
for (int sock=0; sock<FD_SETSIZE; sock++) {
|
||||
buffer_t *ptr=&t->buf[sock];
|
||||
|
||||
if ( ptr->circularBuf && ptr->alreadyRead ) {
|
||||
for (int a=0; a<nbAnt; a++) {
|
||||
sample_t *out=(sample_t *)samplesVoid[a];
|
||||
bool reGenerateChannel=false;
|
||||
|
||||
for ( int i=0; i < nsamps; i++ )
|
||||
out[i]+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1;
|
||||
}
|
||||
//fixme: when do we regenerate
|
||||
// it seems legacy behavior is: never in UL, each frame in DL
|
||||
if (reGenerateChannel)
|
||||
random_channel(ptr->channel_model,0);
|
||||
|
||||
for (int a=0; a<nbAnt; a++)
|
||||
rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a],
|
||||
a,
|
||||
ptr->channel_model,
|
||||
nsamps,
|
||||
t->nextTimestamp
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,10 +556,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
nsamps,
|
||||
*ptimestamp, t->nextTimestamp,
|
||||
signal_energy(samplesVoid[0], nsamps));
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
|
||||
int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||
abort();
|
||||
return 0;
|
||||
@@ -434,11 +583,10 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf
|
||||
int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
__attribute__((__visibility__("default")))
|
||||
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
//set_log(HW,OAILOG_DEBUG);
|
||||
// to change the log level, use this on command line
|
||||
// --log_config.hw_log_level debug
|
||||
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
|
||||
|
||||
if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) {
|
||||
@@ -446,11 +594,28 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ?
|
||||
MAGICeNB:
|
||||
MAGICUE;
|
||||
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE");
|
||||
device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ?
|
||||
pthread_mutex_init(&Sockmutex, NULL);
|
||||
|
||||
if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 ||
|
||||
strncasecmp(rfsimulator->ip,"server",3) == 0 )
|
||||
rfsimulator->typeStamp = ENB_MAGICDL_FDD;
|
||||
else
|
||||
rfsimulator->typeStamp = UE_MAGICDL_FDD;
|
||||
|
||||
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "(eg)NB" : "UE");
|
||||
char *saveF;
|
||||
|
||||
if ((saveF=getenv("saveIQfile")) != NULL) {
|
||||
rfsimulator->saveIQfile=open(saveF,O_APPEND| O_CREAT|O_TRUNC | O_WRONLY, 0666);
|
||||
|
||||
if ( rfsimulator->saveIQfile != -1 )
|
||||
LOG_I(HW,"rfsimulator: will save written IQ samples in %s\n", saveF);
|
||||
else
|
||||
LOG_E(HW, "can't open %s for IQ saving (%s)\n", saveF, strerror(errno));
|
||||
} else
|
||||
rfsimulator->saveIQfile = -1;
|
||||
|
||||
device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ?
|
||||
server_start :
|
||||
start_ue;
|
||||
device->trx_get_stats_func = rfsimulator_get_stats;
|
||||
@@ -470,6 +635,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
rfsimulator->buf[i].conn_sock=-1;
|
||||
|
||||
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
|
||||
rfsimulator->initialAhead=openair0_cfg[0].sample_rate/1000; // One sub frame
|
||||
// initialize channel simulation
|
||||
rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
|
||||
rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
|
||||
rfsimulator->sample_rate=openair0_cfg->sample_rate;
|
||||
rfsimulator->tx_bw=openair0_cfg->tx_bw;
|
||||
randominit(0);
|
||||
set_taus_seed(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
Author: Laurent THOMAS, Open Cells
|
||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
||||
*/
|
||||
|
||||
#include <common/utils/simple_executable.h>
|
||||
|
||||
|
||||
void fullwrite(int fd, void *_buf, int count) {
|
||||
char *buf = _buf;
|
||||
int l;
|
||||
|
||||
while (count) {
|
||||
l = write(fd, buf, count);
|
||||
|
||||
if (l <= 0) {
|
||||
if (errno==EINTR)
|
||||
continue;
|
||||
|
||||
if(errno==EAGAIN) {
|
||||
continue;
|
||||
} else {
|
||||
AssertFatal(false,"Lost socket\n");
|
||||
}
|
||||
} else {
|
||||
count -= l;
|
||||
buf += l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int server_start(short port) {
|
||||
int listen_sock;
|
||||
AssertFatal((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
|
||||
int enable = 1;
|
||||
AssertFatal(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
|
||||
struct sockaddr_in addr = {
|
||||
sin_family:
|
||||
AF_INET,
|
||||
sin_port:
|
||||
htons(port),
|
||||
sin_addr:
|
||||
{ s_addr: INADDR_ANY }
|
||||
};
|
||||
bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr));
|
||||
AssertFatal(listen(listen_sock, 5) == 0, "");
|
||||
return accept(listen_sock,NULL,NULL);
|
||||
}
|
||||
|
||||
int client_start(char *IP, short port) {
|
||||
int sock;
|
||||
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
|
||||
struct sockaddr_in addr = {
|
||||
sin_family:
|
||||
AF_INET,
|
||||
sin_port:
|
||||
htons(port),
|
||||
sin_addr:
|
||||
{ s_addr: INADDR_ANY }
|
||||
};
|
||||
addr.sin_addr.s_addr = inet_addr(IP);
|
||||
bool connected=false;
|
||||
|
||||
while(!connected) {
|
||||
LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", IP, port);
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
|
||||
LOG_I(HW,"rfsimulator: connection established\n");
|
||||
connected=true;
|
||||
}
|
||||
|
||||
perror("simulated node");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
enum blocking_t {
|
||||
notBlocking,
|
||||
blocking
|
||||
};
|
||||
|
||||
void setblocking(int sock, enum blocking_t active) {
|
||||
int opts;
|
||||
AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,"");
|
||||
|
||||
if (active==blocking)
|
||||
opts = opts & ~O_NONBLOCK;
|
||||
else
|
||||
opts = opts | O_NONBLOCK;
|
||||
|
||||
AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, "");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc != 4) {
|
||||
printf("Need parameters: source file, server or destination IP, TCP port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int fd;
|
||||
AssertFatal((fd=open(argv[1],O_RDONLY)) != -1, "file: %s", argv[1]);
|
||||
off_t fileSize=lseek(fd, 0, SEEK_END);
|
||||
int serviceSock;
|
||||
|
||||
if (strcmp(argv[2],"server")==0) {
|
||||
serviceSock=server_start(atoi(argv[3]));
|
||||
} else {
|
||||
client_start(argv[2],atoi(argv[3]));
|
||||
}
|
||||
|
||||
samplesBlockHeader_t header;
|
||||
int bufSize=100000;
|
||||
void *buff=malloc(bufSize);
|
||||
|
||||
while (1) {
|
||||
//Rewind the file to loop on the samples
|
||||
if ( lseek(fd, 0, SEEK_CUR) >= fileSize )
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
// Read one block and send it
|
||||
setblocking(serviceSock, blocking);
|
||||
AssertFatal(read(fd,&header,sizeof(header)), "");
|
||||
fullwrite(serviceSock, &header, sizeof(header));
|
||||
int dataSize=sizeof(sample_t)*header.size*header.nbAnt;
|
||||
|
||||
if (dataSize>bufSize) {
|
||||
void * new_buff = realloc(buff, dataSize);
|
||||
if (new_buff == NULL) {
|
||||
free(buff);
|
||||
AssertFatal(1, "Could not reallocate");
|
||||
} else {
|
||||
buff = new_buff;
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(read(fd,buff,dataSize) == dataSize, "");
|
||||
fullwrite(serviceSock, buff, dataSize);
|
||||
// Purge incoming samples
|
||||
setblocking(serviceSock, notBlocking);
|
||||
|
||||
while(recv(serviceSock,buff, bufSize, MSG_DONTWAIT) > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t
|
||||
proc->subframe_rx = subframe_rx;
|
||||
|
||||
if (!oai_exit) {
|
||||
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
|
||||
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(ru_proc->frame_rx), T_INT(ru_proc->subframe_rx));
|
||||
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
|
||||
L1_proc->frame_rx = ru_proc->frame_rx;
|
||||
L1_proc->subframe_rx = ru_proc->subframe_rx;
|
||||
@@ -509,9 +509,9 @@ int wakeup_txfh(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,int frame_tx,int subfram
|
||||
if (((fp->frame_type == TDD) && (subframe_select(fp,proc->subframe_tx)==SF_UL))||
|
||||
(eNB->RU_list[ru_id]->state == RU_SYNC)||
|
||||
(eNB->RU_list[ru_id]->wait_cnt>0)){
|
||||
AssertFatal((pthread_mutex_lock(&proc->mutex_RUs))==0, "mutex_lock returns %d\n",ret);
|
||||
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs))==0, "mutex_lock returns %d\n",ret);
|
||||
proc->instance_cnt_RUs = 0;
|
||||
AssertFatal((pthread_mutex_unlock(&proc->mutex_RUs))==0, "mutex_unlock returns %d\n",ret);
|
||||
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs))==0, "mutex_unlock returns %d\n",ret);
|
||||
continue;//hacking only works when all RU_tx works on the same subframe #TODO: adding mask stuff
|
||||
}
|
||||
|
||||
|
||||
@@ -34,9 +34,11 @@
|
||||
#include "UTIL/OPT/opt.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
#include <dlfcn.h>
|
||||
static softmodem_params_t softmodem_params;
|
||||
char *parallel_config=NULL;
|
||||
char *worker_config=NULL;
|
||||
double snr_dB=25;
|
||||
|
||||
uint64_t get_softmodem_optmask(void) {
|
||||
return softmodem_params.optmask;
|
||||
|
||||
@@ -152,7 +152,6 @@
|
||||
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0}, \
|
||||
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
|
||||
{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \
|
||||
{"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \
|
||||
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
|
||||
{"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \
|
||||
}
|
||||
@@ -201,6 +200,7 @@
|
||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
|
||||
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
|
||||
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
|
||||
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \
|
||||
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
@@ -285,6 +285,7 @@ uint64_t get_pdcp_optmask(void);
|
||||
extern pthread_cond_t sync_cond;
|
||||
extern pthread_mutex_t sync_mutex;
|
||||
extern int sync_var;
|
||||
extern double snr_dB;
|
||||
|
||||
|
||||
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
@@ -132,8 +132,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
int UE_scan = 1;
|
||||
int UE_scan_carrier = 0;
|
||||
|
||||
int snr_dB=25;
|
||||
|
||||
runmode_t mode = normal_txrx;
|
||||
|
||||
FILE *input_fd=NULL;
|
||||
@@ -813,7 +811,7 @@ int main( int argc, char **argv ) {
|
||||
//p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
|
||||
|
||||
if (IS_SOFTMODEM_SIML1 ) {
|
||||
init_ocm((double)snr_dB,0);
|
||||
init_ocm(snr_dB,0);
|
||||
PHY_vars_UE_g[0][0]->no_timing_correction = 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user