diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 9b365261725e9229c8063e93d1dc5eb8595ad895..401198df515f216fbeafdbff7683a6169bdce4f5 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -28,6 +28,7 @@ cmake_minimum_required (VERSION 2.8) ################################################ set (OPENAIR_DIR $ENV{OPENAIR_DIR}) set (NFAPI_DIR $ENV{NFAPI_DIR}) +set (NFAPI_USER_DIR ${OPENAIR_DIR}/nfapi) set (OPENAIR1_DIR ${OPENAIR_DIR}/openair1) set (OPENAIR2_DIR ${OPENAIR_DIR}/openair2) set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3) @@ -738,7 +739,12 @@ else() include_directories("${OPENAIR2_DIR}/UTIL") include_directories("${OPENAIR2_DIR}/UTIL/LOG") endif() -include_directories("${NFAPI_DIR}") +include_directories("${NFAPI_DIR}/nfapi/public_inc") +include_directories("${NFAPI_DIR}/common/public_inc") +include_directories("${NFAPI_DIR}/pnf/public_inc") +include_directories("${NFAPI_DIR}/nfapi/inc") +include_directories("${NFAPI_DIR}/sim_common/inc") +include_directories("${NFAPI_DIR}/pnf_sim/inc") include_directories("${OPENAIR1_DIR}") include_directories("${OPENAIR2_DIR}/NAS") include_directories("${OPENAIR2_DIR}") @@ -980,6 +986,58 @@ set(SCHED_SRC ) add_library(SCHED_LIB ${SCHED_SRC}) +# nFAPI +################################# +set(NFAPI_COMMON_SRC + ${NFAPI_DIR}/common/src/debug.c +) +add_library(NFAPI_COMMON_LIB ${NFAPI_COMMON_SRC}) + +include_directories(${NFAPI_DIR}/common/public_inc) + +set(NFAPI_SRC + ${NFAPI_DIR}/nfapi/src/nfapi.c + ${NFAPI_DIR}/nfapi/src/nfapi_p4.c + ${NFAPI_DIR}/nfapi/src/nfapi_p5.c + ${NFAPI_DIR}/nfapi/src/nfapi_p7.c +) +add_library(NFAPI_LIB ${NFAPI_SRC}) + +include_directories(${NFAPI_DIR}/nfapi/public_inc) +include_directories(${NFAPI_DIR}/nfapi/inc) + +set(NFAPI_PNF_SRC + ${NFAPI_DIR}/pnf/src/pnf.c + ${NFAPI_DIR}/pnf/src/pnf_interface.c + ${NFAPI_DIR}/pnf/src/pnf_p7.c + ${NFAPI_DIR}/pnf/src/pnf_p7_interface.c +) +add_library(NFAPI_PNF_LIB ${NFAPI_PNF_SRC}) + +include_directories(${NFAPI_DIR}/pnf/public_inc) +include_directories(${NFAPI_DIR}/pnf/inc) + +set(NFAPI_VNF_SRC + ${NFAPI_DIR}/vnf/src/vnf.c + ${NFAPI_DIR}/vnf/src/vnf_interface.c + ${NFAPI_DIR}/vnf/src/vnf_p7.c + ${NFAPI_DIR}/vnf/src/vnf_p7_interface.c +) +add_library(NFAPI_VNF_LIB ${NFAPI_VNF_SRC}) + +include_directories(${NFAPI_DIR}/vnf/public_inc) +include_directories(${NFAPI_DIR}/vnf/inc) + +# nFAPI user defined code +############################# +set(NFAPI_USER_SRC +${NFAPI_USER_DIR}/nfapi.c +${NFAPI_USER_DIR}/nfapi_pnf.c +${NFAPI_USER_DIR}/nfapi_vnf.c +) +add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC}) +include_directories(${NFAPI_USER_DIR}) + # Layer 1 ############################# set(PHY_SRC @@ -1175,6 +1233,8 @@ add_library(L2 ${ENB_APP_SRC}) # ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) +include_directories(${NFAPI_USER_DIR}) + if (FLEXRAN_AGENT_SB_IF) #Test for adding a shared library @@ -1588,6 +1648,13 @@ add_library(OPENAIR0_LIB ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c ) +include_directories("${NFAPI_DIR}/nfapi/public_inc") +include_directories("${NFAPI_DIR}/common/public_inc") +include_directories("${NFAPI_DIR}/pnf/public_inc") +include_directories("${NFAPI_DIR}/nfapi/inc") +include_directories("${NFAPI_DIR}/sim_common/inc") +include_directories("${NFAPI_DIR}/pnf_sim/inc") + # System packages that are required # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ # or cmake provide a generic interface to pkg-config that widely used @@ -1643,6 +1710,26 @@ endif() add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") +#pkg_search_module(NFAPI nfapi) +#if(NOT ${NFAPI_FOUND}) + #message( FATAL_ERROR "PACKAGE nfapi not found: some targets will fail. Run build_oai -I again!") +#else() + #include_directories(${NFAPI_INCLUDE_DIRS}) + #message( "PACKAGE nfapi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + #message( "${NFAPI_INCLUDE_DIR}") + #message( "${NFAPI_COMMON_INCLUDE_DIR}") + #message( "${NFAPI_VNF_INCLUDE_DIR}") + #message( "${NFAPI_PNF_INCLUDE_DIR}") + #message( "XXX") + #message( "${NFAPI_LIBRARY}") + #message( "${NFAPI_COMMON_LIBRARY}") + #message( "${NFAPI_PNF_LIBRARY}") + #message( "XXX") + #message( "${NFAPI_LIBRARIES}") + #message( "XXX") +#endif() + + pkg_search_module(XPM xpm) if(NOT ${XPM_FOUND}) message("PACKAGE xpm not found: some targets will fail") @@ -1682,6 +1769,12 @@ if (${T_TRACER}) set (T_LIB "rt") endif (${T_TRACER}) +#if (${NFAPI_DIR}) +#set (NFAPI_PNF_LIB "nfapi_pnf") +#set (NFAPI_LIB "nfapi") +#set (NFAPI_COMMON_LIB "nfapi_common") +#endif (${NFAPI_DIR}) +# #Some files in the T directory are generated. #This rule and the following deal with it. add_custom_command ( @@ -1740,6 +1833,9 @@ add_executable(lte-softmodem target_link_libraries (lte-softmodem -ldl -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB + NFAPI_USER_LIB + z -Wl,--end-group ) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) @@ -1858,22 +1954,44 @@ add_executable(oaisim ${T_SOURCE} ) +#add_library( imp_nfapi STATIC IMPORTED) +#set_property(TARGET imp_nfapi PROPERTY IMPORTED_LOCATION ${NFAPI_DIR}/libnfapi.a) +#set_property(TARGET imp_nfapi PROPERTY IMPORTED_IMPLIB ${NFAPI_DIR}/libnfapi.a) +#target_link_libraries(oaisim imp_nfapi) + +#add_library( imp_nfapi_common STATIC IMPORTED) +#set_property(TARGET imp_nfapi_common PROPERTY IMPORTED_LOCATION ${NFAPI_DIR}/common/libnfapi_common.a) +#set_property(TARGET imp_nfapi_common PROPERTY IMPORTED_IMPLIB ${NFAPI_DIR}/common/libnfapi_common.a) +#target_link_libraries(oaisim imp_nfapi_common) + +#add_library( imp_nfapi_pnf STATIC IMPORTED) +#set_property(TARGET imp_nfapi_pnf PROPERTY IMPORTED_LOCATION ${NFAPI_DIR}/pnf/libnfapi_pnf.a) +#set_property(TARGET imp_nfapi_pnf PROPERTY IMPORTED_IMPLIB ${NFAPI_DIR}/pnf/libnfapi_pnf.a) +#target_link_libraries(oaisim imp_nfapi_pnf) + +# +#add_library (imp_nfapi_common STATIC IMPORTED) +#set_target_properties(imp_nfapi_common PROPERTIES IMPORTED_LOCATION ${NFAPI_DIR}/common/libnfapi_common.a +#set_target_properties(oaisim PROPERTIES LINK_FLAGS ${NFAPI_DIR}/nfapi/libnfapi.a ${NFAPI_DIR}/pnf/libnfapi_pnf.a ${NFAPI_DIR}/common/libnfapi_common.a) + + target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim -Wl,-ldl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB + NFAPI_USER_LIB -Wl,--end-group ) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) -target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp - ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) +target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp z + ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} ) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim forms) target_link_libraries (oaisim ${T_LIB}) - # A all in one network simulator ################ add_executable(oaisim_nos1 diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 8ed9726e0fc5c7aec937ecae7e771da7c4bb2c83..2877133306447530ea33812699242a0ffa2579b5 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -187,7 +187,7 @@ function main() { GDB=1 CMAKE_BUILD_TYPE="Debug" echo_info "Will Compile with gdb symbols and disable compiler optimization" - CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug" + CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug --trace-expand" shift;; --eNB) eNB=1 diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index a57040449c7223d191be4df7c928ed036b4e5d62..8157d8b705bfbbe3ad36179de24463a10fa35680 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -205,6 +205,7 @@ install_protobuf_c_from_source(){ rm -rf /tmp/protobuf-c git clone https://github.com/protobuf-c/protobuf-c.git cd protobuf-c + git checkout 2a46af42784abf86804d536f6e0122d47cfeea45 ./autogen.sh ./configure echo "Compiling protobuf-c" diff --git a/nfapi/nfapi.c b/nfapi/nfapi.c new file mode 100644 index 0000000000000000000000000000000000000000..4bae644c5f740c6e980ecd71e38f6709da7cc781 --- /dev/null +++ b/nfapi/nfapi.c @@ -0,0 +1,693 @@ + +//#include "fapi_stub.h" +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ifaddrs.h> +#include <netdb.h> +#include <pthread.h> +#include <unistd.h> + +#if 0 +#if 0 +//DJP +#include <mutex> +#include <queue> +#include <list> +#endif + +//DJP struct phy_pdu +typedef struct +{ +#if 0 + phy_pdu() : buffer_len(1500), buffer(0), len(0) + { + buffer = (char*) malloc(buffer_len); + } + + virtual ~phy_pdu() + { + free(buffer); + } +#endif + + unsigned buffer_len; + char* buffer; + unsigned len; +} phy_pdu; + +// DJP class fapi_private +typedef struct +{ + //std::mutex mutex; + //std::queue<phy_pdu*> rx_buffer; + + //std::queue<phy_pdu*> free_store; +#if 0 + public: + + fapi_private() + : byte_count(0), tick(0), first_dl_config(false) + { + } + + phy_pdu* allocate_phy_pdu() + { + phy_pdu* pdu = 0; + mutex.lock(); + if(free_store.empty()) + { + pdu = new phy_pdu(); + } + else + { + pdu = free_store.front(); + free_store.pop(); + } + mutex.unlock(); + return pdu; + } + + void release_phy_pdu(phy_pdu* pdu) + { + mutex.lock(); + free_store.push(pdu); + mutex.unlock(); + } + + bool rx_buffer_empty() + { + bool empty; + mutex.lock(); + empty = rx_buffer.empty(); + mutex.unlock(); + + return empty; + } + + + void push_rx_buffer(phy_pdu* buff) + { + mutex.lock(); + rx_buffer.push(buff); + mutex.unlock(); + } + + phy_pdu* pop_rx_buffer() + { + phy_pdu* buff = 0; + mutex.lock(); + if(!rx_buffer.empty()) + { + buff = rx_buffer.front(); + rx_buffer.pop(); + } + mutex.unlock(); + return buff; + } +#endif + + uint32_t byte_count; + uint32_t tick; + uint8_t first_dl_config; + +} fapi_private ; + +#if defined(__cplusplus) +extern "C" +{ +#endif + typedef struct fapi_internal + { + fapi_t _public; + + fapi_cb_t callbacks; + + uint8_t state; + fapi_config_t config; + + int rx_sock; + int tx_sock; + struct sockaddr_in tx_addr; + + uint32_t tx_byte_count; + uint32_t tick; + + fapi_private* fapi; + + } fapi_internal_t; +#if defined(__cplusplus) +} +#endif + +#if 0 +//DJP +void send_uplink_indications(fapi_internal_t* instance, uint16_t sfn_sf) +{ + fapi_harq_ind_t harq_ind; + (instance->callbacks.fapi_harq_ind)(&(instance->_public), &harq_ind); + + fapi_crc_ind_t crc_ind; + crc_ind.header.message_id = FAPI_CRC_INDICATION; + crc_ind.header.length = 0; //??; + crc_ind.sfn_sf = sfn_sf; + crc_ind.body.number_of_crcs = 1; + crc_ind.body.pdus[0].rx_ue_info.handle = 0; //?? + crc_ind.body.pdus[0].rx_ue_info.rnti = 0; //?? + crc_ind.body.pdus[0].rel8_pdu.crc_flag = 1; + + (instance->callbacks.fapi_crc_ind)(&(instance->_public), &crc_ind); + + if(!instance->fapi->rx_buffer_empty()) + { + fapi_rx_ulsch_ind_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; + rx_ind.sfn_sf = sfn_sf; + + + phy_pdu* buff = 0; + int i = 0; + std::list<phy_pdu*> free_list; + do + { + buff = instance->fapi->pop_rx_buffer(); + if(buff != 0) + { + if(buff->len == 0) + { + printf("[FAPI] Buffer length = 0\n"); + } + + rx_ind.body.pdus[i].rx_ue_info.handle = 0xDEADBEEF; + rx_ind.body.pdus[i].rx_ue_info.rnti = 0x4242; + + rx_ind.body.pdus[i].rel8_pdu.length = buff->len; + //rx_ind.pdus[i].rel8_pdu.data_offset; + //rx_ind.pdus[i].rel8_pdu.ul_cqi; + //rx_ind.pdus[i].rel8_pdu.timing_advance; + + rx_ind.body.data[i] = buff->buffer; + + rx_ind.body.number_of_pdus++; + i++; + + instance->fapi->byte_count += buff->len; + + free_list.push_back(buff); + } + }while(buff != 0 && i < 8); + + (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); + + for(phy_pdu* pdu : free_list) + { + instance->fapi->release_phy_pdu(pdu); + //free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data); + } + } + else + { + fapi_rx_ulsch_ind_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; + rx_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); + } + + + fapi_rx_cqi_ind_t cqi_ind; + cqi_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_cqi_ind)(&(instance->_public), &cqi_ind); + + fapi_rx_sr_ind_t sr_ind; + sr_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_sr_ind)(&(instance->_public), &sr_ind); + + fapi_rach_ind_t rach_ind; + rach_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rach_ind)(&(instance->_public), &rach_ind); + + fapi_srs_ind_t srs_ind; + srs_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_srs_ind)(&(instance->_public), &srs_ind); + /* + nfapi_lbt_dl_indication_t lbt_ind; + memset(&lbt_ind, 0, sizeof(lbt_ind)); + lbt_ind.header.message_id = NFAPI_LBT_DL_INDICATION; + lbt_ind.header.phy_id = config->phy_id; + lbt_ind.sfn_sf = sfn_sf; + nfapi_pnf_p7_lbt_dl_ind(config, &lbt_ind); + + vendor_ext_p7_ind ve_p7_ind; + memset(&ve_p7_ind, 0, sizeof(ve_p7_ind)); + ve_p7_ind.header.message_id = P7_VENDOR_EXT_IND; + ve_p7_ind.header.phy_id = config->phy_id; + ve_p7_ind.error_code = NFAPI_MSG_OK; + nfapi_pnf_p7_vendor_extension(config, &(ve_p7_ind.header)); + */ + + fapi_nb_harq_ind_t nb_harq_ind; + nb_harq_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_nb_harq_ind)(&(instance->_public), &nb_harq_ind); + + fapi_nrach_ind_t nrach_ind; + nrach_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_nrach_ind)(&(instance->_public), &nrach_ind); + +} +#endif + +#if 0 +void* fapi_thread_start(void* ptr) +{ + set_thread_priority(81); + + fapi_internal_t* instance = (fapi_internal_t*)ptr; + uint16_t sfn_sf_dec = 0; + uint32_t last_tv_usec = 0; + uint32_t last_tv_sec = 0; + + uint32_t millisec; + uint32_t last_millisec = -1; + uint16_t catchup = 0; + + while(1) + { + // get the time + struct timeval sf_start; + (void)gettimeofday(&sf_start, NULL); + + uint16_t sfn_sf = ((((sfn_sf_dec) / 10) << 4) | (((sfn_sf_dec) - (((sfn_sf_dec) / 10) * 10)) & 0xF)); + // increment the sfn/sf - for the next subframe + sfn_sf_dec++; + if(sfn_sf_dec > 10239) + sfn_sf_dec = 0; + + + fapi_subframe_ind_t ind; + ind.sfn_sf = sfn_sf; + + if(instance->fapi->first_dl_config) + { + //DJP send_uplink_indications(instance, sfn_sf); + } + + if(instance->tick == 1000) + { + if(instance->tx_byte_count > 0) + { + printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count); + instance->tx_byte_count = 0; + } + + instance->tick = 0; + } + + instance->tick++; + + (instance->callbacks.fapi_subframe_ind)(&(instance->_public), &ind); + + { + //DJP phy_pdu* pdu = instance->fapi->allocate_phy_pdu(); + phy_pdu* pdu = (phy_pdu*)malloc(sizeof(phy_pdu)); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, MSG_DONTWAIT, 0, 0); + if(len > 0) + { + pdu->len = len; + //DJP instance->fapi->push_rx_buffer(pdu); + } + else + { + //DJP instance->fapi->release_phy_pdu(pdu); + } + } + + + if(catchup) + { + catchup--; + } + else + { + struct timespec now_ts; + struct timespec sleep_ts; + struct timespec sleep_rem_ts; + + // get the current time + clock_gettime(CLOCK_MONOTONIC, &now_ts); + + + // determine how long to sleep before the start of the next 1ms + sleep_ts.tv_sec = 0; + sleep_ts.tv_nsec = 1e6 - (now_ts.tv_nsec % 1000000); + + int nanosleep_result = nanosleep(&sleep_ts, &sleep_rem_ts); + + if(nanosleep_result != 0) + printf("*** nanosleep failed or was interrupted\n"); + + + clock_gettime(CLOCK_MONOTONIC, &now_ts); + millisec = now_ts.tv_nsec / 1e6; + + if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) + { + printf("*** missing millisec %d %d\n", last_millisec, millisec); + catchup = millisec - last_millisec - 1; + } + + last_millisec = millisec; + } + } +} +#endif + +#if defined(__cplusplus) +extern "C" { +#endif +#if 0 + fapi_t* fapi_create(fapi_cb_t* callbacks, fapi_config_t* config) + { + fapi_internal_t* instance = (fapi_internal_t*)calloc(1, sizeof(fapi_internal_t)); + instance->callbacks = *callbacks; + instance->config = *config; + instance->state = 0; + + // DJP instance->fapi = new fapi_private(); + instance->fapi = (fapi_t*)malloc(sizeof(fapi_private)); + + return (fapi_t*)instance; + } +#endif + +#if 0 + void fapi_destroy(fapi_t* fapi) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + //DJP delete instance->fapi; + free(instance); + } +#endif + +#if 0 + void* fapi_rx_thread_start(void* ptr) + { + set_thread_priority(60); + + fapi_internal_t* instance = (fapi_internal_t*)ptr; + + while(1) + { + //DJP phy_pdu* pdu = instance->fapi->allocate_phy_pdu(); + phy_pdu* pdu = (phy_pdu*)malloc(sizeof(phy_pdu)); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0); + if(len > 0) + { + pdu->len = len; + //instance->fapi->push_rx_buffer(pdu); + } + else + { + //instance->fapi->release_phy_pdu(pdu); + } + + } + } +#endif + +#if 0 + void fapi_start_data(fapi_t* fapi, unsigned rx_port, const char* tx_address, unsigned tx_port) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + printf("[FAPI] Rx Data from %d\n", rx_port); + printf("[FAPI] Tx Data to %s:%d\n", tx_address, tx_port); + + instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0); + + if(instance->rx_sock < 0) + { + printf("[FAPI] Failed to create socket\n"); + return; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(rx_port); + addr.sin_addr.s_addr = INADDR_ANY; + + int bind_result = bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); + + if(bind_result == -1) + { + printf("[FAPI] Failed to bind to port %d\n", rx_port); + close(instance->rx_sock); + return ; + } + + instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0); + instance->tx_addr.sin_family = AF_INET; + instance->tx_addr.sin_port = htons(tx_port); + instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address); + } +#endif + + + void fill_tlv(fapi_tlv_t tlvs[], uint8_t count, uint8_t tag, uint8_t len, uint16_t value) + { + tlvs[count].tag = tag; + tlvs[count].value = value; + tlvs[count].length = len; + } + +#if 0 + int fapi_param_request(fapi_t* fapi, fapi_param_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + fapi_param_resp_t resp; + resp.header.message_id = FAPI_PARAM_RESPONSE; + + resp.error_code = FAPI_MSG_OK; + + resp.number_of_tlvs = 0; + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_STATE_TAG, 2, instance->state); +#if 0 +//DJP + if(instance->state == 0) + { + if(instance->config.duplex_mode == 0) + { + // -- TDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + } + else if(instance->config.duplex_mode == 1) + { + // -- FDD + // Downlink Bandwidth Support + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.dl_channel_bw_support); + // Uplink Bandwidth Support + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.ul_channel_bw_support); + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // LAA Capability + } + } + else + { + if(instance->config.duplex_mode == 0) + { + // -- TDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // Duplexing Mode + // PCFICH Power Offset + // P-B + // DL Cyclic Prefix Type + // UL Cyclic Prefix Type + // RF Config + // PHICH Config + // SCH Config + // PRACH Config + // PUSCH Config + // PUCCH Config + // SRS Config + // Uplink Reference Signal Config + // TDD Frame Structure Config + // Data Report Mode + } + else if(instance->config.duplex_mode == 1) + { + // FDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // LAA Capability + // Duplexing Mode + // PCFICH Power Offset + // P-B + // DL Cyclic Prefix Type + // UL Cyclic Prefix Type + // RF Config + // PHICH Config + // SCH Config + // PRACH Config + // PUSCH Config + // PUCCH Config + // SRS Config + // Uplink Reference Signal Config + // Data Report Mode + } + } +#endif + + + //todo fill + (instance->callbacks.fapi_param_response)(fapi, &resp); + + return 0; + } +#endif + +#if 0 + int fapi_config_request(fapi_t* fapi, fapi_config_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + fapi_config_resp_t resp; + resp.header.message_id = FAPI_CONFIG_RESPONSE; + resp.error_code = FAPI_MSG_OK; + + (instance->callbacks.fapi_config_response)(fapi, &resp); + return 0; + } +#endif + +#if 0 + int fapi_start_request(fapi_t* fapi, fapi_start_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + pthread_t fapi_thread; + pthread_create(&fapi_thread, NULL, &fapi_thread_start, instance); + + return 0; + } +#endif + +#if 0 + int fapi_dl_config_request(fapi_t* fapi, fapi_dl_config_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + //DJP instance->fapi->first_dl_config = true; + instance->fapi->first_dl_config = 1; + + return 0; + } +#endif + +#if 0 + int fapi_ul_config_request(fapi_t* fapi, fapi_ul_config_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + return 0; + } +#endif +#if 0 + int fapi_hi_dci0_request(fapi_t* fapi, fapi_hi_dci0_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + return 0; + } +#endif +#if 0 + int fapi_tx_request(fapi_t* fapi, fapi_tx_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + for(int i = 0; i < req->body.number_of_pdus; ++i) + { + uint16_t len = req->body.pdus[i].pdu_length; + uint32_t* data = req->body.pdus[i].tlvs[0].value; + //printf("[FAPI] sfnsf:%d len:%d\n", req->sfn_sf,len); + // + instance->tx_byte_count += len; + + int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr*)&(instance->tx_addr), sizeof(instance->tx_addr)); + + if(sendto_result == -1) + { + // error + } + } + + return 0; + } +#endif + +#if defined(__cplusplus) +} +#endif +#endif + + + +void set_thread_priority(int priority) +{ + //printf("%s(priority:%d)\n", __FUNCTION__, priority); + + pthread_attr_t ptAttr; + + struct sched_param schedParam; + schedParam.__sched_priority = priority; //79; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) + { + printf("Failed to set scheduler to SCHED_RR\n"); + } + + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) + { + printf("Failed to set pthread sched policy SCHED_RR\n"); + } + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + + struct sched_param thread_params; + thread_params.sched_priority = 20; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) + { + printf("failed to set sched param\n"); + } +} + diff --git a/nfapi/nfapi_pnf.c b/nfapi/nfapi_pnf.c new file mode 100644 index 0000000000000000000000000000000000000000..7009833ecca5db031b7ed2f3afae3bb9f08d2804 --- /dev/null +++ b/nfapi/nfapi_pnf.c @@ -0,0 +1,1985 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#include "debug.h" +#include "nfapi_pnf_interface.h" +#include "nfapi.h" +#include "nfapi_pnf.h" +#include "common/ran_context.h" +//#include "openair1/PHY/vars.h" +extern RAN_CONTEXT_t RC; + +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <assert.h> +#include <arpa/inet.h> +#include <pthread.h> +#include <errno.h> + +#include <vendor_ext.h> +#include "fapi_stub.h" + +#if 0 +#include "pool.h" + +#include <mutex> +#include <list> +#include <queue> +#include <map> +#include <vector> +#include <algorithm> +#include <stdlib.h> +#endif + +#define NUM_P5_PHY 2 + +uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 }; + +nfapi_pnf_param_response_t g_pnf_param_resp; + + +nfapi_pnf_p7_config_t *p7_config_g = NULL; + +void* pnf_allocate(size_t size) +{ + //DJP + //return (void*)memory_pool::allocate(size); + return malloc(size); +} + +void pnf_deallocate(void* ptr) +{ + //DJP + //memory_pool::deallocate((uint8_t*)ptr); + free(ptr); +} + + +//class udp_data +//DJP +typedef struct +{ + //public: + uint8_t enabled; + uint32_t rx_port; + uint32_t tx_port; + //std::string tx_addr; + char tx_addr[80]; +}udp_data; + +//class phy_info +//DJP +typedef struct +{ +#if 0 + public: + + phy_info() + : first_subframe_ind(0), fapi(0), + dl_ues_per_subframe(0), ul_ues_per_subframe(0), + timing_window(0), timing_info_mode(0), timing_info_period(0) + { + index = 0; + id = 0; + + local_port = 0; + remote_addr = 0; + remote_port = 0; + + duplex_mode = 0; + dl_channel_bw_support = 0; + ul_channel_bw_support = 0; + num_dl_layers_supported = 0; + num_ul_layers_supported = 0; + release_supported = 0; + nmm_modes_supported = 0; + } +#endif + + uint16_t index; + uint16_t id; + //std::vector<uint8_t> rfs; + //std::vector<uint8_t> excluded_rfs; + uint8_t rfs[2]; + uint8_t excluded_rfs[2]; + + udp_data udp; + + //std::string local_addr; + char local_addr[80]; + int local_port; + + char* remote_addr; + int remote_port; + + uint8_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; + uint8_t num_dl_layers_supported; + uint8_t num_ul_layers_supported; + uint16_t release_supported; + uint8_t nmm_modes_supported; + + uint8_t dl_ues_per_subframe; + uint8_t ul_ues_per_subframe; + + uint8_t first_subframe_ind; + + // timing information recevied from the vnf + uint8_t timing_window; + uint8_t timing_info_mode; + uint8_t timing_info_period; + + //fapi_t* fapi; + +}phy_info; + +//class rf_info +//DJP +typedef struct +{ + //public: + uint16_t index; + uint16_t band; + int16_t max_transmit_power; + int16_t min_transmit_power; + uint8_t num_antennas_supported; + uint32_t min_downlink_frequency; + uint32_t max_downlink_frequency; + uint32_t max_uplink_frequency; + uint32_t min_uplink_frequency; +}rf_info; + + +//class pnf_info +//DJP +typedef struct +{ +#if 0 + public: + + pnf_info() + : release(13), wireshark_test_mode(0), + max_total_power(0), oui(0) + + { + release = 0; + + sync_mode = 0; + location_mode = 0; + dl_config_timing = 0; + ul_config_timing = 0; + tx_timing = 0; + hi_dci0_timing = 0; + + max_phys = 0; + max_total_bw = 0; + max_total_dl_layers = 0; + max_total_ul_layers = 0; + shared_bands = 0; + shared_pa = 0; + + } +#endif + + int release; + //DJPstd::vector<phy_info> phys; + //std::vector<rf_info> rfs; + phy_info phys[2]; + rf_info rfs[2]; + + uint8_t sync_mode; + uint8_t location_mode; + uint8_t location_coordinates[6]; + uint32_t dl_config_timing; + uint32_t ul_config_timing; + uint32_t tx_timing; + uint32_t hi_dci0_timing; + + uint16_t max_phys; + uint16_t max_total_bw; + uint16_t max_total_dl_layers; + uint16_t max_total_ul_layers; + uint8_t shared_bands; + uint8_t shared_pa; + int16_t max_total_power; + uint8_t oui; + + uint8_t wireshark_test_mode; + +}pnf_info; + +// DJP struct pnf_phy_user_data_t +typedef struct +{ + uint16_t phy_id; + nfapi_pnf_config_t* config; + phy_info* phy; + nfapi_pnf_p7_config_t* p7_config; +}pnf_phy_user_data_t; + +//DJP int read_pnf_xml(pnf_info& pnf, const char* xml_file) +int read_pnf_xml(pnf_info* pnf, const char* xml_file) +{ +#if 0 + try + { + std::ifstream input(xml_file); + + using boost::property_tree::ptree; + ptree pt; + + read_xml(input, pt); + + pnf.wireshark_test_mode = pt.get<unsigned>("pnf.wireshark_test_mode", 0); + + + pnf.sync_mode = pt.get<unsigned>("pnf.sync_mode"); + pnf.location_mode= pt.get<unsigned>("pnf.location_mode"); + //pnf.sync_mode = pt.get<unsigned>("pnf.location_coordinates"); + + pnf.dl_config_timing= pt.get<unsigned>("pnf.dl_config_timing"); + pnf.ul_config_timing = pt.get<unsigned>("pnf.ul_config_timing"); + pnf.tx_timing = pt.get<unsigned>("pnf.tx_timing"); + pnf.hi_dci0_timing = pt.get<unsigned>("pnf.hi_dci0_timing"); + + pnf.max_phys = pt.get<unsigned>("pnf.max_phys"); + pnf.max_total_bw = pt.get<unsigned>("pnf.max_total_bandwidth"); + pnf.max_total_dl_layers = pt.get<unsigned>("pnf.max_total_num_dl_layers"); + pnf.max_total_ul_layers = pt.get<unsigned>("pnf.max_total_num_ul_layers"); + + pnf.shared_bands = pt.get<unsigned>("pnf.shared_bands"); + pnf.shared_pa = pt.get<unsigned>("pnf.shared_pas"); + + pnf.max_total_power = pt.get<signed>("pnf.maximum_total_power"); + + //"oui"); + + for(const auto& v : pt.get_child("pnf.phys")) + { + if(v.first == "phy") + { + phy_info phy; + + + + phy.index = v.second.get<unsigned>("index"); + phy.local_port = v.second.get<unsigned>("port"); + phy.local_addr = v.second.get<std::string>("address"); + phy.duplex_mode = v.second.get<unsigned>("duplex_mode"); + + phy.dl_channel_bw_support = v.second.get<unsigned>("downlink_channel_bandwidth_support"); + phy.ul_channel_bw_support = v.second.get<unsigned>("uplink_channel_bandwidth_support"); + phy.num_dl_layers_supported = v.second.get<unsigned>("number_of_dl_layers"); + phy.num_ul_layers_supported = v.second.get<unsigned>("number_of_ul_layers"); + phy.release_supported = v.second.get<unsigned>("3gpp_release_supported"); + phy.nmm_modes_supported = v.second.get<unsigned>("nmm_modes_supported"); + + for(const auto& v2 : v.second.get_child("rfs")) + { + if(v2.first == "index") + phy.rfs.push_back(v2.second.get_value<unsigned>()); + } + for(const auto& v2 : v.second.get_child("excluded_rfs")) + { + if(v2.first == "index") + phy.excluded_rfs.push_back(v2.second.get_value<unsigned>()); + } + + boost::optional<const boost::property_tree::ptree&> d = v.second.get_child_optional("data.udp"); + if(d.is_initialized()) + { + phy.udp.enabled = true; + phy.udp.rx_port = d.get().get<unsigned>("rx_port"); + phy.udp.tx_port = d.get().get<unsigned>("tx_port"); + phy.udp.tx_addr = d.get().get<std::string>("tx_addr"); + } + else + { + phy.udp.enabled = false; + } + + phy.dl_ues_per_subframe = v.second.get<unsigned>("dl_ues_per_subframe"); + phy.ul_ues_per_subframe = v.second.get<unsigned>("ul_ues_per_subframe"); + + pnf.phys.push_back(phy); + } + } + for(const auto& v : pt.get_child("pnf.rfs")) + { + if(v.first == "rf") + { + rf_info rf; + + rf.index = v.second.get<unsigned>("index"); + rf.band = v.second.get<unsigned>("band"); + rf.max_transmit_power = v.second.get<signed>("max_transmit_power"); + rf.min_transmit_power = v.second.get<signed>("min_transmit_power"); + rf.num_antennas_supported = v.second.get<unsigned>("num_antennas_supported"); + rf.min_downlink_frequency = v.second.get<unsigned>("min_downlink_frequency"); + rf.max_downlink_frequency = v.second.get<unsigned>("max_downlink_frequency"); + rf.min_uplink_frequency = v.second.get<unsigned>("max_uplink_frequency"); + rf.max_uplink_frequency = v.second.get<unsigned>("min_uplink_frequency"); + + pnf.rfs.push_back(rf); + } + } + } + catch(std::exception& e) + { + printf("%s", e.what()); + return -1; + } + catch(boost::exception& e) + { + printf("%s", boost::diagnostic_information(e).c_str()); + return -1; + } + +#endif + +#if 0 + pnf->phys[0].udp.enabled = 1; + pnf->phys[0].udp.rx_port = 50000; //DJP d.get().get<unsigned>("rx_port"); + pnf->phys[0].udp.tx_port = 50001; //DJP d.get().get<unsigned>("tx_port"); + strcpy(pnf->phys[0].udp.tx_addr, "127.0.0.2"); //DJP d.get().get<std::string>("tx_addr"); + printf("%s() DJP HARD CODED PHY UDP address port to %s rx:%d tx:%d\n", + __FUNCTION__, pnf->phys[0].udp.tx_addr, pnf->phys[0].udp.rx_port, pnf->phys[0].udp.tx_port); +#endif + + return 0; +} + +void pnf_sim_trace(nfapi_trace_level_t level, const char* message, ...) +{ + va_list args; + va_start(args, message); + vprintf(message, args); + va_end(args); +} + +void pnf_set_thread_priority(int priority) +{ + //printf("%s(priority:%d)\n", __FUNCTION__, priority); + + pthread_attr_t ptAttr; + + struct sched_param schedParam; + schedParam.__sched_priority = priority; //79; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) + { + printf("failed to set SCHED_RR\n"); + } + + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) + { + printf("failed to set pthread SCHED_RR %d\n", errno); + } + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + + struct sched_param thread_params; + thread_params.sched_priority = 20; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) + { + printf("failed to set sched param\n"); + } +} + +void* pnf_p7_thread_start(void* ptr) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P7 THREAD %s\n", __FUNCTION__); + + pnf_set_thread_priority(79); + + nfapi_pnf_p7_config_t* config = (nfapi_pnf_p7_config_t*)ptr; + nfapi_pnf_p7_start(config); + + return 0; +} + + + +int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req) +{ + printf("[PNF] pnf param request\n"); + + nfapi_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + + pnf_info* pnf = (pnf_info*)(config->user_data); + + resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG; + resp.pnf_param_general.nfapi_sync_mode = pnf->sync_mode; + resp.pnf_param_general.location_mode = pnf->location_mode; + //uint8_t location_coordinates[NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH]; + resp.pnf_param_general.dl_config_timing = pnf->dl_config_timing; + resp.pnf_param_general.tx_timing = pnf->tx_timing; + resp.pnf_param_general.ul_config_timing = pnf->ul_config_timing; + resp.pnf_param_general.hi_dci0_timing = pnf->hi_dci0_timing; + resp.pnf_param_general.maximum_number_phys = pnf->max_phys; + resp.pnf_param_general.maximum_total_bandwidth = pnf->max_total_bw; + resp.pnf_param_general.maximum_total_number_dl_layers = pnf->max_total_dl_layers; + resp.pnf_param_general.maximum_total_number_ul_layers = pnf->max_total_ul_layers; + resp.pnf_param_general.shared_bands = pnf->shared_bands; + resp.pnf_param_general.shared_pa = pnf->shared_pa; + resp.pnf_param_general.maximum_total_power = pnf->max_total_power; + //uint8_t oui[NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH]; + + resp.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG; + //DJP resp.pnf_phy.number_of_phys = pnf->phys.size(); + resp.pnf_phy.number_of_phys = 1; + + //for(int i = 0; i < pnf->phys.size(); ++i) + for(int i = 0; i < 1; ++i) + { + resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy.phy[i].downlink_channel_bandwidth_supported = pnf->phys[i].dl_channel_bw_support; + resp.pnf_phy.phy[i].uplink_channel_bandwidth_supported = pnf->phys[i].ul_channel_bw_support; + resp.pnf_phy.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; + resp.pnf_phy.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; + resp.pnf_phy.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; + resp.pnf_phy.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; + + //DJP resp.pnf_phy.phy[i].number_of_rfs = pnf->phys[i].rfs.size(); + resp.pnf_phy.phy[i].number_of_rfs = 2; + //for(int j = 0; j < pnf->phys[i].rfs.size(); ++j) + for(int j = 0; j < 1; ++j) + { + resp.pnf_phy.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; + } + + //DJP resp.pnf_phy.phy[i].number_of_rf_exclusions = pnf->phys[i].excluded_rfs.size(); + resp.pnf_phy.phy[i].number_of_rf_exclusions = 0; + //DJP for(int j = 0; j < pnf->phys[i].excluded_rfs.size(); ++j) + for(int j = 0; j < 0; ++j) + { + resp.pnf_phy.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; + } + } + + + resp.pnf_rf.tl.tag = NFAPI_PNF_RF_TAG; + //DJPresp.pnf_rf.number_of_rfs = pnf->rfs.size(); + resp.pnf_rf.number_of_rfs = 2; + + //for(int i = 0; i < pnf->rfs.size(); ++i) + for(int i = 0; i < 2; ++i) + { + resp.pnf_rf.rf[i].rf_config_index = pnf->rfs[i].index; + resp.pnf_rf.rf[i].band = pnf->rfs[i].band; + resp.pnf_rf.rf[i].maximum_transmit_power = pnf->rfs[i].max_transmit_power; + resp.pnf_rf.rf[i].minimum_transmit_power = pnf->rfs[i].min_transmit_power; + resp.pnf_rf.rf[i].number_of_antennas_suppported = pnf->rfs[i].num_antennas_supported; + resp.pnf_rf.rf[i].minimum_downlink_frequency = pnf->rfs[i].min_downlink_frequency; + resp.pnf_rf.rf[i].maximum_downlink_frequency = pnf->rfs[i].max_downlink_frequency; + resp.pnf_rf.rf[i].minimum_uplink_frequency = pnf->rfs[i].min_uplink_frequency; + resp.pnf_rf.rf[i].maximum_uplink_frequency = pnf->rfs[i].max_uplink_frequency; + } + + if(pnf->release >= 10) + { + resp.pnf_phy_rel10.tl.tag = NFAPI_PNF_PHY_REL10_TAG; + //DJPresp.pnf_phy_rel10.number_of_phys = pnf->phys.size(); + resp.pnf_phy_rel10.number_of_phys = 1; + + //for(int i = 0; i < pnf->phys.size(); ++i) + for(int i = 0; i < 1; ++i) + { + resp.pnf_phy_rel10.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel10.phy[i].transmission_mode_7_supported = 0; + resp.pnf_phy_rel10.phy[i].transmission_mode_8_supported = 1; + resp.pnf_phy_rel10.phy[i].two_antenna_ports_for_pucch = 0; + resp.pnf_phy_rel10.phy[i].transmission_mode_9_supported = 1; + resp.pnf_phy_rel10.phy[i].simultaneous_pucch_pusch = 0; + resp.pnf_phy_rel10.phy[i].four_layer_tx_with_tm3_and_tm4 = 1; + + } + } + + if(pnf->release >= 11) + { + resp.pnf_phy_rel11.tl.tag = NFAPI_PNF_PHY_REL11_TAG; + //DJP resp.pnf_phy_rel11.number_of_phys = pnf->phys.size(); + resp.pnf_phy_rel11.number_of_phys = 1; + + //DJP for(int i = 0; i < pnf->phys.size(); ++i) + for(int i = 0; i < 1; ++i) + { + resp.pnf_phy_rel11.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel11.phy[i].edpcch_supported = 0; + resp.pnf_phy_rel11.phy[i].multi_ack_csi_reporting = 1; + resp.pnf_phy_rel11.phy[i].pucch_tx_diversity = 0; + resp.pnf_phy_rel11.phy[i].ul_comp_supported = 1; + resp.pnf_phy_rel11.phy[i].transmission_mode_5_supported = 0; + } + } + + if(pnf->release >= 12) + { + resp.pnf_phy_rel12.tl.tag = NFAPI_PNF_PHY_REL12_TAG; + //DJP resp.pnf_phy_rel12.number_of_phys = pnf->phys.size(); + resp.pnf_phy_rel12.number_of_phys = 1; + + //DJP for(int i = 0; i < pnf->phys.size(); ++i) + for(int i = 0; i < 1; ++i) + { + resp.pnf_phy_rel12.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel12.phy[i].csi_subframe_set = 0; + resp.pnf_phy_rel12.phy[i].enhanced_4tx_codebook = 2; // yes this is invalid + resp.pnf_phy_rel12.phy[i].drs_supported = 0; + resp.pnf_phy_rel12.phy[i].ul_64qam_supported = 1; + resp.pnf_phy_rel12.phy[i].transmission_mode_10_supported = 0; + resp.pnf_phy_rel12.phy[i].alternative_bts_indices = 1; + } + } + + if(pnf->release >= 13) + { + resp.pnf_phy_rel13.tl.tag = NFAPI_PNF_PHY_REL13_TAG; + //DJP resp.pnf_phy_rel13.number_of_phys = pnf->phys.size(); + resp.pnf_phy_rel13.number_of_phys = 1; + + //for(int i = 0; i < pnf->phys.size(); ++i) + for(int i = 0; i < 1; ++i) + { + resp.pnf_phy_rel13.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel13.phy[i].pucch_format4_supported = 0; + resp.pnf_phy_rel13.phy[i].pucch_format5_supported = 1; + resp.pnf_phy_rel13.phy[i].more_than_5_ca_support = 0; + resp.pnf_phy_rel13.phy[i].laa_supported = 1; + resp.pnf_phy_rel13.phy[i].laa_ending_in_dwpts_supported = 0; + resp.pnf_phy_rel13.phy[i].laa_starting_in_second_slot_supported = 1; + resp.pnf_phy_rel13.phy[i].beamforming_supported = 0; + resp.pnf_phy_rel13.phy[i].csi_rs_enhancement_supported = 1; + resp.pnf_phy_rel13.phy[i].drms_enhancement_supported = 0; + resp.pnf_phy_rel13.phy[i].srs_enhancement_supported = 1; + } + + resp.pnf_phy_rel13_nb_iot.tl.tag = NFAPI_PNF_PHY_REL13_NB_IOT_TAG; + //DJP resp.pnf_phy_rel13_nb_iot.number_of_phys = pnf->phys.size(); + resp.pnf_phy_rel13_nb_iot.number_of_phys = 1; + + //for(int i = 0; i < pnf->phys.size(); ++i) + for(int i = 0; i < 1; ++i) + { + resp.pnf_phy_rel13_nb_iot.phy[i].phy_config_index = pnf->phys[i].index; + + //DJP resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rfs = pnf->phys[i].rfs.size(); + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rfs = 1; + //DJP for(int j = 0; j < pnf->phys[i].rfs.size(); ++j) + for(int j = 0; j < 1; ++j) + { + resp.pnf_phy_rel13_nb_iot.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; + } + + //DJP resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rf_exclusions = pnf->phys[i].excluded_rfs.size(); + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rf_exclusions = 1; + //DJP for(int j = 0; j < pnf->phys[i].excluded_rfs.size(); ++j) + for(int j = 0; j < 1; ++j) + { + resp.pnf_phy_rel13_nb_iot.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; + } + + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; + + } + } + + + nfapi_pnf_pnf_param_resp(config, &resp); + + return 0; +} + +int pnf_config_request(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req) +{ + printf("[PNF] pnf config request\n"); + + pnf_info* pnf = (pnf_info*)(config->user_data); + +#if 0 + for(int i = 0; i < req->pnf_phy_rf_config.number_phy_rf_config_info; ++i) + { + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.index == req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index; }); + + if(found != pnf->phys.end()) + { + phy_info& phy = (*found); + phy.id = req->pnf_phy_rf_config.phy_rf_config[i].phy_id; + printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy.id, req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index); + } + else + { + // did not find the phy + printf("[PNF] pnf config request did not find phy_config_index %d\n", req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index); + } + + } +#endif + //DJP + phy_info *phy = pnf->phys; + phy->id = req->pnf_phy_rf_config.phy_rf_config[0].phy_id; + printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy->id, req->pnf_phy_rf_config.phy_rf_config[0].phy_config_index); + //DJP + + nfapi_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_config_resp(config, &resp); + printf("[PNF] Sent pnf_config_resp\n"); + + return 0; +} + +int fapi_param_response(fapi_t* fapi, fapi_param_resp_t* resp) +{ + printf("[PNF] fapi param response\n"); + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_param_response_t nfapi_resp; + + printf("[PNF] fapi param response phy_id:%d number_of_tlvs:%u\n", data->phy_id, resp->number_of_tlvs); + + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_PARAM_RESPONSE; + nfapi_resp.header.phy_id = data->phy_id; + nfapi_resp.error_code = resp->error_code; + + for(int i = 0; i < resp->number_of_tlvs; ++i) + { + switch(resp->tlvs[i].tag) + { + case FAPI_PHY_STATE_TAG: + nfapi_resp.l1_status.phy_state.tl.tag = NFAPI_L1_STATUS_PHY_STATE_TAG; + nfapi_resp.l1_status.phy_state.value = resp->tlvs[i].value; + nfapi_resp.num_tlv++; + break; + + case FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG: + nfapi_resp.phy_capabilities.dl_bandwidth_support.tl.tag = NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG; + nfapi_resp.phy_capabilities.dl_bandwidth_support.value = resp->tlvs[i].value; + nfapi_resp.num_tlv++; + printf("%s() DL BW support %d\n", __FUNCTION__, nfapi_resp.phy_capabilities.dl_bandwidth_support.value); + break; + + case FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG: + nfapi_resp.phy_capabilities.ul_bandwidth_support.tl.tag = NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG; + nfapi_resp.phy_capabilities.ul_bandwidth_support.value = resp->tlvs[i].value; + nfapi_resp.num_tlv++; + break; + default: + printf("%s() %s:%d Unhandled TLV:%d\n", __FUNCTION__, __FILE__, __LINE__, resp->tlvs[i].tag); + break; + } + } + + { + //if(phy->state == NFAPI_PNF_PHY_IDLE) + //if(nfapi_resp.l1_status.phy_state.value == NFAPI_PNF_PHY_IDLE) + { + // -- NFAPI + // Downlink UEs per Subframe + nfapi_resp.nfapi_config.dl_ue_per_sf.tl.tag = NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG; + nfapi_resp.nfapi_config.dl_ue_per_sf.value = data->phy->dl_ues_per_subframe; + nfapi_resp.num_tlv++; + // Uplink UEs per Subframe + nfapi_resp.nfapi_config.ul_ue_per_sf.tl.tag = NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG; + nfapi_resp.nfapi_config.ul_ue_per_sf.value = data->phy->ul_ues_per_subframe; + nfapi_resp.num_tlv++; + // nFAPI RF Bands + nfapi_resp.nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; + nfapi_resp.nfapi_config.rf_bands.number_rf_bands = 2; + nfapi_resp.nfapi_config.rf_bands.rf_band[0] = 23; + nfapi_resp.nfapi_config.rf_bands.rf_band[1] = 7; + + // P7 PNF Address IPv4 + nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + struct sockaddr_in pnf_p7_sockaddr; + //DJP pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(data->phy->local_addr.c_str()); + + //DJP + strcpy(data->phy->local_addr, "192.168.1.74"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DJP HARD CODED IP ADDRESS to %s\n", __FUNCTION__, data->phy->local_addr); + data->phy->local_port = 32123; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DJP HARD CODED PORT to %d\n", __FUNCTION__, data->phy->local_port); + + + + + pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(data->phy->local_addr); + memcpy(&(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address[0]), &pnf_p7_sockaddr.sin_addr.s_addr, 4); + nfapi_resp.num_tlv++; + // P7 PNF Address IPv6 + // P7 PNF Port + nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; + nfapi_resp.nfapi_config.p7_pnf_port.value = data->phy->local_port; + nfapi_resp.num_tlv++; + // NMM GSM Frequency Bands + nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG; + nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands = 1; + nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.bands[0] = 23; + nfapi_resp.num_tlv++; + // NMM UMTS Frequency Bands + nfapi_resp.nfapi_config.nmm_umts_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG; + nfapi_resp.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands = 1; + nfapi_resp.nfapi_config.nmm_umts_frequency_bands.bands[0] = 23; + nfapi_resp.num_tlv++; + // NMM LTE Frequency Bands + nfapi_resp.nfapi_config.nmm_lte_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG; + nfapi_resp.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands = 1; + nfapi_resp.nfapi_config.nmm_lte_frequency_bands.bands[0] = 23; + nfapi_resp.num_tlv++; + // NMM Uplink RSSI supported + nfapi_resp.nfapi_config.nmm_uplink_rssi_supported.tl.tag = NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG; + nfapi_resp.nfapi_config.nmm_uplink_rssi_supported.value = 1; + nfapi_resp.num_tlv++; + + } + } + + nfapi_pnf_param_resp(data->config, &nfapi_resp); + + return 0; +} + +void nfapi_send_pnf_start_resp(nfapi_pnf_config_t* config, uint16_t phy_id) +{ + printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id); + + nfapi_start_response_t start_resp; + memset(&start_resp, 0, sizeof(start_resp)); + start_resp.header.message_id = NFAPI_START_RESPONSE; + start_resp.header.phy_id = phy_id; + start_resp.error_code = NFAPI_MSG_OK; + + nfapi_pnf_start_resp(config, &start_resp); +} + +int pnf_start_request(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req) +{ + printf("Received NFAPI_PNF_START_REQUEST\n"); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + // start all phys that have been configured + //for(phy_info& phy : pnf->phys) + phy_info* phy = pnf->phys; + if(phy->id != 0) + { + //auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + // { return item.id == req->header.phy_id; }); + // + // if(found != pnf->phys.end()) + // { + // phy_info& phy = (*found); + //} + + nfapi_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_START_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_start_resp(config, &resp); + printf("[PNF] Sent NFAPI_PNF_START_RESP\n"); + } + return 0; +} + +int pnf_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req) +{ + printf("[PNF] Received NFAPI_PNF_STOP_REQ\n"); + + nfapi_pnf_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_STOP_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_stop_resp(config, &resp); + printf("[PNF] Sent NFAPI_PNF_STOP_REQ\n"); + + return 0; +} + +int param_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req) +{ + printf("[PNF] Received NFAPI_PARAM_REQUEST phy_id:%d\n", req->header.phy_id); + + //pnf_info* pnf = (pnf_info*)(config->user_data); + + nfapi_param_response_t nfapi_resp; + + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_PARAM_RESPONSE; + nfapi_resp.header.phy_id = req->header.phy_id; + nfapi_resp.error_code = 0; // DJP - what value??? + + char local_addr[80]; + struct sockaddr_in pnf_p7_sockaddr; + + strcpy(local_addr, "192.168.1.74"); // DJP - hard code alert FIXME TODO + + pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(local_addr); + nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + memcpy(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address, &pnf_p7_sockaddr.sin_addr.s_addr, 4); + nfapi_resp.num_tlv++; + + // P7 PNF Port + nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; + nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; // DJP - hard code alert!!!! FIXME TODO + nfapi_resp.num_tlv++; + + nfapi_pnf_param_resp(config, &nfapi_resp); + + printf("[PNF] Sent NFAPI_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv); +#if 0 + //DJP + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.id == req->header.phy_id; }); + + if(found != pnf->phys.end()) +#endif + { + //DJP phy_info& phy_info = (*found); + //phy_info *phy_info = pnf->phys; + + } +#if 0 + else + { + // did not find the phy + } +#endif + + printf("[PNF] param request .. exit\n"); + + return 0; +} + +// From MAC config.c +extern uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn); +extern int32_t get_uldl_offset(int eutra_bandP); + +int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req) +{ + printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id); + + pnf_info* pnf = (pnf_info*)(config->user_data); + uint8_t num_tlv = 0; + +#if 0 + //DJP + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.id == req->header.phy_id; }); + + if(found != pnf->phys.end()) + { + phy_info& phy_info = (*found); + } +#endif + //DJP + phy_info* phy_info = pnf->phys; + + if(req->nfapi_config.timing_window.tl.tag == NFAPI_NFAPI_TIMING_WINDOW_TAG) + { + phy_info->timing_window = req->nfapi_config.timing_window.value; + num_tlv++; + } + + if(req->nfapi_config.timing_info_mode.tl.tag == NFAPI_NFAPI_TIMING_INFO_MODE_TAG) + { + printf("timing info mode provided\n"); + phy_info->timing_info_mode = req->nfapi_config.timing_info_mode.value; + num_tlv++; + } + else + { + phy_info->timing_info_mode = 0; + printf("NO timing info mode provided\n"); + } + + if(req->nfapi_config.timing_info_period.tl.tag == NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG) + { + printf("timing info period provided\n"); + phy_info->timing_info_period = req->nfapi_config.timing_info_period.value; + num_tlv++; + } + else + { + phy_info->timing_info_period = 0; + } + + if(req->rf_config.dl_channel_bandwidth.tl.tag == NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG) + { + phy_info->dl_channel_bw_support = req->rf_config.dl_channel_bandwidth.value; + RC.eNB[0][0]->frame_parms.N_RB_DL = req->rf_config.dl_channel_bandwidth.value; + num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG N_RB_DL:%u\n", __FUNCTION__, RC.eNB[0][0]->frame_parms.N_RB_DL); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() Missing NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG\n", __FUNCTION__); + } + + if(req->rf_config.ul_channel_bandwidth.tl.tag == NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG) + { + phy_info->ul_channel_bw_support = req->rf_config.ul_channel_bandwidth.value; + RC.eNB[0][0]->frame_parms.N_RB_UL = req->rf_config.ul_channel_bandwidth.value; + num_tlv++; + } + + if(req->nfapi_config.rf_bands.tl.tag == NFAPI_NFAPI_RF_BANDS_TAG) + { + pnf->rfs[0].band = req->nfapi_config.rf_bands.rf_band[0]; + RC.eNB[0][0]->frame_parms.eutra_band = req->nfapi_config.rf_bands.rf_band[0]; + num_tlv++; + } + + if(req->nfapi_config.earfcn.tl.tag == NFAPI_NFAPI_EARFCN_TAG) + { + RC.eNB[0][0]->frame_parms.dl_CarrierFreq = from_earfcn(RC.eNB[0][0]->frame_parms.eutra_band, req->nfapi_config.earfcn.value); // DJP - TODO FIXME - hard coded to first rf + RC.eNB[0][0]->frame_parms.ul_CarrierFreq = RC.eNB[0][0]->frame_parms.dl_CarrierFreq - (get_uldl_offset(RC.eNB[0][0]->frame_parms.eutra_band) * 1e5); + num_tlv++; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() earfcn:%u dl_carrierFreq:%u ul_CarrierFreq:%u band:%u N_RB_DL:%u\n", + __FUNCTION__, req->nfapi_config.earfcn.value, RC.eNB[0][0]->frame_parms.dl_CarrierFreq, RC.eNB[0][0]->frame_parms.ul_CarrierFreq, pnf->rfs[0].band, RC.eNB[0][0]->frame_parms.N_RB_DL); + } + + if (req->subframe_config.duplex_mode.tl.tag == NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG) + { + RC.eNB[0][0]->frame_parms.frame_type = req->subframe_config.duplex_mode.value==0 ? TDD : FDD; + num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() frame_type:%d\n", __FUNCTION__, RC.eNB[0][0]->frame_parms.frame_type); + } + if (req->subframe_config.dl_cyclic_prefix_type.tl.tag == NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG) + { + RC.eNB[0][0]->frame_parms.Ncp = req->subframe_config.dl_cyclic_prefix_type.value; + num_tlv++; + } + + if (req->subframe_config.ul_cyclic_prefix_type.tl.tag == NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG) + { + RC.eNB[0][0]->frame_parms.Ncp_UL = req->subframe_config.ul_cyclic_prefix_type.value; + num_tlv++; + } + + RC.eNB[0][0]->frame_parms.num_MBSFN_config = 0; // DJP - hard code alert + + if (req->sch_config.physical_cell_id.tl.tag == NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG) + { + RC.eNB[0][0]->frame_parms.Nid_cell = req->sch_config.physical_cell_id.value; + num_tlv++; + } + + if (req->rf_config.tx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG) + { + RC.eNB[0][0]->frame_parms.nb_antennas_tx = req->rf_config.tx_antenna_ports.value; + RC.eNB[0][0]->frame_parms.nb_antenna_ports_eNB = 1; + num_tlv++; + } + + if (req->rf_config.rx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG) + { + RC.eNB[0][0]->frame_parms.nb_antennas_rx = req->rf_config.rx_antenna_ports.value; + num_tlv++; + } + + if (req->rf_config.rx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG) + { + RC.eNB[0][0]->frame_parms.nb_antennas_rx = req->rf_config.rx_antenna_ports.value; + num_tlv++; + } + + RC.eNB[0][0]->frame_parms.nushift = 0; + + if (req->phich_config.phich_resource.tl.tag == NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG) + { + RC.eNB[0][0]->frame_parms.phich_config_common.phich_resource = req->phich_config.phich_resource.value; + num_tlv++; + } + + if (req->phich_config.phich_duration.tl.tag == NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG) + { + RC.eNB[0][0]->frame_parms.phich_config_common.phich_duration = req->phich_config.phich_duration.value; + num_tlv++; + } + + if (req->phich_config.phich_power_offset.tl.tag == NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG) + { + LOG_E(PHY, "%s() NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG tag:%d not supported\n", __FUNCTION__, req->phich_config.phich_power_offset.tl.tag); + //RC.eNB[0][0]->frame_parms.phich_config_common.phich_power_offset = req->phich_config. + num_tlv++; + } + + // UL RS Config + if (req->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG) + { + RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = req->uplink_reference_signal_config.cyclic_shift_1_for_drms.value; + num_tlv++; + } + + if (req->uplink_reference_signal_config.uplink_rs_hopping.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG) + { + RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = req->uplink_reference_signal_config.uplink_rs_hopping.value; + num_tlv++; + } + + if (req->uplink_reference_signal_config.group_assignment.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG) + { + RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = req->uplink_reference_signal_config.group_assignment.value; + num_tlv++; + } + + if (req->pusch_config.hopping_mode.tl.tag == NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG) { } // DJP - not being handled? + + RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; // DJP - not being handled + + if (req->prach_config.configuration_index.tl.tag == NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG) + { + RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=req->prach_config.configuration_index.value; + num_tlv++; + } + + if (req->prach_config.root_sequence_index.tl.tag == NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG) + { + RC.eNB[0][0]->frame_parms.prach_config_common.rootSequenceIndex=req->prach_config.root_sequence_index.value; + num_tlv++; + } + + if (req->prach_config.zero_correlation_zone_configuration.tl.tag == NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG) + { + RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=req->prach_config.zero_correlation_zone_configuration.value; + num_tlv++; + } + + if (req->prach_config.high_speed_flag.tl.tag == NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG) + { + RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=req->prach_config.high_speed_flag.value; + num_tlv++; + } + + if (req->prach_config.frequency_offset.tl.tag == NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG) + { + RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset=req->prach_config.frequency_offset.value; + num_tlv++; + } + + printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv); + + // DJP - commented out 19/9/17 + //init_frame_parms(&RC.eNB[0][0]->frame_parms,1); + //init_lte_top(&RC.eNB[0][0]->frame_parms); + + printf("[PNF] Simulating PHY CONFIG - DJP\n"); + PHY_Config_t phy_config; + phy_config.Mod_id = 0; + phy_config.CC_id=0; + phy_config.cfg = req; + + phy_config_request(&phy_config); + + dump_frame_parms(&RC.eNB[0][0]->frame_parms); + + phy_info->remote_port = req->nfapi_config.p7_vnf_port.value; + + struct sockaddr_in vnf_p7_sockaddr; + memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4); + phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr); + + printf("[PNF] %d vnf p7 %s:%d timing %d %d %d\n", phy_info->id, phy_info->remote_addr, phy_info->remote_port, + phy_info->timing_window, phy_info->timing_info_mode, phy_info->timing_info_period); + + nfapi_config_response_t nfapi_resp; + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_CONFIG_RESPONSE; + nfapi_resp.header.phy_id = phy_info->id; + nfapi_resp.error_code = 0; // DJP - some value resp->error_code; + nfapi_pnf_config_resp(config, &nfapi_resp); + printf("[PNF] Sent NFAPI_CONFIG_RESPONSE phy_id:%d\n", phy_info->id); + + return 0; +} + +nfapi_p7_message_header_t* pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P7_VENDOR_EXT_REQ) + { + (*msg_size) = sizeof(vendor_ext_p7_req); + return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_req)); + } + + return 0; +} + +void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) +{ + free(header); +} + +int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) +{ +#if 0 + printf("[PNF] dl config request sfn_sf:%d(%d) pdcch:%u dci:%u pdu:%d pdsch_rnti:%d pcfich:%u - DO NOTHING\n", + req->sfn_sf, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->dl_config_request_body.number_pdcch_ofdm_symbols, + req->dl_config_request_body.number_dci, + req->dl_config_request_body.number_pdu, + req->dl_config_request_body.number_pdsch_rnti, + req->dl_config_request_body.transmission_power_pcfich + ); +#endif + + if (RC.ru == 0) + { + return -1; + } + + if (RC.eNB == 0) + { + return -2; + } + + if (RC.eNB[0][0] == 0) + { + return -3; + } + + if (RC.eNB[0][0] == 0) + { + return -3; + } + + //int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + //int sf = NFAPI_SFNSF2SF(req->sfn_sf); + + //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + //int num_pdcch_symbols = eNB->pdcch_vars[sf&1].num_pdcch_symbols; + + + + if(req->vendor_extension) + free(req->vendor_extension); + + return 0; +} + +int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) +{ + //printf("[PNF] ul config request\n"); + //phy_info* phy = (phy_info*)(pnf_p7->user_data); + + return 0; +} + +int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) +{ + //printf("[PNF] hi dci0 request\n"); + //phy_info* phy = (phy_info*)(pnf_p7->user_data); + + return 0; +} + + +void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe); +void pdsch_procedures(PHY_VARS_eNB *eNB, + eNB_rxtx_proc_t *proc, + int harq_pid, + LTE_eNB_DLSCH_t *dlsch, + LTE_eNB_DLSCH_t *dlsch1, + LTE_eNB_UE_stats *ue_stats, + int ra_flag); + +//int __attribute__((optimize("O0"))) pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) +int pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) +{ + if (RC.ru == 0) + { + return -1; + } + + if (RC.eNB == 0) + { + return -2; + } + + if (RC.eNB[0][0] == 0) + { + return -3; + } + + if (RC.eNB[0][0] == 0) + { + return -3; + } + + { + uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf); + LTE_DL_FRAME_PARMS *fp = &RC.ru[0]->frame_parms; + //int ONE_SUBFRAME_OF_SAMPLES = fp->ofdm_symbol_size*fp->symbols_per_tti; + //int ONE_SUBFRAME_OF_SAMPLES = fp->symbols_per_tti; + //int ONE_SUBFRAME_OF_SAMPLES = fp->ofdm_symbol_size*fp->symbols_per_tti*sizeof(int32_t); + //int offset = sf * ONE_SUBFRAME_OF_SAMPLES; + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + //int aa; + + // clear the transmit data array for the current subframe +#if 0 + for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) { + memset(&eNB->common_vars.txdataF[aa][offset], 0, ONE_SUBFRAME_OF_SAMPLES); + } +#endif + + if ( + 0 + //&& NFAPI_SFNSF2DEC(req->sfn_sf) % 500 == 0 + ) + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn_sf:%u first_carrier_offset:%d pdus:%u RC.ru:%p RC.eNB:%p RC.eNB[0][0]:%p RC.eNB[0][0]->pbch_pdu:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), fp->first_carrier_offset, req->tx_request_body.number_of_pdus, RC.ru, RC.eNB, RC.eNB[0][0], RC.eNB[0][0]->pbch_pdu); + + for(int i = 0; i < req->tx_request_body.number_of_pdus; ++i) + { + // DJP - TODO FIXME - work out if BCH (common_var)s or DLSCH (common.txdata) + + for(int j=0; j < req->tx_request_body.tx_pdu_list[i].num_segments; ++j) + { + // DJP - hack - assume tx_req segment of length 3 = bch + if (req->tx_request_body.tx_pdu_list[i].segments[0].segment_length == 3) + { + eNB->pbch_pdu[2] = req->tx_request_body.tx_pdu_list[i].segments[j].segment_data[0]; + eNB->pbch_pdu[1] = req->tx_request_body.tx_pdu_list[i].segments[j].segment_data[1]; + eNB->pbch_pdu[0] = req->tx_request_body.tx_pdu_list[i].segments[j].segment_data[2]; + + eNB->pbch_configured=1; + + if ( + 1 + //&& NFAPI_SFNSF2DEC(req->sfn_sf) % 500 == 0 + ) + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() [PDU:%u] len:%u pdu_index:%u num_segments:%u segment[0]_length:%u pbch_pdu:%x %x %x\n", + __FUNCTION__, i, req->tx_request_body.tx_pdu_list[i].pdu_length, req->tx_request_body.tx_pdu_list[i].pdu_index, req->tx_request_body.tx_pdu_list[i].num_segments, + req->tx_request_body.tx_pdu_list[i].segments[0].segment_length, + eNB->pbch_pdu[0], + eNB->pbch_pdu[1], + eNB->pbch_pdu[2]); + + } + else + { + int num_dci = 1; // DJP -HACK!!!! + int frame = sfn; + int subframe = sf; + int num_pdcch_symbols = 1; // DJP HARD CODe HACK - this is zero - eNB->pdcch_vars[subframe&1].num_pdcch_symbols; + + if (num_dci > 0) + LOG_E(PHY,"SFN/SF:%d/%d num_dci:%d num_pdcch_symbols:%d\n", frame, subframe, num_dci, num_pdcch_symbols); + + generate_dci_top(num_pdcch_symbols, + num_dci, + &eNB->pdcch_vars[subframe&1].dci_alloc[0], + 0, + AMP, + fp, + eNB->common_vars.txdataF, + subframe); + } + } + } + +#if 0 + { + int sched_sfn = sf==0?sfn-1:sfn-0; + int sched_sf = sf==0?9:sf-1; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn_sf:%u sfn:%u sf:%u SCHED:%d/%d calling common_signal_procedures\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + sfn, sf, + sched_sfn, sched_sf + ); + + common_signal_procedures(eNB, sched_sfn, sched_sf); + + } +#else + common_signal_procedures(eNB, sfn, sf); +#endif + + // Now scan UE specific DLSCH + for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) + { + LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[(uint8_t)UE_id][0]; + LTE_eNB_DLSCH_t *dlsch1 = eNB->dlsch[(uint8_t)UE_id][1]; + + if ((dlsch0)&& + (dlsch0->rnti>0) && + (dlsch0->active == 1)) { + + // get harq_pid + uint8_t harq_pid = dlsch0->harq_ids[sf]; + AssertFatal(harq_pid>=0,"harq_pid is negative\n"); + // generate pdsch + pdsch_procedures(eNB, + &eNB->proc.proc_rxtx[sf&1], + harq_pid, + dlsch0, + dlsch1, + &eNB->UE_stats[(uint32_t)UE_id], + 0); + } + + else if ((dlsch0)&& + (dlsch0->rnti>0)&& + (dlsch0->active == 0)) { + + // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later) + dlsch0->subframe_tx[sf]=0; + } + } + + if (0 && NFAPI_SFNSF2DEC(req->sfn_sf) % 500 == 0) + { + int32_t *txdataF = eNB->common_vars.txdataF[0]; + + char *buf = malloc(fp->ofdm_symbol_size * fp->symbols_per_tti * 3); + char *pbuf = buf; + + for (int i=0;i<10;i++) + { + buf[0]='\0'; + pbuf = buf; + + for (int j=0;j<fp->ofdm_symbol_size;j++) + { + for (int k=0;k<fp->symbols_per_tti;k++) + { + pbuf += sprintf(pbuf, "%2x ", txdataF[(i*fp->symbols_per_tti)+j]); + } + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s", buf); + + } + free(buf); + } + + return 0; + } +} + +int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req) +{ + //printf("[PNF] lbt dl config request\n"); + return 0; +} + +int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg) +{ + if(msg->message_id == P7_VENDOR_EXT_REQ) + { + //vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg; + //printf("[PNF] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2); + } + else + { + printf("[PNF] unknown vendor ext\n"); + } + return 0; +} + +int pnf_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codex) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_IND) + { + vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)(header); + if(!push16(ind->error_code, ppWritePackedMsg, end)) + return 0; + + return 1; + } + return -1; +} + +int pnf_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* codec) +{ + if(header->message_id == P7_VENDOR_EXT_REQ) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + if(!(pull16(ppReadPackedMessage, &req->dummy1, end) && + pull16(ppReadPackedMessage, &req->dummy2, end))) + return 0; + return 1; + } + return -1; +} + +int pnf_phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t* end, void** ve, nfapi_p7_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_phy_unpack_vendor_extension_tlv\n"); + + switch(tl->tag) + { + case VENDOR_EXT_TLV_1_TAG: + *ve = malloc(sizeof(vendor_ext_tlv_1)); + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_1*)(*ve))->dummy, end)) + return 0; + + return 1; + break; + } + + return -1; +} + +int pnf_phy_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p7_codec_config_t* config) +{ + //printf("%s\n", __FUNCTION__); + (void)ve; + (void)ppWritePackedMsg; + return -1; +} + +int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_unpack_vendor_extension_tlv\n"); + + switch(tl->tag) + { + case VENDOR_EXT_TLV_2_TAG: + *ve = malloc(sizeof(vendor_ext_tlv_2)); + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_2*)(*ve))->dummy, end)) + return 0; + + return 1; + break; + } + + return -1; +} + +int pnf_sim_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + //printf("%s\n", __FUNCTION__); + (void)ve; + (void)ppWritePackedMsg; + return -1; +} + +int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req) +{ + printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id); + + pnf_info* pnf = (pnf_info*)(config->user_data); + +#if 0 + //DJP + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.id == req->header.phy_id; }); + + if(found != pnf->phys.end()) +#endif + { + //DJP phy_info& phy_info = (*found); + phy_info* phy_info = pnf->phys; + + nfapi_pnf_p7_config_t* p7_config = nfapi_pnf_p7_config_create(); + + p7_config->phy_id = phy->phy_id; + + p7_config->remote_p7_port = phy_info->remote_port; + p7_config->remote_p7_addr = phy_info->remote_addr; + p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port; + //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str(); + p7_config->local_p7_addr = phy_info->local_addr; + + printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port); + + p7_config->user_data = phy_info; + + p7_config->malloc = &pnf_allocate; + p7_config->free = &pnf_deallocate; + p7_config->codec_config.allocate = &pnf_allocate; + p7_config->codec_config.deallocate = &pnf_deallocate; + + p7_config->trace = &pnf_sim_trace; + + phy->user_data = p7_config; + + p7_config->subframe_buffer_size = phy_info->timing_window; + if(phy_info->timing_info_mode & 0x1) + { + p7_config->timing_info_mode_periodic = 1; + p7_config->timing_info_period = phy_info->timing_info_period; + } + + if(phy_info->timing_info_mode & 0x2) + { + p7_config->timing_info_mode_aperiodic = 1; + } + + p7_config->dl_config_req = &pnf_phy_dl_config_req; + p7_config->ul_config_req = &pnf_phy_ul_config_req; + p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; + p7_config->tx_req = &pnf_phy_tx_req; + p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; + + p7_config->vendor_ext = &pnf_phy_vendor_ext; + + p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext; + p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext; + + p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension; + p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension; + p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv; + p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__); + pthread_t p7_thread; + pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config); + + //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__); + l1_north_init_eNB(); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__); + p7_config_g = p7_config; + + printf("[PNF] MARKING RC.eNB[0][0]->configured=1 %s()\n", __FUNCTION__); + RC.eNB[0][0]->configured = 1; + + // DJP - INIT PHY RELATED STUFF - this should be separate i think but is not currently... + { + printf("[PNF] %s() Calling phy_init_lte_eNB() and setting nb_antennas_rx = 1\n", __FUNCTION__); + printf("[PNF] %s() TBD create frame_parms from NFAPI message\n", __FUNCTION__); + + phy_init_lte_eNB(RC.eNB[0][0],0,0); + RC.eNB[0][0]->frame_parms.nb_antennas_rx = 1; + for (int ce_level=0;ce_level<4;ce_level++) + RC.eNB[0][0]->prach_vars.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*)); +#ifdef Rel14 + for (int ce_level=0;ce_level<4;ce_level++) + RC.eNB[0][0]->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*)); +#endif + } + + while(sync_var<0) + { + usleep(5000000); + printf("[PNF] waiting for OAI to be started\n"); + } + + printf("[PNF] Sending PNF_START_RESP\n"); + nfapi_send_pnf_start_resp(config, p7_config->phy_id); + + printf("[PNF] Sending first P7 subframe ind\n"); + nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? + } + + return 0; +} + +int measurement_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req) +{ + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_measurement_resp(config, &resp); + return 0; +} + +int rssi_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req) +{ + nfapi_rssi_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_RSSI_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_rssi_resp(config, &resp); + + nfapi_rssi_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_RSSI_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + ind.rssi_indication_body.tl.tag = NFAPI_RSSI_INDICATION_TAG; + ind.rssi_indication_body.number_of_rssi = 1; + ind.rssi_indication_body.rssi[0] = -42; + nfapi_pnf_rssi_ind(config, &ind); + return 0; +} + +int cell_search_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req) +{ + nfapi_cell_search_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_cell_search_resp(config, &resp); + + nfapi_cell_search_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_CELL_SEARCH_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_cell_search_indication.tl.tag = NFAPI_LTE_CELL_SEARCH_INDICATION_TAG; + ind.lte_cell_search_indication.number_of_lte_cells_found = 1; + ind.lte_cell_search_indication.lte_found_cells[0].pci = 123; + ind.lte_cell_search_indication.lte_found_cells[0].rsrp = 123; + ind.lte_cell_search_indication.lte_found_cells[0].rsrq = 123; + ind.lte_cell_search_indication.lte_found_cells[0].frequency_offset = 123; + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_cell_search_indication.tl.tag = NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG; + ind.utran_cell_search_indication.number_of_utran_cells_found = 1; + ind.utran_cell_search_indication.utran_found_cells[0].psc = 89; + ind.utran_cell_search_indication.utran_found_cells[0].rscp = 89; + ind.utran_cell_search_indication.utran_found_cells[0].ecno = 89; + ind.utran_cell_search_indication.utran_found_cells[0].frequency_offset = -89; + + } + break; + case NFAPI_RAT_TYPE_GERAN: + { + ind.geran_cell_search_indication.tl.tag = NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG; + ind.geran_cell_search_indication.number_of_gsm_cells_found = 1; + ind.geran_cell_search_indication.gsm_found_cells[0].bsic = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxlev = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxqual = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].frequency_offset = -23; + ind.geran_cell_search_indication.gsm_found_cells[0].sfn_offset = 230; + + } + break; + } + + ind.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + ind.pnf_cell_search_state.length = 3; + + nfapi_pnf_cell_search_ind(config, &ind); + + return 0; +} + +int broadcast_detect_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req) +{ + nfapi_broadcast_detect_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_broadcast_detect_resp(config, &resp); + + nfapi_broadcast_detect_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_broadcast_detect_indication.tl.tag = NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG; + ind.lte_broadcast_detect_indication.number_of_tx_antenna = 1; + ind.lte_broadcast_detect_indication.mib_length = 4; + //ind.lte_broadcast_detect_indication.mib... + ind.lte_broadcast_detect_indication.sfn_offset = 77; + + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_broadcast_detect_indication.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG; + ind.utran_broadcast_detect_indication.mib_length = 4; + //ind.utran_broadcast_detect_indication.mib... + // ind.utran_broadcast_detect_indication.sfn_offset; DJP - nonsense line + + } + break; + } + + ind.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + ind.pnf_cell_broadcast_state.length = 3; + + nfapi_pnf_broadcast_detect_ind(config, &ind); + + return 0; +} + +int system_information_schedule_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req) +{ + nfapi_system_information_schedule_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_system_information_schedule_resp(config, &resp); + + nfapi_system_information_schedule_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + ind.lte_system_information_indication.sib_type = 3; + ind.lte_system_information_indication.sib_length = 5; + //ind.lte_system_information_indication.sib... + + nfapi_pnf_system_information_schedule_ind(config, &ind); + + return 0; +} + +int system_information_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req) +{ + nfapi_system_information_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_system_information_resp(config, &resp); + + nfapi_system_information_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + ind.lte_system_information_indication.sib_type = 1; + ind.lte_system_information_indication.sib_length = 3; + //ind.lte_system_information_indication.sib... + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_system_information_indication.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.utran_system_information_indication.sib_length = 3; + //ind.utran_system_information_indication.sib... + + } + break; + case NFAPI_RAT_TYPE_GERAN: + { + ind.geran_system_information_indication.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.geran_system_information_indication.si_length = 3; + //ind.geran_system_information_indication.si... + + } + break; + } + + nfapi_pnf_system_information_ind(config, &ind); + + return 0; +} + +int nmm_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req) +{ + nfapi_nmm_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NMM_STOP_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_nmm_stop_resp(config, &resp); + return 0; +} + +int vendor_ext(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 %s %p\n", __FUNCTION__, msg); + + switch(msg->message_id) + { + case P5_VENDOR_EXT_REQ: + { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)msg; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2); + // send back the P5_VENDOR_EXT_RSP + vendor_ext_p5_rsp rsp; + memset(&rsp, 0, sizeof(rsp)); + rsp.header.message_id = P5_VENDOR_EXT_RSP; + rsp.error_code = NFAPI_MSG_OK; + nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp)); + } + break; + } + + return 0; +} + +nfapi_p4_p5_message_header_t* pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P5_VENDOR_EXT_REQ) + { + (*msg_size) = sizeof(vendor_ext_p5_req); + return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_req)); + } + + return 0; +} + +void pnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) +{ + free(header); +} + +int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_RSP) + { + vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)(header); + return (!push16(rsp->error_code, ppWritePackedMsg, end)); + } + return 0; +} + +int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_REQ) + { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + return (!(pull16(ppReadPackedMessage, &req->dummy1, end) && + pull16(ppReadPackedMessage, &req->dummy2, end))); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2); + } + return 0; +} + +/*------------------------------------------------------------------------------*/ +static pnf_info pnf; +static pthread_t pnf_start_pthread; + +void* pnf_start_thread(void* ptr) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__); + + nfapi_pnf_config_t *config = (nfapi_pnf_config_t*)ptr; + + nfapi_pnf_start(config); + + return (void*)0; +} + +void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, int pnf_p7_port, int vnf_p7_port) +{ + char *xml_file = 0; + + //DJP if(read_pnf_xml(pnf, argv[3]) < 0) + if(read_pnf_xml(&pnf, xml_file) < 0) + { + printf("Failed to read xml file>\n"); + return ; + } + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + + config->vnf_ip_addr = vnf_ip_addr; + config->vnf_p5_port = vnf_p5_port; + + pnf.phys[0].udp.enabled = 1; + pnf.phys[0].udp.rx_port = pnf_p7_port; + pnf.phys[0].udp.tx_port = vnf_p7_port; + strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr); + + printf("%s() VNF:%s:%d PNF_PHY[UDP:tx_addr:%s:%d rx:%d]\n", + __FUNCTION__, + config->vnf_ip_addr, config->vnf_p5_port, + pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port, + pnf.phys[0].udp.rx_port); + + config->pnf_param_req = &pnf_param_request; + config->pnf_config_req = &pnf_config_request; + config->pnf_start_req = &pnf_start_request; + config->pnf_stop_req = &pnf_stop_request; + config->param_req = ¶m_request; + config->config_req = &config_request; + config->start_req = &start_request; + + config->measurement_req = &measurement_request; + config->rssi_req = &rssi_request; + config->cell_search_req = &cell_search_request; + config->broadcast_detect_req = &broadcast_detect_request; + config->system_information_schedule_req = &system_information_schedule_request; + config->system_information_req = &system_information_request; + config->nmm_stop_req = &nmm_stop_request; + + config->vendor_ext = &vendor_ext; + + config->trace = &pnf_sim_trace; + + config->user_data = &pnf; + + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv; + + config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext; + + config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&pnf_start_pthread, NULL, &pnf_start_thread, config); +} + +void oai_subframe_ind(uint16_t frame, uint16_t subframe) +{ + //TODO FIXME - HACK - DJP - using a global to bodge it in + + if (p7_config_g != NULL && sync_var==0) + { + uint16_t sfn = subframe>=9?frame+1:frame; + uint16_t sf = subframe>=9?0:subframe+1; + uint16_t sfn_sf = sfn<<4 | sf; + + if ((frame % 100 == 0) && subframe==0) + { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (frame:%u subframe:%u) sfn_sf:%u sfn_sf(DEC):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, frame, subframe, sfn_sf, NFAPI_SFNSF2DEC(sfn_sf)); + } + + int subframe_ret = nfapi_pnf_p7_subframe_ind(p7_config_g, p7_config_g->phy_id, sfn_sf); + + if (subframe_ret) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u subframe:%u) sfn_sf:%u sfn_sf(DEC):%u - PROBLEM with pnf_p7_subframe_ind()\n", __FUNCTION__, frame, subframe, sfn_sf, NFAPI_SFNSF2DEC(sfn_sf)); + } + } + else + { + } +} diff --git a/nfapi/nfapi_pnf.h b/nfapi/nfapi_pnf.h new file mode 100644 index 0000000000000000000000000000000000000000..5b97536f58bc8b3900e24b2cb26d951b916f5e1c --- /dev/null +++ b/nfapi/nfapi_pnf.h @@ -0,0 +1,6 @@ +#if !defined(NFAPI_PNF_H__) +#define NFAPI_PNF_H__ + +void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, int pnf_p7_port, int vnf_p7_port); + +#endif diff --git a/nfapi/nfapi_vnf.c b/nfapi/nfapi_vnf.c new file mode 100644 index 0000000000000000000000000000000000000000..a4310819fc9284ce6ceb5829b5dcd3cba8946781 --- /dev/null +++ b/nfapi/nfapi_vnf.c @@ -0,0 +1,1595 @@ + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <pthread.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "nfapi_interface.h" +#include "nfapi_vnf_interface.h" +#include "nfapi.h" +#include "vendor_ext.h" + +#include "nfapi_vnf.h" + + +#include "common/ran_context.h" +//#include "openair1/PHY/vars.h" +extern RAN_CONTEXT_t RC; + +typedef struct +{ + //public: + uint8_t enabled; + uint32_t rx_port; + uint32_t tx_port; + //std::string tx_addr; + char tx_addr[80]; +} udp_data; + +//class phy_info +//DJP +typedef struct +{ +#if 0 + public: + + phy_info() + : first_subframe_ind(0), fapi(0), + dl_ues_per_subframe(0), ul_ues_per_subframe(0), + timing_window(0), timing_info_mode(0), timing_info_period(0) + { + index = 0; + id = 0; + + local_port = 0; + remote_addr = 0; + remote_port = 0; + + duplex_mode = 0; + dl_channel_bw_support = 0; + ul_channel_bw_support = 0; + num_dl_layers_supported = 0; + num_ul_layers_supported = 0; + release_supported = 0; + nmm_modes_supported = 0; + } +#endif + + uint16_t index; + uint16_t id; + //std::vector<uint8_t> rfs; + //std::vector<uint8_t> excluded_rfs; + uint8_t rfs[2]; + uint8_t excluded_rfs[2]; + + udp_data udp; + + //std::string local_addr; + char local_addr[80]; + int local_port; + + char* remote_addr; + int remote_port; + + uint8_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; + uint8_t num_dl_layers_supported; + uint8_t num_ul_layers_supported; + uint16_t release_supported; + uint8_t nmm_modes_supported; + + uint8_t dl_ues_per_subframe; + uint8_t ul_ues_per_subframe; + + uint8_t first_subframe_ind; + + // timing information recevied from the vnf + uint8_t timing_window; + uint8_t timing_info_mode; + uint8_t timing_info_period; + + // DJP + //fapi_t* fapi; + +} phy_info; + +//class rf_info +//DJP +typedef struct +{ + //public: + uint16_t index; + uint16_t band; + int16_t max_transmit_power; + int16_t min_transmit_power; + uint8_t num_antennas_supported; + uint32_t min_downlink_frequency; + uint32_t max_downlink_frequency; + uint32_t max_uplink_frequency; + uint32_t min_uplink_frequency; +} rf_info; + + +//class pnf_info +//DJP +typedef struct +{ +#if 0 + public: + + pnf_info() + : release(13), wireshark_test_mode(0), + max_total_power(0), oui(0) + + { + release = 0; + + sync_mode = 0; + location_mode = 0; + dl_config_timing = 0; + ul_config_timing = 0; + tx_timing = 0; + hi_dci0_timing = 0; + + max_phys = 0; + max_total_bw = 0; + max_total_dl_layers = 0; + max_total_ul_layers = 0; + shared_bands = 0; + shared_pa = 0; + + } +#endif + + int release; + //DJPstd::vector<phy_info> phys; + //std::vector<rf_info> rfs; + phy_info phys[2]; + rf_info rfs[2]; + + uint8_t sync_mode; + uint8_t location_mode; + uint8_t location_coordinates[6]; + uint32_t dl_config_timing; + uint32_t ul_config_timing; + uint32_t tx_timing; + uint32_t hi_dci0_timing; + + uint16_t max_phys; + uint16_t max_total_bw; + uint16_t max_total_dl_layers; + uint16_t max_total_ul_layers; + uint8_t shared_bands; + uint8_t shared_pa; + int16_t max_total_power; + uint8_t oui; + + uint8_t wireshark_test_mode; + +} pnf_info; + +typedef struct mac mac_t; + +typedef struct mac +{ + void* user_data; + + void (*dl_config_req)(mac_t* mac, nfapi_dl_config_request_t* req); + void (*ul_config_req)(mac_t* mac, nfapi_ul_config_request_t* req); + void (*hi_dci0_req)(mac_t* mac, nfapi_hi_dci0_request_t* req); + void (*tx_req)(mac_t* mac, nfapi_tx_request_t* req); +} mac_t; + +//class vnf_p7_info +typedef struct +{ + //public: + +#if 0 + vnf_p7_info() + : thread_started(false), + config(nfapi_vnf_p7_config_create(), + [] (nfapi_vnf_p7_config_t* f) { nfapi_vnf_p7_config_destory(f); }), + mac(0) + { + local_port = 0; + + timing_window = 0; + periodic_timing_enabled = 0; + aperiodic_timing_enabled = 0; + periodic_timing_period = 0; + + //config = nfapi_vnf_p7_config_create(); + } + + vnf_p7_info(const vnf_p7_info& other) = default; + + vnf_p7_info(vnf_p7_info&& other) = default; + + vnf_p7_info& operator=(const vnf_p7_info&) = default; + + vnf_p7_info& operator=(vnf_p7_info&&) = default; + + + + virtual ~vnf_p7_info() + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "*** vnf_p7_info delete ***\n"); + + //nfapi_vnf_p7_config_destory(config); + + // should we delete the mac? + } +#endif + + + int local_port; + //DJP std::string local_addr; + char local_addr[80]; + + unsigned timing_window; + unsigned periodic_timing_enabled; + unsigned aperiodic_timing_enabled; + unsigned periodic_timing_period; + + // This is not really the right place if we have multiple PHY, + // should be part of the phy struct + udp_data udp; + + uint8_t thread_started; + + nfapi_vnf_p7_config_t* config; + //std::shared_ptr<nfapi_vnf_p7_config_t> config; + + mac_t* mac; + +} vnf_p7_info; + +//class vnf_info +typedef struct +{ + //public: + + uint8_t wireshark_test_mode; + + //std::map<uint16_t, pnf_info> pnfs; + pnf_info pnfs[2]; + + //std::vector<vnf_p7_info> p7_vnfs; + vnf_p7_info p7_vnfs[2]; +} vnf_info; + +int vnf_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "vnf_pack_vendor_extension_tlv\n"); + nfapi_tl_t* tlv = (nfapi_tl_t*)ve; + switch(tlv->tag) + { + case VENDOR_EXT_TLV_2_TAG: + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n"); + vendor_ext_tlv_2* ve = (vendor_ext_tlv_2*)tlv; + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + return 1; + } + break; + } + return -1; +} +int vnf_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* codec) +{ + return -1; +} + +void install_schedule_handlers(IF_Module_t *if_inst); +extern int single_thread_flag; +extern void init_eNB_afterRU(); + +void oai_create_enb(void) +{ + static int bodge_counter = 0; + PHY_VARS_eNB *eNB; + + if (RC.eNB && RC.eNB[0] && RC.eNB[0][0]) + { + eNB = RC.eNB[0][0]; + printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d\n", eNB->Mod_id, eNB->CC_id); + } + else + { + printf("[VNF] DJP ***** RC.eNB[] and RC.eNB[%d][%d] RC.nb_CC[%d]=1 MALLOCING structure and zeroing *******\n", bodge_counter, bodge_counter, bodge_counter); + + RC.eNB[bodge_counter] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**)); + RC.eNB[bodge_counter][bodge_counter] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB)); + memset((void*)RC.eNB[bodge_counter][bodge_counter],0,sizeof(PHY_VARS_eNB)); + + eNB = RC.eNB[bodge_counter][bodge_counter]; + + eNB->Mod_id = bodge_counter; + eNB->CC_id = bodge_counter; + eNB->if_inst = IF_Module_init(bodge_counter); + eNB->abstraction_flag = 0; + eNB->single_thread_flag = 0;//single_thread_flag; + eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + + RC.nb_CC[bodge_counter] = 1; + } + + //init_eNB_proc(bodge_counter); + + // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY + // that will result in eNB->configured being set to TRUE. + // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values + if (RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) + { + install_schedule_handlers(RC.eNB[0][0]->if_inst); + } + + do { + printf("%s() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__); + usleep(50000); + } while(eNB->configured != 1); +} + + +void oai_enb_init(void) +{ + PHY_VARS_eNB *eNB = RC.eNB[0][0]; + + init_eNB_afterRU(); + + //phy_init_lte_eNB(eNB,0,0); + + printf("%s() take this out - done properly now - eNB->frame_parms.nb_antennas_rx = 1;\n", __FUNCTION__); + eNB->frame_parms.nb_antennas_rx = 1; // DJP + + //printf("%s() Mark eNB as configured\n", __FUNCTION__); + //eNB->configured = 1; +} + +int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) +{ + printf("[VNF] pnf connection indication idx:%d\n", p5_idx); + + //pnf_info pnf; + //vnf_info* vnf = (vnf_info*)(config->user_data); + //vnf->pnfs.insert(std::pair<uint16_t, pnf_info>(p5_idx, pnf)); + + oai_create_enb(); + + nfapi_pnf_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_PARAM_REQUEST; + nfapi_vnf_pnf_param_req(config, p5_idx, &req); + return 0; +} + +int pnf_disconnection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) +{ + printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx); + + vnf_info* vnf = (vnf_info*)(config->user_data); +#if 0 + auto find_result = vnf->pnfs.find(p5_idx); + + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + for(phy_info& phy : pnf.phys) + { + vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; + nfapi_vnf_p7_del_pnf((p7_vnf.config.get()), phy.id); + } + } +#else + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + + vnf_p7_info* p7_vnf = vnf->p7_vnfs; + // DJP nfapi_vnf_p7_del_pnf((p7_vnf->config.get()), phy->id); + nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id); +#endif + + return 0; +} + +int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp) +{ + printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + + vnf_info* vnf = (vnf_info*)(config->user_data); + +#if 0 + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; +#else + { + pnf_info *pnf = vnf->pnfs; +#endif + + for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) + { + phy_info phy; + phy.index = resp->pnf_phy.phy[i].phy_config_index; + + printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + + nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); + + for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) + { + printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index; + } + + pnf->phys[0] = phy; + } + + for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) + { + rf_info rf; + rf.index = resp->pnf_rf.rf[i].rf_config_index; + + printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); + + pnf->rfs[0] = rf; + } + + nfapi_pnf_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size(); + printf("DJP:Hard coded num phy rf to 2\n"); + + // DJP for(unsigned i = 0; i < pnf.phys.size(); ++i) + for(unsigned i = 0; i < 2; ++i) + { + req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id; + req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index; + req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0]; + } + + nfapi_vnf_pnf_config_req(config, p5_idx, &req); + } + return 0; +} + +int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp) +{ + printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%u message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); + + if(1) + { + //vnf_info* vnf = (vnf_info*)(config->user_data); +#if 0 + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + //pnf_info& pnf = find_result->second; + } +#else + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.phy_id = resp->header.phy_id; + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); +#endif + } + else + { + // Rather than send the pnf_start_request we will demonstrate + // sending a vendor extention message. The start request will be + // send when the vendor extension response is received + + //vnf_info* vnf = (vnf_info*)(config->user_data); + vendor_ext_p5_req req; + memset(&req, 0, sizeof(req)); + req.header.message_id = P5_VENDOR_EXT_REQ; + req.dummy1 = 45; + req.dummy2 = 1977; + nfapi_vnf_vendor_extension(config, p5_idx, &req.header); + } + return 0; +} + +int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) +{ + eNB_proc_t *proc=&eNB->proc; + + eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[sf&1]; + + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + + //int i; + struct timespec wait; + + wait.tv_sec=0; + wait.tv_nsec=5000000L; + +#if 0 + /* accept some delay in processing - up to 5ms */ + for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { + LOG_W( PHY,"[eNB] sfn/sf:%d:%d proc_rxtx[%d]:TXsfn:%d/%d eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", sfn, sf, sf&1, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx); + usleep(500); + } + if (proc_rxtx->instance_cnt_rxtx == 0) { + exit_fun( "TX thread busy" ); + return(-1); + } +#endif + + // wake up TX for subframe n+4 + // lock the TX mutex and make sure the thread is ready + if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); + exit_fun( "error locking mutex_rxtx" ); + return(-1); + } + + { + static uint16_t old_sf = 0; + static uint16_t old_sfn = 0; + + proc->subframe_rx = old_sf; + proc->frame_rx = old_sfn; + + // Try to be 1 frame back + old_sf = sf; + old_sfn = sfn; + + if (old_sf == 0 && old_sfn % 100==0) LOG_W( PHY,"[eNB] sfn/sf:%d:%d old_sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d]\n", sfn, sf, old_sfn, old_sf, proc->frame_rx, proc->subframe_rx); + } + + ++proc_rxtx->instance_cnt_rxtx; + + //LOG_E( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] proc_rxtx->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, proc_rxtx->instance_cnt_rxtx); + + // We have just received and processed the common part of a subframe, say n. + // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired + // transmitted timestamp of the next TX slot (first). + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, + // we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti, + // and proc->subframe_tx = proc->subframe_rx+4 + proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); + proc_rxtx->frame_rx = proc->frame_rx; + proc_rxtx->subframe_rx = proc->subframe_rx; + proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; + proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10; + + // the thread can now be woken up + if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); + + return(0); +} + +extern pthread_cond_t nfapi_sync_cond; +extern pthread_mutex_t nfapi_sync_mutex; +extern int nfapi_sync_var; + +int phy_sync_indication(struct nfapi_vnf_p7_config* config, uint8_t sync) +{ + //vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + + printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST"); + + if (1) + { + if (sync==1 && nfapi_sync_var!=0) + { + + printf("[VNF] Signal to OAI main code that it can go\n"); + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var=0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + } + } + + //if (RC.eNB && RC.eNB[0][0]->configured) + //wake_eNB_rxtx(RC.eNB[0][0], 0, 0); + + return(0); +} + +int phy_subframe_indication(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf) +{ + static uint8_t first_time = 1; + if (first_time) + { + printf("[VNF] subframe indication %d\n", sfn_sf); + first_time = 0; + } + + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_subframe_ind(p7_vnf->mac, phy_id, sfn_sf); + +#if 1 + if (RC.eNB && RC.eNB[0][0]->configured) + { + uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf); + uint16_t sf = NFAPI_SFNSF2SF(sfn_sf); + + //LOG_E(PHY,"[VNF] subframe indication sfn_sf:%d sfn:%d sf:%d\n", sfn_sf, sfn, sf); + + wake_eNB_rxtx(RC.eNB[0][0], sfn, sf); + } + else + { + printf("[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB); + if (RC.eNB) printf("RC.eNB[0][0]->configured:%d\n", RC.eNB[0][0]->configured); + } +#endif + + return 0; +} + +int phy_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_harq_ind(p7_vnf->mac, ind); + return 1; +} + +int phy_crc_indication(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_crc_ind(p7_vnf->mac, ind); + return 1; +} +int phy_rx_indication(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_rx_ind(p7_vnf->mac, ind); + return 1; +} +int phy_rach_indication(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_rach_ind(p7_vnf->mac, ind); + return 1; +} +int phy_srs_indication(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_srs_ind(p7_vnf->mac, ind); + return 1; +} +int phy_sr_indication(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_sr_ind(p7_vnf->mac, ind); + return 1; +} +int phy_cqi_indication(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_cqi_ind(p7_vnf->mac, ind); + return 1; +} +int phy_lbt_dl_indication(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_lbt_dl_ind(p7_vnf->mac, ind); + return 1; +} +int phy_nb_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_nb_harq_ind(p7_vnf->mac, ind); + return 1; +} +int phy_nrach_indication(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind) +{ + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_nrach_ind(p7_vnf->mac, ind); + return 1; +} + +void* vnf_allocate(size_t size) +{ + //return (void*)memory_pool::allocate(size); + return (void*)malloc(size); +} + +void vnf_deallocate(void* ptr) +{ + //memory_pool::deallocate((uint8_t*)ptr); + free(ptr); +} + +void vnf_trace(nfapi_trace_level_t level, const char* message, ...) +{ + va_list args; + va_start(args, message); + vprintf(message, args); + va_end(args); +} + +int phy_vendor_ext(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg) +{ + if(msg->message_id == P7_VENDOR_EXT_IND) + { + //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; + //printf("[VNF] vendor_ext (error_code:%d)\n", ind->error_code); + } + else + { + printf("[VNF] unknown %d\n", msg->message_id); + } + return 0; +} + +nfapi_p7_message_header_t* phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P7_VENDOR_EXT_IND) + { + *msg_size = sizeof(vendor_ext_p7_ind); + return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_ind)); + } + return 0; +} + +void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) +{ + free(header); +} + +/// maybe these should be in the mac file... +int phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p7_codec_config_t* codec) +{ + (void)tl; + (void)ppReadPackedMessage; + (void)ve; + return -1; +} + +int phy_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n"); + + nfapi_tl_t* tlv = (nfapi_tl_t*)ve; + switch(tlv->tag) + { + case VENDOR_EXT_TLV_1_TAG: + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); + vendor_ext_tlv_1* ve = (vendor_ext_tlv_1*)tlv; + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + return 1; + } + break; + default: + return -1; + break; + } +} + +int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_IND) + { + vendor_ext_p7_ind* req = (vendor_ext_p7_ind*)(header); + if(!pull16(ppReadPackedMessage, &req->error_code, end)) + return 0; + } + return 1; +} + +int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_REQ) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + if(!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))) + return 0; + } + return 1; +} + +int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_REQ) + { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2); + return (!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))); + } + return 0; +} + +static pthread_t vnf_start_pthread; +static pthread_t vnf_p7_start_pthread; +void* vnf_p7_start_thread(void *ptr) +{ + printf("%s()\n", __FUNCTION__); + + nfapi_vnf_p7_config_t* config = (nfapi_vnf_p7_config_t*)ptr; + + nfapi_vnf_p7_start(config); + + return config; +} + +void set_thread_priority(int priority); + +void* vnf_p7_thread_start(void* ptr) +{ + set_thread_priority(79); + + vnf_p7_info* p7_vnf = (vnf_p7_info*)ptr; + + p7_vnf->config->port = p7_vnf->local_port; + p7_vnf->config->sync_indication = &phy_sync_indication; + p7_vnf->config->subframe_indication = &phy_subframe_indication; + p7_vnf->config->harq_indication = &phy_harq_indication; + p7_vnf->config->crc_indication = &phy_crc_indication; + p7_vnf->config->rx_indication = &phy_rx_indication; + p7_vnf->config->rach_indication = &phy_rach_indication; + p7_vnf->config->srs_indication = &phy_srs_indication; + p7_vnf->config->sr_indication = &phy_sr_indication; + p7_vnf->config->cqi_indication = &phy_cqi_indication; + p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication; + p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication; + p7_vnf->config->nrach_indication = &phy_nrach_indication; + p7_vnf->config->malloc = &vnf_allocate; + p7_vnf->config->free = &vnf_deallocate; + + p7_vnf->config->trace = &vnf_trace; + + p7_vnf->config->vendor_ext = &phy_vendor_ext; + p7_vnf->config->user_data = p7_vnf; + + p7_vnf->mac->user_data = p7_vnf; + + p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; + p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; + p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; + p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv; + p7_vnf->config->codec_config.allocate = &vnf_allocate; + p7_vnf->config->codec_config.deallocate = &vnf_deallocate; + + p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; + p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; + + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config); + } + return 0; +} + +int pnf_start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp) +{ + vnf_info* vnf = (vnf_info*)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + + printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); + + if(p7_vnf->thread_started == 0) + { + pthread_t vnf_p7_thread; + pthread_create(&vnf_p7_thread, NULL, &vnf_p7_thread_start, p7_vnf); + p7_vnf->thread_started = 1; + } + else + { + // P7 thread already running. + } + + // start all the phys in the pnf. + +#if 0 + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + for(unsigned i = 0; i < pnf.phys.size(); ++i) + { + pnf_info& pnf = find_result->second; + } + } +#else + { + pnf_info *pnf = vnf->pnfs; + nfapi_param_request_t req; + + printf("[VNF] Sending NFAPI_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); + + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PARAM_REQUEST; + req.header.phy_id = pnf->phys[0].id; + + nfapi_vnf_param_req(config, p5_idx, &req); + } +#endif + + return 0; +} + +extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw); + +int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp) +{ + printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + vnf_info* vnf = (vnf_info*)(config->user_data); + +#if 0 + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item) + { return item.id == resp->header.phy_id; }); + + if(found != pnf.phys.end()) + { + phy_info& phy = (*found); +#else + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + { + { +#endif + + phy->remote_port = resp->nfapi_config.p7_pnf_port.value; + + struct sockaddr_in pnf_p7_sockaddr; + memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); + + phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); + + // for now just 1 + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + + printf("[VNF] %d.%d pnf p7 %s:%d timing %d %d %d %d\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period); + + nfapi_config_request_t *req = &RC.mac[0]->config[0]; + + //memset(&req, 0, sizeof(req)); + req->header.message_id = NFAPI_CONFIG_REQUEST; + req->header.phy_id = phy->id; + + printf("[VNF] Send NFAPI_CONFIG_REQUEST\n"); + + req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; + req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; + req->num_tlv++; + +printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port); + + req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + struct sockaddr_in vnf_p7_sockaddr; + vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr); + memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); + req->num_tlv++; +printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); + + req->nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG; + req->nfapi_config.timing_window.value = p7_vnf->timing_window; + req->num_tlv++; + + if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) + { + req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NFAPI_TIMING_INFO_MODE_TAG; + req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled); + req->num_tlv++; + + if(p7_vnf->periodic_timing_enabled) + { + req->nfapi_config.timing_info_period.tl.tag = NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG; + req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period; + req->num_tlv++; + } + } + +#if 0 + req->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; + req->nfapi_config.earfcn.value = phy->earfcn; + req->num_tlv++; +#endif + + //req->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; + //req->rf_config.dl_channel_bandwidth.value = RC.eNB[0][0]->frame_parms.N_RB_DL; + //req->num_tlv++; + + //req->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; + //req->rf_config.ul_channel_bandwidth.value = RC.eNB[0][0]->frame_parms.N_RB_UL; + //req->num_tlv++; + + //req->nfapi_config.rf_bands.tl.tag = NFAPI_NFAPI_RF_BANDS_TAG; + //req->nfapi_config.rf_bands.number_rf_bands = 1; + //req->nfapi_config.rf_bands.rf_band[0] = RC.eNB[0][0]->frame_parms.eutra_band; + //req->num_tlv++; + + //req->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; + //req->nfapi_config.earfcn.value = to_earfcn(RC.eNB[0][0]->frame_parms.eutra_band, RC.eNB[0][0]->frame_parms.dl_CarrierFreq, RC.eNB[0][0]->frame_parms.N_RB_DL); + //req->num_tlv++; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() EARFCN:%u BAND:%u dlCarrierFreq:%u N_RB_DL:%u (NFAPI:%d)\n", + __FUNCTION__, req->nfapi_config.earfcn.value, RC.eNB[0][0]->frame_parms.eutra_band, RC.eNB[0][0]->frame_parms.dl_CarrierFreq, RC.eNB[0][0]->frame_parms.N_RB_DL, req->rf_config.ul_channel_bandwidth.value); + + + + //RC.eNB[0][0]->frame_parms.ul_CarrierFreq = req->nfapi_config.earfcn.value; + + //req->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + //req->subframe_config.duplex_mode.value = RC.eNB[0][0]->frame_parms.frame_type; + //req->num_tlv++; + + //req->subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; + //req->subframe_config.dl_cyclic_prefix_type.value = RC.eNB[0][0]->frame_parms.Ncp; + //req->num_tlv++; + + //req->subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; + //req->subframe_config.ul_cyclic_prefix_type.value = RC.eNB[0][0]->frame_parms.Ncp_UL; + //req->num_tlv++; + + //RC.eNB[0][0]->frame_parms.num_MBSFN_config = 0; // DJP - hard code alert + + //req->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; + //req->sch_config.physical_cell_id.value = RC.eNB[0][0]->frame_parms.Nid_cell; + //req->num_tlv++; + + //req->rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; + //req->rf_config.tx_antenna_ports.value = RC.eNB[0][0]->frame_parms.nb_antennas_tx; + //req->num_tlv++; + //RC.eNB[0][0]->frame_parms.nb_antenna_ports_eNB = 1; + + //req->rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; + //req->rf_config.rx_antenna_ports.value = RC.eNB[0][0]->frame_parms.nb_antennas_rx; + + //RC.eNB[0][0]->frame_parms.nushift = 0; + + //req->phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; + //req->phich_config.phich_resource.value = RC.eNB[0][0]->frame_parms.phich_config_common.phich_resource; + //req->num_tlv++; + + //req->phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; + //req->phich_config.phich_duration.value = RC.eNB[0][0]->frame_parms.phich_config_common.phich_duration; + //req->num_tlv++; + + // DJP - not supported in OAI + //req->phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; + //req->phich_config.phich_power_offset.value = RC.eNB[0][0]->frame_parms.phich_config_common. + //req->num_tlv++; + + // UL RS Config + //req->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; + //req->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift; + //req->num_tlv++; + + //req->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; + //req->uplink_reference_signal_config.uplink_rs_hopping.value = RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; + //req->num_tlv++; + + //req->uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; + //req->uplink_reference_signal_config.group_assignment.value = RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; + //req->num_tlv++; + + //if (req->pusch_config.hopping_mode.tl.tag == NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG) { } // DJP - not being handled? + + //RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; // DJP - not being handled + + //req->prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; + //req->prach_config.configuration_index.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; + //req->num_tlv++; + + //req->prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; + //req->prach_config.root_sequence_index.value = RC.eNB[0][0]->frame_parms.prach_config_common.rootSequenceIndex; + //req->num_tlv++; + + //req->prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + //req->prach_config.zero_correlation_zone_configuration.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; + //req->num_tlv++; + + //req->prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; + //req->prach_config.high_speed_flag.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag; + //req->num_tlv++; + + //req->prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; + //req->prach_config.frequency_offset.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; + //req->num_tlv++; + + vendor_ext_tlv_2 ve2; + memset(&ve2, 0, sizeof(ve2)); + ve2.tl.tag = VENDOR_EXT_TLV_2_TAG; + ve2.dummy = 2016; + req->vendor_extension = &ve2.tl; + + nfapi_vnf_config_req(config, p5_idx, req); + printf("[VNF] Sent NFAPI_CONFIG_REQ num_tlv:%u\n",req->num_tlv); + } +#if 0 + else + { + printf("[VNF] param response failed to find pnf %d phy %d\n", p5_idx, resp->header.phy_id); + } +#endif + } +#if 0 + else + { + printf("[VNF] param response failed to find pnf %d\n", p5_idx); + } +#endif + + return 0; +} + +int config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp) +{ + nfapi_start_request_t req; + + printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + printf("[VNF] Calling oai_enb_init()\n"); + oai_enb_init(); + + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_START_REQUEST; + req.header.phy_id = resp->header.phy_id; + nfapi_vnf_start_req(config, p5_idx, &req); + + printf("[VNF] Send NFAPI_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + return 0; +} + +void test_p4_requests(nfapi_vnf_config_t* config, int p5_idx, int phy_id) +{ +#if 0 + { + nfapi_measurement_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_MEASUREMENT_REQUEST; + req.header.phy_id = phy_id; + + req.dl_rs_tx_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG; + req.dl_rs_tx_power.value = 42; + req.received_interference_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG; + req.received_interference_power.value = 42; + req.thermal_noise_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG; + req.thermal_noise_power.value = 42; + + nfapi_vnf_measurement_req(config, p5_idx, &req); + } + { + nfapi_rssi_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_RSSI_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_rssi_request.tl.tag = NFAPI_LTE_RSSI_REQUEST_TAG; + lte_req.lte_rssi_request.frequency_band_indicator = 2; + lte_req.lte_rssi_request.measurement_period = 1000; + lte_req.lte_rssi_request.bandwidth = 50; + lte_req.lte_rssi_request.timeout = 0; + lte_req.lte_rssi_request.number_of_earfcns = 2; + lte_req.lte_rssi_request.earfcn[0] = 389; + lte_req.lte_rssi_request.earfcn[1] = 123; + + nfapi_vnf_rssi_request(config, p5_idx, <e_req); + + nfapi_rssi_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_RSSI_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_rssi_request.tl.tag = NFAPI_UTRAN_RSSI_REQUEST_TAG; + utran_req.utran_rssi_request.frequency_band_indicator = 2; + utran_req.utran_rssi_request.measurement_period = 1000; + utran_req.utran_rssi_request.timeout = 0; + utran_req.utran_rssi_request.number_of_uarfcns = 2; + utran_req.utran_rssi_request.uarfcn[0] = 2348; + utran_req.utran_rssi_request.uarfcn[1] = 52; + + nfapi_vnf_rssi_request(config, p5_idx, &utran_req); + + + nfapi_rssi_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_RSSI_REQUEST; + geran_req.header.phy_id = phy_id; + + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_rssi_request.tl.tag = NFAPI_GERAN_RSSI_REQUEST_TAG; + geran_req.geran_rssi_request.frequency_band_indicator = 2; + geran_req.geran_rssi_request.measurement_period = 1000; + geran_req.geran_rssi_request.timeout = 0; + geran_req.geran_rssi_request.number_of_arfcns = 1; + geran_req.geran_rssi_request.arfcn[0].arfcn = 34; + geran_req.geran_rssi_request.arfcn[0].direction = 0; + + nfapi_vnf_rssi_request(config, p5_idx, &geran_req); + } + { + nfapi_cell_search_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_cell_search_request.tl.tag = NFAPI_LTE_CELL_SEARCH_REQUEST_TAG; + lte_req.lte_cell_search_request.earfcn = 1234; + lte_req.lte_cell_search_request.measurement_bandwidth = 50; + lte_req.lte_cell_search_request.exhaustive_search = 1; + lte_req.lte_cell_search_request.timeout = 1000; + lte_req.lte_cell_search_request.number_of_pci = 1; + lte_req.lte_cell_search_request.pci[0] = 234; + + nfapi_vnf_cell_search_request(config, p5_idx, <e_req); + + nfapi_cell_search_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_cell_search_request.tl.tag = NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG; + utran_req.utran_cell_search_request.uarfcn = 1234; + utran_req.utran_cell_search_request.exhaustive_search = 0; + utran_req.utran_cell_search_request.timeout = 1000; + utran_req.utran_cell_search_request.number_of_psc = 1; + utran_req.utran_cell_search_request.psc[0] = 234; + + nfapi_vnf_cell_search_request(config, p5_idx, &utran_req); + + nfapi_cell_search_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + geran_req.header.phy_id = phy_id; + + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_cell_search_request.tl.tag = NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG; + geran_req.geran_cell_search_request.timeout = 1000; + geran_req.geran_cell_search_request.number_of_arfcn = 1; + geran_req.geran_cell_search_request.arfcn[0] = 8765; + + nfapi_vnf_cell_search_request(config, p5_idx, &geran_req); + } + { + nfapi_broadcast_detect_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_broadcast_detect_request.tl.tag = NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG; + lte_req.lte_broadcast_detect_request.earfcn = 1234; + lte_req.lte_broadcast_detect_request.pci = 50; + lte_req.lte_broadcast_detect_request.timeout = 1000; + + lte_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + lte_req.pnf_cell_search_state.length = 3; + + nfapi_vnf_broadcast_detect_request(config, p5_idx, <e_req); + + nfapi_broadcast_detect_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_LTE; + utran_req.utran_broadcast_detect_request.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG; + utran_req.utran_broadcast_detect_request.uarfcn = 1234; + utran_req.utran_broadcast_detect_request.psc = 50; + utran_req.utran_broadcast_detect_request.timeout = 1000; + + utran_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + utran_req.pnf_cell_search_state.length = 3; + + nfapi_vnf_broadcast_detect_request(config, p5_idx, &utran_req); + } + { + nfapi_system_information_schedule_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_system_information_schedule_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG; + lte_req.lte_system_information_schedule_request.earfcn = 1234; + lte_req.lte_system_information_schedule_request.pci = 50; + lte_req.lte_system_information_schedule_request.downlink_channel_bandwidth = 100; + lte_req.lte_system_information_schedule_request.phich_configuration = 3; + lte_req.lte_system_information_schedule_request.number_of_tx_antenna = 2; + lte_req.lte_system_information_schedule_request.retry_count = 4; + lte_req.lte_system_information_schedule_request.timeout = 1000; + + lte_req.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + lte_req.pnf_cell_broadcast_state.length = 3; + + nfapi_vnf_system_information_schedule_request(config, p5_idx, <e_req); + } + { + nfapi_system_information_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_system_information_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG; + lte_req.lte_system_information_request.earfcn = 1234; + lte_req.lte_system_information_request.pci= 456; + lte_req.lte_system_information_request.downlink_channel_bandwidth = 5; + lte_req.lte_system_information_request.phich_configuration = 2; + lte_req.lte_system_information_request.number_of_tx_antenna = 2; + lte_req.lte_system_information_request.number_of_si_periodicity = 1; + lte_req.lte_system_information_request.si_periodicity[0].si_periodicity = 3; + lte_req.lte_system_information_request.si_periodicity[0].si_index = 3; + lte_req.lte_system_information_request.si_window_length = 15; + lte_req.lte_system_information_request.timeout = 1000; + + nfapi_vnf_system_information_request(config, p5_idx, <e_req); + + nfapi_system_information_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_system_information_request.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG; + utran_req.utran_system_information_request.uarfcn = 1234; + utran_req.utran_system_information_request.psc = 456; + utran_req.utran_system_information_request.timeout = 1000; + + nfapi_vnf_system_information_request(config, p5_idx, &utran_req); + + nfapi_system_information_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + geran_req.header.phy_id = phy_id; + + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_system_information_request.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG; + geran_req.geran_system_information_request.arfcn = 1234; + geran_req.geran_system_information_request.bsic = 21; + geran_req.geran_system_information_request.timeout = 1000; + + nfapi_vnf_system_information_request(config, p5_idx, &geran_req); + } + { + nfapi_nmm_stop_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NMM_STOP_REQUEST; + req.header.phy_id = phy_id; + nfapi_vnf_nmm_stop_request(config, p5_idx, &req); + } +#endif +} + +int start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp) +{ + printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + vnf_info* vnf = (vnf_info*)(config->user_data); + + if(vnf->wireshark_test_mode) + test_p4_requests(config, p5_idx, resp->header.phy_id); + +#if 0 + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + + auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item) + { return item.id == resp->header.phy_id; }); + + if(found != pnf.phys.end()) + { + phy_info& phy = (*found); + + vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; + + nfapi_vnf_p7_add_pnf((p7_vnf.config.get()), phy.remote_addr.c_str(), phy.remote_port, phy.id); + + } + } +#else + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id); + + +#if 0 + { + extern pthread_cond_t nfapi_sync_cond; + extern pthread_mutex_t nfapi_sync_mutex; + extern int nfapi_sync_var; + + printf("[VNF] Signal to OAI main code that it can go\n"); + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var=0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + } +#endif + +#endif + + return 0; +} + +int vendor_ext_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg) +{ + printf("[VNF] %s\n", __FUNCTION__); + + switch(msg->message_id) + { + case P5_VENDOR_EXT_RSP: + { + vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)msg; + printf("[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); + + // send the start request + + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } + break; + } + + return 0; +} + +int vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_RSP) + { + vendor_ext_p5_rsp* req = (vendor_ext_p5_rsp*)(header); + return(!pull16(ppReadPackedMessage, &req->error_code, end)); + } + return 0; +} + +nfapi_p4_p5_message_header_t* vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P5_VENDOR_EXT_RSP) + { + *msg_size = sizeof(vendor_ext_p5_rsp); + return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_rsp)); + } + return 0; +} + +void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) +{ + free(header); +} + +nfapi_vnf_config_t *config = 0; + +void vnf_start_thread(void* ptr) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__); + + config = (nfapi_vnf_config_t*)ptr; + + nfapi_vnf_start(config); +} + +static vnf_info vnf; +/*------------------------------------------------------------------------------*/ +void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) +{ + memset(&vnf, 0, sizeof(vnf)); + + memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs)); + + vnf.p7_vnfs[0].timing_window = 32; + vnf.p7_vnfs[0].periodic_timing_enabled = 1; + vnf.p7_vnfs[0].aperiodic_timing_enabled = 0; + vnf.p7_vnfs[0].periodic_timing_period = 10; + + vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create(); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port); + + strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr); + vnf.p7_vnfs[0].local_port = 50001; + vnf.p7_vnfs[0].mac = (mac_t*)malloc(sizeof(mac_t)); + + nfapi_vnf_config_t* config = nfapi_vnf_config_create(); + + config->malloc = malloc; + config->free = free; + config->trace = &vnf_trace; + + config->vnf_p5_port = vnf_p5_port; + config->vnf_ipv4 = 1; + config->vnf_ipv6 = 0; + + config->pnf_list = 0; + config->phy_list = 0; + + config->pnf_connection_indication = &pnf_connection_indication_cb; + config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; + config->pnf_param_resp = &pnf_param_resp_cb; + config->pnf_config_resp = &pnf_config_resp_cb; + config->pnf_start_resp = &pnf_start_resp_cb; + config->param_resp = ¶m_resp_cb; + config->config_resp = &config_resp_cb; + config->start_resp = &start_resp_cb; + config->vendor_ext = &vendor_ext_cb; + + config->user_data = &vnf; + + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv; + + config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension; + config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext; + config->codec_config.allocate = &vnf_allocate; + config->codec_config.deallocate = &vnf_deallocate; + + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&vnf_start_pthread, NULL, (void*)&vnf_start_thread, config); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__); + } +} + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) +{ + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + //dl_config_req->header.message_id = NFAPI_DL_CONFIG_BCH_PDU_TYPE; + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() header message_id:%d\n", __FUNCTION__, dl_config_req->header.message_id); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() p7_config:%p phy_id:%d message_id:%d sfn_sf:%d pdcch:%d dci:%d pdu:%d pdsch_rnti:%d pcfich:%d\n", __FUNCTION__, p7_config, dl_config_req->header.phy_id, dl_config_req->header.message_id, dl_config_req->sfn_sf, dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols, dl_config_req->dl_config_request_body.number_dci, dl_config_req->dl_config_request_body.number_pdu, dl_config_req->dl_config_request_body.number_pdsch_rnti, dl_config_req->dl_config_request_body.transmission_power_pcfich); + + return nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req); +} + +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) +{ + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + tx_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + //dl_config_req->header.message_id = NFAPI_DL_CONFIG_BCH_PDU_TYPE; + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() p7_config:%p phy_id:%d message_id:%d sfn_sf:%d pdcch:%d dci:%d pdu:%d pdsch_rnti:%d pcfich:%d\n", __FUNCTION__, p7_config, dl_config_req->header.phy_id, dl_config_req->header.message_id, dl_config_req->sfn_sf, dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols, dl_config_req->dl_config_request_body.number_dci, dl_config_req->dl_config_request_body.number_pdu, dl_config_req->dl_config_request_body.number_pdsch_rnti, dl_config_req->dl_config_request_body.transmission_power_pcfich); + + return nfapi_vnf_p7_tx_req(p7_config, tx_req); +} diff --git a/nfapi/nfapi_vnf.h b/nfapi/nfapi_vnf.h new file mode 100644 index 0000000000000000000000000000000000000000..5a608d49555c22a5d2fed4436cfa4465545dc09b --- /dev/null +++ b/nfapi/nfapi_vnf.h @@ -0,0 +1,6 @@ +#if !defined(NFAPI_VNF_H__) +#define NFAPI_VNF_H__ + +void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port); + +#endif diff --git a/nfapi/vendor_ext.h b/nfapi/vendor_ext.h new file mode 100644 index 0000000000000000000000000000000000000000..d0fd57837d2eef4650700eb58399c0249eb68918 --- /dev/null +++ b/nfapi/vendor_ext.h @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _VENDOR_EXT_H_ +#define _VENDOR_EXT_H_ + +#include "nfapi_interface.h" + +typedef enum +{ + P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN, + P5_VENDOR_EXT_RSP, + + P7_VENDOR_EXT_REQ, + P7_VENDOR_EXT_IND + +} vendor_ext_message_id_e; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; +} vendor_ext_p5_req; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint16_t error_code; +} vendor_ext_p5_rsp; + +typedef struct { + nfapi_p7_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; +} vendor_ext_p7_req; + +typedef struct { + nfapi_p7_message_header_t header; + uint16_t error_code; +} vendor_ext_p7_ind; + +typedef struct { + nfapi_tl_t tl; + uint32_t dummy; +} vendor_ext_tlv_1; + +#define VENDOR_EXT_TLV_1_TAG 0xF001 + +typedef struct { + nfapi_tl_t tl; + uint32_t dummy; +} vendor_ext_tlv_2; + +#define VENDOR_EXT_TLV_2_TAG 0xF002 + + + + +#endif // _VENDOR_EXT_ diff --git a/oaienv b/oaienv index f6b298debf69e2e24c2c65cce458291b9ff0a513..aa4bce9e78a513b7114f088b9062ebda10186af0 100644 --- a/oaienv +++ b/oaienv @@ -17,3 +17,12 @@ alias oait='cd $OPENAIR_TARGETS' alias oailte='cd $OPENAIR_TARGETS/RT/USER' alias oais='cd $OPENAIR_TARGETS/SIMU/USER' alias oaiex='cd $OPENAIR_TARGETS/SIMU/EXAMPLES' + +#export NFAPI_DIR=/home/nfapi-001/open-nFAPI/nfapi/public_inc +export NFAPI_DIR=/home/nfapi-001/open-nFAPI + +alias bld='cd $OPENAIR_HOME/cmake_targets ; ./build_oai --eNB -x -w USRP' +alias b='cd $OPENAIR_HOME/cmake_targets ; ./build_oai --eNB -x -w USRP' +alias run='cd $OPENAIR_HOME/cmake_targets/lte_build_oai/build' +alias nf='cd $OPENAIR_HOME/nfapi' +alias conf='cd $OPENAIR_HOME/targets/PROJECTS/GENERIC-LTE-EPC/CONF' diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 3a7eab5a5d7fe4874e17c00368cdaff93fdc5e98..832ba0ce5de236f74300366810423b92f9a9cf69 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -42,24 +42,37 @@ int N_RB_DL_array[6] = {6,15,25,50,75,100}; int l1_north_init_eNB() { int i,j; - AssertFatal(RC.nb_L1_inst>0,"nb_L1_inst=%d\n",RC.nb_L1_inst); - AssertFatal(RC.nb_L1_CC!=NULL,"nb_L1_CC is null\n"); - AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n"); - for (i=0;i<RC.nb_L1_inst;i++) { - AssertFatal(RC.eNB[i]!=NULL,"RC.eNB[%d] is null\n",i); - AssertFatal(RC.nb_L1_CC[i]>0,"RC.nb_L1_CC[%d]=%d\n",i,RC.nb_L1_CC[i]); - for (j=0;j<RC.nb_L1_CC[i];j++) { - AssertFatal(RC.eNB[i][j]!=NULL,"RC.eNB[%d][%d] is null\n",i,j); - if ((RC.eNB[i][j]->if_inst = IF_Module_init(i))<0) return(-1); - RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request; - RC.eNB[i][j]->if_inst->schedule_response = schedule_response; + + if (RC.nb_L1_inst > 0 && RC.nb_L1_CC != NULL && RC.eNB != NULL) + { + AssertFatal(RC.nb_L1_inst>0,"nb_L1_inst=%d\n",RC.nb_L1_inst); + AssertFatal(RC.nb_L1_CC!=NULL,"nb_L1_CC is null\n"); + AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n"); + + LOG_I(PHY,"%s() RC.nb_L1_inst:%d\n", __FUNCTION__, RC.nb_L1_inst); + + for (i=0;i<RC.nb_L1_inst;i++) { + AssertFatal(RC.eNB[i]!=NULL,"RC.eNB[%d] is null\n",i); + AssertFatal(RC.nb_L1_CC[i]>0,"RC.nb_L1_CC[%d]=%d\n",i,RC.nb_L1_CC[i]); + + LOG_I(PHY,"%s() RC.nb_L1_CC[%d]:%d\n", __FUNCTION__, i, RC.nb_L1_CC[i]); + + for (j=0;j<RC.nb_L1_CC[i];j++) { + AssertFatal(RC.eNB[i][j]!=NULL,"RC.eNB[%d][%d] is null\n",i,j); + + if ((RC.eNB[i][j]->if_inst = IF_Module_init(i))<0) return(-1); + + LOG_I(PHY,"%s() RC.eNB[%d][%d] installing callbacks\n", __FUNCTION__, i, j); + + RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request; + RC.eNB[i][j]->if_inst->schedule_response = schedule_response; + } } } return(0); } - void phy_config_request(PHY_Config_t *phy_config) { uint8_t Mod_id = phy_config->Mod_id; @@ -71,13 +84,14 @@ void phy_config_request(PHY_Config_t *phy_config) { PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two}; int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0]; int dl_Bandwidth = cfg->rf_config.dl_channel_bandwidth.value; + int ul_Bandwidth = cfg->rf_config.ul_channel_bandwidth.value; int Nid_cell = cfg->sch_config.physical_cell_id.value; int Ncp = cfg->subframe_config.dl_cyclic_prefix_type.value; int p_eNB = cfg->rf_config.tx_antenna_ports.value; uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value; - LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", - Mod_id, CC_id, eutra_band, N_RB_DL_array[dl_Bandwidth], Nid_cell, p_eNB,Ncp,dl_CarrierFreq, + LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,eNB_tx_antenna_ports %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", + Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq, cfg->phich_config.phich_resource.value, cfg->phich_config.phich_duration.value); @@ -91,8 +105,8 @@ void phy_config_request(PHY_Config_t *phy_config) { fp = &RC.eNB[Mod_id][CC_id]->frame_parms; - fp->N_RB_DL = N_RB_DL_array[dl_Bandwidth]; - fp->N_RB_UL = N_RB_DL_array[dl_Bandwidth]; + fp->N_RB_DL = dl_Bandwidth; + fp->N_RB_UL = ul_Bandwidth; fp->Nid_cell = Nid_cell; fp->nushift = fp->Nid_cell%6; fp->eutra_band = eutra_band; @@ -153,93 +167,95 @@ void phy_config_request(PHY_Config_t *phy_config) { RC.eNB[Mod_id][CC_id]->X_u); #ifdef Rel14 - if (cfg->emtc_config.prach_ce_level_0_enable.value == 1) { - fp->prach_emtc_config_common.prach_Config_enabled=1; - - fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; - - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag = cfg->emtc_config.prach_catm_high_speed_flag.value; - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value; - - // CE Level 3 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] = cfg->emtc_config.prach_ce_level_3_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3] = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3], - "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n"); - - - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3] = cfg->emtc_config.prach_ce_level_3_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3] = cfg->emtc_config.prach_ce_level_3_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3] = cfg->emtc_config.prach_ce_level_3_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3] = cfg->emtc_config.prach_ce_level_3_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[3]); - - // CE Level 2 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] = cfg->emtc_config.prach_ce_level_2_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2] = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2], - "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2] = cfg->emtc_config.prach_ce_level_2_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2] = cfg->emtc_config.prach_ce_level_2_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2] = cfg->emtc_config.prach_ce_level_2_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2] = cfg->emtc_config.prach_ce_level_2_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[2]); - - // CE Level 1 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] = cfg->emtc_config.prach_ce_level_1_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1] = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1], - "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n"); - - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1] = cfg->emtc_config.prach_ce_level_1_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1] = cfg->emtc_config.prach_ce_level_1_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1] = cfg->emtc_config.prach_ce_level_1_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1] = cfg->emtc_config.prach_ce_level_1_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[1]); + fp->prach_emtc_config_common.prach_Config_enabled=1; + + fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; + + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag = cfg->emtc_config.prach_catm_high_speed_flag.value; + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value; + + // CE Level 3 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] = cfg->emtc_config.prach_ce_level_3_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3] = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3], + "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n"); + + + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3] = cfg->emtc_config.prach_ce_level_3_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3] = cfg->emtc_config.prach_ce_level_3_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3] = cfg->emtc_config.prach_ce_level_3_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3] = cfg->emtc_config.prach_ce_level_3_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[3]); + + // CE Level 2 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] = cfg->emtc_config.prach_ce_level_2_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2] = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2], + "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n"); + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2] = cfg->emtc_config.prach_ce_level_2_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2] = cfg->emtc_config.prach_ce_level_2_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2] = cfg->emtc_config.prach_ce_level_2_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2] = cfg->emtc_config.prach_ce_level_2_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[2]); + + // CE Level 1 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] = cfg->emtc_config.prach_ce_level_1_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1] = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1], + "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n"); + + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1] = cfg->emtc_config.prach_ce_level_1_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1] = cfg->emtc_config.prach_ce_level_1_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1] = cfg->emtc_config.prach_ce_level_1_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1] = cfg->emtc_config.prach_ce_level_1_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[1]); - // CE Level 0 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] = cfg->emtc_config.prach_ce_level_0_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0] = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], - "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n", - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0], - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]); - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0, - "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0] = cfg->emtc_config.prach_ce_level_0_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0] = cfg->emtc_config.prach_ce_level_0_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0] = cfg->emtc_config.prach_ce_level_0_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0] = cfg->emtc_config.prach_ce_level_0_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[0]); - } + // CE Level 0 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] = cfg->emtc_config.prach_ce_level_0_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0] = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], + "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n", + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0], + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]); +#if 0 + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0, + "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n"); +#else + LOG_E(PHY,"***DJP*** removed assert on preamble fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]:%d expecting >0 %s:%d\n\n\n", fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], __FILE__, __LINE__); +#endif + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0] = cfg->emtc_config.prach_ce_level_0_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0] = cfg->emtc_config.prach_ce_level_0_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0] = cfg->emtc_config.prach_ce_level_0_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0] = cfg->emtc_config.prach_ce_level_0_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[0]); #endif @@ -266,9 +282,9 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 1) - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 2) - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1; LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = cfg->uplink_reference_signal_config.group_assignment.value; LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); @@ -315,14 +331,14 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id, } /* - void phy_config_sib2_eNB(uint8_t Mod_id, - int CC_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CArrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) - { +void phy_config_sib2_eNB(uint8_t Mod_id, + int CC_id, + RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + ARFCN_ValueEUTRA_t *ul_CArrierFreq, + long *ul_Bandwidth, + AdditionalSpectrumEmission_t *additionalSpectrumEmission, + struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) +{ LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; //LTE_eNB_UE_stats *eNB_UE_stats = RC.eNB[Mod_id][CC_id].eNB_UE_stats; @@ -349,7 +365,7 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id, init_prach_tables(839); compute_prach_seq(&fp->prach_config_common,fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u); + RC.eNB[Mod_id][CC_id]->X_u); fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift; fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI; @@ -391,15 +407,15 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id, fp->soundingrs_ul_config_common.enabled_flag = 0; if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { - fp->soundingrs_ul_config_common.enabled_flag = 1; - fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; - fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; - fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + fp->soundingrs_ul_config_common.enabled_flag = 1; + fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; + fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; + fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) - fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; - else - fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) + fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; + else + fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; } @@ -427,34 +443,34 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id, // MBSFN if (mbsfn_SubframeConfigList != NULL) { - fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; - - for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { - fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; - fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; - - if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { - fp->MBSFN_config[i].fourFrames_flag = 0; - fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration - fp->MBSFN_config[i].fourFrames_flag = 1; - fp->MBSFN_config[i].mbsfn_SubframeConfig = - mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); - - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } - } + fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; + + for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { + fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; + fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; + + if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + fp->MBSFN_config[i].fourFrames_flag = 0; + fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + fp->MBSFN_config[i].fourFrames_flag = 1; + fp->MBSFN_config[i].mbsfn_SubframeConfig = + mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); + + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } + } } else - fp->num_MBSFN_config = 0; + fp->num_MBSFN_config = 0; // - } +} */ void phy_config_sib2_ue(uint8_t Mod_id,int CC_id, @@ -854,7 +870,7 @@ void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobility PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); } if(ho_failed) { @@ -883,67 +899,67 @@ void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n } /* - void phy_config_dedicated_eNB(uint8_t Mod_id, - int CC_id, - uint16_t rnti, - struct PhysicalConfigDedicated *physicalConfigDedicated) - { +void phy_config_dedicated_eNB(uint8_t Mod_id, + int CC_id, + uint16_t rnti, + struct PhysicalConfigDedicated *physicalConfigDedicated) +{ PHY_VARS_eNB *eNB = RC.eNB[Mod_id][CC_id]; int8_t UE_id = find_ue(rnti,eNB); int i; if (UE_id == -1) { - LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id); - return; + LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id); + return; } if (physicalConfigDedicated) { - eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated; - LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated); - - if (physicalConfigDedicated->antennaInfo) { - switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case AntennaInfoDedicated__transmissionMode_tm1: - eNB->transmission_mode[UE_id] = 1; - break; - case AntennaInfoDedicated__transmissionMode_tm2: - eNB->transmission_mode[UE_id] = 2; - break; - case AntennaInfoDedicated__transmissionMode_tm3: - eNB->transmission_mode[UE_id] = 3; - break; - case AntennaInfoDedicated__transmissionMode_tm4: - eNB->transmission_mode[UE_id] = 4; - break; - case AntennaInfoDedicated__transmissionMode_tm5: - eNB->transmission_mode[UE_id] = 5; - break; - case AntennaInfoDedicated__transmissionMode_tm6: - eNB->transmission_mode[UE_id] = 6; - break; - case AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti); - - for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1; - eNB->transmission_mode[UE_id] = 7; - break; - default: - LOG_E(PHY,"Unknown transmission mode!\n"); - break; - } - LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]); + eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated; + LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated); + if (physicalConfigDedicated->antennaInfo) { + switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { + case AntennaInfoDedicated__transmissionMode_tm1: + eNB->transmission_mode[UE_id] = 1; + break; + case AntennaInfoDedicated__transmissionMode_tm2: + eNB->transmission_mode[UE_id] = 2; + break; + case AntennaInfoDedicated__transmissionMode_tm3: + eNB->transmission_mode[UE_id] = 3; + break; + case AntennaInfoDedicated__transmissionMode_tm4: + eNB->transmission_mode[UE_id] = 4; + break; + case AntennaInfoDedicated__transmissionMode_tm5: + eNB->transmission_mode[UE_id] = 5; + break; + case AntennaInfoDedicated__transmissionMode_tm6: + eNB->transmission_mode[UE_id] = 6; + break; + case AntennaInfoDedicated__transmissionMode_tm7: + lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti); + + for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1; + eNB->transmission_mode[UE_id] = 7; + break; + default: + LOG_E(PHY,"Unknown transmission mode!\n"); + break; + } + LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]); + + } else { + LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id); + } } else { - LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id); - } - } else { - LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id); - return; + LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id); + return; } - } +} */ #if defined(Rel10) || defined(Rel14) @@ -955,11 +971,11 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id, } /* - void phy_config_dedicated_scell_eNB(uint8_t Mod_id, - uint16_t rnti, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id) - { +void phy_config_dedicated_scell_eNB(uint8_t Mod_id, + uint16_t rnti, + SCellToAddMod_r10_t *sCellToAddMod_r10, + int CC_id) +{ uint8_t UE_id = find_ue(rnti,RC.eNB[Mod_id][0]); @@ -970,37 +986,37 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint32_t carrier_freq_local; if ((dl_CarrierFreq_r10>=36000) && (dl_CarrierFreq_r10<=36199)) { - carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1 - LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, - //eNB->frame - 0, - CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); + carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1 + LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, + //eNB->frame + 0, + CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); } else if ((dl_CarrierFreq_r10>=6150) && (dl_CarrierFreq_r10<=6449)) { - carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1 - // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band - LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, - //eNB->frame - 0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); + carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1 + // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band + LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, + //eNB->frame + 0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); } else { - LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id, - //eNB->frame - 0,dl_CarrierFreq_r10,CC_id,UE_id); + LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id, + //eNB->frame + 0,dl_CarrierFreq_r10,CC_id,UE_id); } if (physicalConfigDedicatedSCell_r10) { - //#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB" - // eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10; - LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id, - //eNB->frame - 0,CC_id,UE_id); +//#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB" + // eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10; + LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id, + //eNB->frame + 0,CC_id,UE_id); } else { - LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, - //eNB->frame - 0,CC_id,UE_id); - return; + LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, + //eNB->frame + 0,CC_id,UE_id); + return; } - } +} */ #endif @@ -1174,7 +1190,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, } if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { - // configure PUCCH CQI reporting + // configure PUCCH CQI reporting phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) @@ -1213,12 +1229,12 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->decode_MIB = 0; //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) - phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; else - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); } @@ -1655,7 +1671,7 @@ int phy_init_RU(RU_t *ru) { ru->common.txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i], - fp->samples_per_tti*10*sizeof(int32_t)); + fp->samples_per_tti*10*sizeof(int32_t)); } for (i=0;i<ru->nb_rx;i++) { @@ -1720,11 +1736,18 @@ int phy_init_RU(RU_t *ru) { // antenna ports 5-14 are mapped on all antennas if (((i<4) && (i==j)) || ((i==4) && (j==0))) { for (re=0; re<fp->ofdm_symbol_size; re++) + { ru->beam_weights[i][p][j][re] = 0x00007fff; + + LOG_E(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); + } } else if (i>4) { for (re=0; re<fp->ofdm_symbol_size; re++) + { ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; + LOG_E(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); + } } LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], @@ -1755,6 +1778,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, #endif int i, eNB_id, UE_id; + LOG_I(PHY,"[eNB %d] %s() About to wait for eNB to be configured", eNB->Mod_id, __FUNCTION__); eNB->total_dlsch_bitrate = 0; eNB->total_transmitted_bits = 0; @@ -1763,10 +1787,18 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, while(eNB->configured == 0) usleep(10000); - LOG_I(PHY,"[eNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d\n", + LOG_I(PHY,"[eNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u nb_antenna_ports_eNB:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n", eNB->Mod_id, fp->N_RB_DL,fp->phich_config_common.phich_resource, - fp->phich_config_common.phich_duration); + fp->phich_config_common.phich_duration, + fp->nb_antennas_tx, fp->nb_antennas_rx, fp->nb_antenna_ports_eNB, + fp->prach_config_common.rootSequenceIndex, + fp->prach_config_common.prach_Config_enabled, + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset + ); LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_eNB][MOD %02"PRIu8"][]\n", eNB->Mod_id); @@ -1793,11 +1825,13 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*)); common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*)); + LOG_D(PHY,"[INIT] NB_ANTENNA_PORTS_ENB:%d fp->nb_antenna_ports_eNB:%d\n", NB_ANTENNA_PORTS_ENB, fp->nb_antenna_ports_eNB); + for (i=0; i<NB_ANTENNA_PORTS_ENB; i++) { if (i<fp->nb_antenna_ports_eNB || i==5) { common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); - LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", + LOG_E(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", i,common_vars->txdataF[i], fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t)); } @@ -1845,12 +1879,12 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, #endif /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) - AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]), - "nb_antennas_rx too large"); - for (i=0; i<fp->nb_antennas_rx; i++) { - prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); - LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]); - }*/ + AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]), + "nb_antennas_rx too large"); + for (i=0; i<fp->nb_antennas_rx; i++) { + prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); + LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]); + }*/ for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { @@ -1878,7 +1912,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); - } + } pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); } //UE_id @@ -1893,3 +1927,9 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, return (0); } + +void install_schedule_handlers(IF_Module_t *if_inst) +{ + if_inst->PHY_config_req = phy_config_request; + if_inst->schedule_response = schedule_response; +} diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c index 603c92d69f121b8384d6eda2c8d7bd5e1121200c..d25cd7cc9369b649a708b39750b9fa1f85506ead 100644 --- a/openair1/PHY/LTE_TRANSPORT/pbch.c +++ b/openair1/PHY/LTE_TRANSPORT/pbch.c @@ -174,6 +174,8 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, pbch_E = (frame_parms->Ncp==NORMAL) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK) // pbch_E_bytes = pbch_coded_bits>>3; + LOG_D(PHY,"%s(eNB_pbch:%p txdataF:%p amp:%d frame_parms:%p pbch_pdu:%p frame_mod4:%d)\n", __FUNCTION__, eNB_pbch, txdataF, amp, frame_parms, pbch_pdu, frame_mod4==0); + if (frame_mod4==0) { bzero(pbch_a,PBCH_A>>3); bzero(eNB_pbch->pbch_e,pbch_E); diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 2ca502d1f686d68bc203da6e772dfd22d2b7d39e..9c2fc6a16776e606c063a5f3a18871124af1f9aa 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -1531,6 +1531,8 @@ static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char * return(-1); } + LOG_D(PHY, "%s() name:%s instance_cnt:%u - about to decrement\n", __FUNCTION__, name, *instance_cnt); + *instance_cnt=*instance_cnt-1; if (pthread_mutex_unlock(mutex) != 0) { diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 4e0c38174deecfc3e0f84fb7fc796876c4ca9af3..58f1ccd69db28bb9a8ca4f6368e9ee400e3e963b 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -37,6 +37,8 @@ #include "nfapi_interface.h" #include "fapi_l1.h" +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req); +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, @@ -576,8 +578,9 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); - AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe); - AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame); +// DJP - subframe assert will fail - not sure why yet + // DJP - AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe); + // DJP - AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame); uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; uint8_t number_hi_dci0_pdu = HI_DCI0_req->hi_dci0_request_body.number_of_dci+HI_DCI0_req->hi_dci0_request_body.number_of_hi; @@ -591,12 +594,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { int i; eNB->pdcch_vars[subframe&1].num_pdcch_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols; - eNB->pdcch_vars[subframe&1].num_dci = 0; + eNB->pdcch_vars[subframe&1].num_dci = DL_req->dl_config_request_body.number_dci; eNB->phich_vars[subframe&1].num_hi = 0; LOG_D(PHY,"NFAPI: Frame %d, Subframe %d: received %d dl_pdu, %d tx_req, %d hi_dci0_config_req, %d UL_config \n", frame,subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu); + int do_oai =0; if ((subframe_select(fp,ul_subframe)==SF_UL) || (fp->frame_type == FDD)) { @@ -619,6 +623,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: handle_nfapi_dci_dl_pdu(eNB,proc,dl_config_pdu); eNB->pdcch_vars[subframe&1].num_dci++; + do_oai=1; break; case NFAPI_DL_CONFIG_BCH_PDU_TYPE: AssertFatal(dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus, @@ -626,6 +631,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index, TX_req->tx_request_body.number_of_pdus); eNB->pbch_configured=1; + do_oai=1; + //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n", + //__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf)); + + handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data); break; @@ -633,6 +643,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { // handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu); break; case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE TX:%d/%d RX:%d/%d\n", __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx); + AssertFatal(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus, "dlsch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n", dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index, @@ -653,6 +665,10 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { subframe); } */ + // Send the data first so that the DL_CONFIG can just pluck it out of the buffer + // DJP - OAI was here - moved to bottom + do_oai=1; + break; case NFAPI_DL_CONFIG_PCH_PDU_TYPE: // handle_nfapi_pch_pdu(eNB,dl_config_pdu); @@ -673,6 +689,15 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { } } +#if 1 + if (do_oai) + { + oai_nfapi_tx_req(Sched_INFO->TX_req); + + oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu + } +#endif + for (i=0;i<number_hi_dci0_pdu;i++) { hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i]; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index e4be105a5fe994e878de49cf9f9dc38fcd9d2883..63ac501ecccf11fa0ff16563fd00980fb56b7e48 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -135,13 +135,11 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,rel #endif } -void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { +void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int **txdataF = eNB->common_vars.txdataF; uint8_t *pbch_pdu=&eNB->pbch_pdu[0]; - int subframe = proc->subframe_tx; - int frame = proc->frame_tx; LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d\n",frame,subframe); @@ -420,7 +418,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } else { // this is not a pmch subframe, so generate PSS/SSS/PBCH - common_signal_procedures(eNB,proc); + common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx); } // clear existing ulsch dci allocations before applying info from MAC (this is table @@ -1914,10 +1912,20 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const // Call SRS first since all others depend on presence of SRS or lack thereof srs_procedures(eNB,proc); + { + static int first_time=1; + if (first_time) + { + LOG_E(PHY,"%s() DJP - removed lte_eNB_I0_measurements because it core dumps - no idea why!!!\n\n\n\n\n", __FUNCTION__); + first_time=0; + } + } +#if 0 lte_eNB_I0_measurements(eNB, subframe, 0, eNB->first_run_I0_measurements); +#endif eNB->first_run_I0_measurements = 0; uci_procedures(eNB,proc); diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 19adae31b880116b8a1dfdc8c03bccddf935d201..ca480adb28c8bf15d00b67f737aba3d4dcba5af2 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -146,7 +146,7 @@ void feptx_ofdm(RU_t *ru) { } txdata = (int16_t*)&ru->common.txdata[aa][0]; for (j=0; i<(len<<1); i++,j++) { - txdata[j++] = ((int16_t*)dummy_tx_b)[i]; + txdata[j++] = ((int16_t*)dummy_tx_b)[i]; } } else { @@ -205,6 +205,14 @@ void feptx_prec(RU_t *ru) { eNB = eNB_list[0]; fp = &eNB->frame_parms; + if (0) LOG_E(PHY,"%s() run->nb_tx:%u subframe:%u fp->symbols_per_tti:%u fp->ofdm_symbol_size:%u symbols:(%d, %d), (%d,%d)\n", + __FUNCTION__, ru->nb_tx, subframe, fp->symbols_per_tti, fp->ofdm_symbol_size, + ((short*)&eNB->common_vars.txdataF[0][1])[0], + ((short*)&eNB->common_vars.txdataF[0][1])[1], + ((short*)&eNB->common_vars.txdataF[0][2])[0], + ((short*)&eNB->common_vars.txdataF[0][2])[1] + ); + for (aa=0;aa<ru->nb_tx;aa++) memcpy((void*)ru->common.txdataF_BF[aa], (void*)&eNB->common_vars.txdataF[aa][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size], @@ -409,4 +417,3 @@ void do_prach_ru(RU_t *ru) { } } - diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index e26cf54a1ccced682d2d074fd9d994c7e8d9b85d..3c3f10a510b45186db14f0b3f975bd818413612e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -53,7 +53,9 @@ #include "LAYER2/MAC/extern.h" #include "PHY/extern.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" -#include "enb_paramdef.h" +#include "nfapi_vnf.h" +#include "nfapi_pnf.h" + /* those macros are here to help diagnose problems in configuration files * if the lookup fails, a warning is printed * (yes we can use the function name for the macro itself, the C preprocessor @@ -75,6 +77,276 @@ (config_setting_lookup_string(setting, name, value) || \ (printf("WARNING: setting '%s' not found in configuration file\n", name), 0)) +#define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs" + +#define ENB_CONFIG_STRING_ENB_LIST "eNBs" +#define ENB_CONFIG_STRING_ENB_ID "eNB_ID" +#define ENB_CONFIG_STRING_CELL_TYPE "cell_type" +#define ENB_CONFIG_STRING_ENB_NAME "eNB_name" + +#define ENB_CONFIG_STRING_TRACKING_AREA_CODE "tracking_area_code" +#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE "mobile_country_code" +#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE "mobile_network_code" + +#define ENB_CONFIG_STRING_LOCAL_S_IF_NAME "local_s_if_name" +#define ENB_CONFIG_STRING_LOCAL_S_ADDRESS "local_s_address" +#define ENB_CONFIG_STRING_REMOTE_S_ADDRESS "remote_s_address" +#define ENB_CONFIG_STRING_LOCAL_S_PORTC "local_s_portc" +#define ENB_CONFIG_STRING_REMOTE_S_PORTC "remote_s_portc" +#define ENB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd" +#define ENB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd" +#define ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE "tr_s_preference" + + +#define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" + +#define ENB_CONFIG_STRING_CC_NODE_FUNCTION "node_function" +#define ENB_CONFIG_STRING_CC_NODE_TIMING "node_timing" +#define ENB_CONFIG_STRING_CC_NODE_SYNCH_REF "node_synch_ref" + +#define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" +#define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" +#define ENB_CONFIG_STRING_TDD_CONFIG_S "tdd_config_s" +#define ENB_CONFIG_STRING_PREFIX_TYPE "prefix_type" +#define ENB_CONFIG_STRING_PBCH_REPETITION "pbch_repetition" +#define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" +#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" +#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" + +#define ENB_CONFIG_STRING_NID_CELL "Nid_cell" +#define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" +#define ENB_CONFIG_STRING_CELL_MBSFN "Nid_cell_mbsfn" +#define ENB_CONFIG_STRING_NB_ANT_PORTS "nb_antenna_ports" +#define ENB_CONFIG_STRING_NB_ANT_TX "nb_antennas_tx" +#define ENB_CONFIG_STRING_NB_ANT_RX "nb_antennas_rx" +#define ENB_CONFIG_STRING_TX_GAIN "tx_gain" +#define ENB_CONFIG_STRING_RX_GAIN "rx_gain" +#define ENB_CONFIG_STRING_PRACH_ROOT "prach_root" +#define ENB_CONFIG_STRING_PRACH_CONFIG_INDEX "prach_config_index" +#define ENB_CONFIG_STRING_PRACH_HIGH_SPEED "prach_high_speed" +#define ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION "prach_zero_correlation" +#define ENB_CONFIG_STRING_PRACH_FREQ_OFFSET "prach_freq_offset" +#define ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT "pucch_delta_shift" +#define ENB_CONFIG_STRING_PUCCH_NRB_CQI "pucch_nRB_CQI" +#define ENB_CONFIG_STRING_PUCCH_NCS_AN "pucch_nCS_AN" +#if !defined(Rel10) && !defined(Rel14) +#define ENB_CONFIG_STRING_PUCCH_N1_AN "pucch_n1_AN" +#endif +#define ENB_CONFIG_STRING_PDSCH_RS_EPRE "pdsch_referenceSignalPower" +#define ENB_CONFIG_STRING_PDSCH_PB "pdsch_p_b" +#define ENB_CONFIG_STRING_PUSCH_N_SB "pusch_n_SB" +#define ENB_CONFIG_STRING_PUSCH_HOPPINGMODE "pusch_hoppingMode" +#define ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET "pusch_hoppingOffset" +#define ENB_CONFIG_STRING_PUSCH_ENABLE64QAM "pusch_enable64QAM" +#define ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN "pusch_groupHoppingEnabled" +#define ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT "pusch_groupAssignment" +#define ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN "pusch_sequenceHoppingEnabled" +#define ENB_CONFIG_STRING_PUSCH_NDMRS1 "pusch_nDMRS1" +#define ENB_CONFIG_STRING_PHICH_DURATION "phich_duration" +#define ENB_CONFIG_STRING_PHICH_RESOURCE "phich_resource" +#define ENB_CONFIG_STRING_SRS_ENABLE "srs_enable" +#define ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG "srs_BandwidthConfig" +#define ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG "srs_SubframeConfig" +#define ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG "srs_ackNackST" +#define ENB_CONFIG_STRING_SRS_MAXUPPTS "srs_MaxUpPts" +#define ENB_CONFIG_STRING_PUSCH_PO_NOMINAL "pusch_p0_Nominal" +#define ENB_CONFIG_STRING_PUSCH_ALPHA "pusch_alpha" +#define ENB_CONFIG_STRING_PUCCH_PO_NOMINAL "pucch_p0_Nominal" +#define ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE "msg3_delta_Preamble" +#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1 "pucch_deltaF_Format1" +#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b "pucch_deltaF_Format1b" +#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2 "pucch_deltaF_Format2" +#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A "pucch_deltaF_Format2a" +#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B "pucch_deltaF_Format2b" +#define ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES "rach_numberOfRA_Preambles" +#define ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG "rach_preamblesGroupAConfig" +#define ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA "rach_sizeOfRA_PreamblesGroupA" +#define ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA "rach_messageSizeGroupA" +#define ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB "rach_messagePowerOffsetGroupB" +#define ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP "rach_powerRampingStep" +#define ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER "rach_preambleInitialReceivedTargetPower" +#define ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX "rach_preambleTransMax" +#define ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE "rach_raResponseWindowSize" +#define ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER "rach_macContentionResolutionTimer" +#define ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX "rach_maxHARQ_Msg3Tx" +#define ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE "pcch_default_PagingCycle" +#define ENB_CONFIG_STRING_PCCH_NB "pcch_nB" +#define ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF "bcch_modificationPeriodCoeff" +#define ENB_CONFIG_STRING_UETIMERS_T300 "ue_TimersAndConstants_t300" +#define ENB_CONFIG_STRING_UETIMERS_T301 "ue_TimersAndConstants_t301" +#define ENB_CONFIG_STRING_UETIMERS_T310 "ue_TimersAndConstants_t310" +#define ENB_CONFIG_STRING_UETIMERS_T311 "ue_TimersAndConstants_t311" +#define ENB_CONFIG_STRING_UETIMERS_N310 "ue_TimersAndConstants_n310" +#define ENB_CONFIG_STRING_UETIMERS_N311 "ue_TimersAndConstants_n311" +#define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE "ue_TransmissionMode" + +#define ENB_CONFIG_STRING_SRB1 "srb1_parameters" +#define ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT "timer_poll_retransmit" +#define ENB_CONFIG_STRING_SRB1_TIMER_REORDERING "timer_reordering" +#define ENB_CONFIG_STRING_SRB1_TIMER_STATUS_PROHIBIT "timer_status_prohibit" +#define ENB_CONFIG_STRING_SRB1_POLL_PDU "poll_pdu" +#define ENB_CONFIG_STRING_SRB1_POLL_BYTE "poll_byte" +#define ENB_CONFIG_STRING_SRB1_MAX_RETX_THRESHOLD "max_retx_threshold" +#define ENB_CONFIG_STRING_MME_IP_ADDRESS "mme_ip_address" +#define ENB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4" +#define ENB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6" +#define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active" +#define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference" + +#define ENB_CONFIG_STRING_SCTP_CONFIG "SCTP" +#define ENB_CONFIG_STRING_SCTP_INSTREAMS "SCTP_INSTREAMS" +#define ENB_CONFIG_STRING_SCTP_OUTSTREAMS "SCTP_OUTSTREAMS" + +#define ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES" +#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME" +#define ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME "ENB_IPV4_ADDRESS_FOR_S1_MME" +#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U "ENB_INTERFACE_NAME_FOR_S1U" +#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U" +#define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" + +#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" +#define ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME "FLEXRAN_AGENT_INTERFACE_NAME" +#define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS "FLEXRAN_AGENT_IPV4_ADDRESS" +#define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT "FLEXRAN_AGENT_PORT" +#define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE "FLEXRAN_AGENT_CACHE" + + + + +#define ENB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity" +#define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none" +#define ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING "annoying" +#define ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO "info" + +// OTG config per ENB-UE DL +#define ENB_CONF_STRING_OTG_CONFIG "otg_config" +#define ENB_CONF_STRING_OTG_UE_ID "ue_id" +#define ENB_CONF_STRING_OTG_APP_TYPE "app_type" +#define ENB_CONF_STRING_OTG_BG_TRAFFIC "bg_traffic" + +// per eNB configuration +#define ENB_CONFIG_STRING_LOG_CONFIG "log_config" +#define ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL "global_log_level" +#define ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY "global_log_verbosity" +#define ENB_CONFIG_STRING_HW_LOG_LEVEL "hw_log_level" +#define ENB_CONFIG_STRING_HW_LOG_VERBOSITY "hw_log_verbosity" +#define ENB_CONFIG_STRING_PHY_LOG_LEVEL "phy_log_level" +#define ENB_CONFIG_STRING_PHY_LOG_VERBOSITY "phy_log_verbosity" +#define ENB_CONFIG_STRING_MAC_LOG_LEVEL "mac_log_level" +#define ENB_CONFIG_STRING_MAC_LOG_VERBOSITY "mac_log_verbosity" +#define ENB_CONFIG_STRING_RLC_LOG_LEVEL "rlc_log_level" +#define ENB_CONFIG_STRING_RLC_LOG_VERBOSITY "rlc_log_verbosity" +#define ENB_CONFIG_STRING_PDCP_LOG_LEVEL "pdcp_log_level" +#define ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY "pdcp_log_verbosity" +#define ENB_CONFIG_STRING_RRC_LOG_LEVEL "rrc_log_level" +#define ENB_CONFIG_STRING_RRC_LOG_VERBOSITY "rrc_log_verbosity" +#define ENB_CONFIG_STRING_GTPU_LOG_LEVEL "gtpu_log_level" +#define ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY "gtpu_log_verbosity" +#define ENB_CONFIG_STRING_UDP_LOG_LEVEL "udp_log_level" +#define ENB_CONFIG_STRING_UDP_LOG_VERBOSITY "udp_log_verbosity" +#define ENB_CONFIG_STRING_OSA_LOG_LEVEL "osa_log_level" +#define ENB_CONFIG_STRING_OSA_LOG_VERBOSITY "osa_log_verbosity" + +#define CONFIG_STRING_MACRLC_LIST "MACRLCs" +#define CONFIG_STRING_MACRLC_CONFIG "macrlc_config" +#define CONFIG_STRING_MACRLC_CC "num_cc" +#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME "local_s_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" +#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" +#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference" + +#define CONFIG_STRING_L1_LIST "L1s" +#define CONFIG_STRING_L1_CONFIG "l1_config" +#define CONFIG_STRING_L1_CC "num_cc" +#define CONFIG_STRING_L1_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_L1_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_L1_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_L1_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_L1_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" + +#define CONFIG_STRING_ACTIVE_RUS "Active_RUs" +#define CONFIG_STRING_RU_LIST "RUs" +#define CONFIG_STRING_RU_CONFIG "ru_config" +#define CONFIG_STRING_RU_LOCAL_IF_NAME "local_if_name" +#define CONFIG_STRING_RU_LOCAL_ADDRESS "local_address" +#define CONFIG_STRING_RU_REMOTE_ADDRESS "remote_address" +#define CONFIG_STRING_RU_LOCAL_PORTC "local_portc" +#define CONFIG_STRING_RU_REMOTE_PORTC "remote_portc" +#define CONFIG_STRING_RU_LOCAL_PORTD "local_portd" +#define CONFIG_STRING_RU_REMOTE_PORTD "remote_portd" +#define CONFIG_STRING_RU_LOCAL_RF "local_rf" +#define CONFIG_STRING_RU_TRANSPORT_PREFERENCE "tr_preference" +#define CONFIG_STRING_RU_BAND_LIST "bands" +#define CONFIG_STRING_RU_ENB_LIST "eNB_instances" +#define CONFIG_STRING_RU_NB_TX "nb_tx" +#define CONFIG_STRING_RU_NB_RX "nb_rx" +#define CONFIG_STRING_RU_ATT_TX "att_tx" +#define CONFIG_STRING_RU_ATT_RX "att_rx" +#define CONFIG_STRING_RU_MAX_RS_EPRE "max_pdschReferenceSignalPower" +#define CONFIG_STRING_RU_MAX_RXGAIN "max_rxgain" +#define CONFIG_STRING_RU_IF_COMPRESSION "if_compression" + +#define KHz (1000UL) +#define MHz (1000 * KHz) + +typedef struct eutra_band_s { + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; +} eutra_band_t; + +static const eutra_band_t eutra_bands[] = { + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, +}; + + static int enb_check_band_frequencies(char* lib_config_file_name_pP, @@ -117,6 +389,26 @@ static int enb_check_band_frequencies(char* lib_config_file_name_pP, return errors; } +#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) +extern int asn_debug; +extern int asn1_xer_print; +#endif + +#ifdef LIBCONFIG_LONG +#define libconfig_int long +#else +#define libconfig_int int +#endif + +typedef enum { + RU = 0, + L1 = 1, + L2 = 2, + L3 = 3, + S1 = 4, + lastel = 5 +} RC_config_functions_t; + void RCconfig_RU(void); void RCconfig_L1(void); void RCconfig_macrlc(void); @@ -140,6 +432,8 @@ int load_config_file(config_t *cfg) { } } +extern uint8_t nfapi_pnf; + void RCconfig_RU() { config_t cfg; @@ -206,12 +500,9 @@ void RCconfig_RU() { config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_RF,(const char **)&local_rf) ) ) { - local_rf_flag = CONFIG_FALSE; + local_rf_flag = CONFIG_FALSE; } - else { - if (strcmp(local_rf, "no") == 0) - local_rf_flag = CONFIG_FALSE; - } + if (local_rf_flag == CONFIG_TRUE) { // eNB or RRU @@ -258,27 +549,37 @@ void RCconfig_RU() { } - if (RC.nb_L1_inst>0) { - AssertFatal((setting_eNB_list = config_setting_get_member(setting_ru, CONFIG_STRING_RU_ENB_LIST))!=NULL,"No RU<->eNB mappings\n"); - - if (setting_eNB_list != NULL) num_eNB4RU = config_setting_length(setting_eNB_list); - else num_eNB4RU=0; - AssertFatal(num_eNB4RU>0,"Number of eNBs is zero\n"); - - for (i=0;i<num_eNB4RU;i++) { - setting_eNB_list_elem = config_setting_get_elem(setting_eNB_list,i); - eNB_list[i] = config_setting_get_int(setting_eNB_list_elem); - printf("RU %d: eNB %d\n",j,eNB_list[i]); - } + if (nfapi_pnf == 1 || nfapi_pnf == 2) + { + printf("DJP - COMMENTED OUT nb_L1_inst %s:%d\n\n\n\n", __FILE__, __LINE__); + } + else + { + printf("Before eNB_list\n"); + printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); + if (RC.nb_L1_inst>0) { + AssertFatal((setting_eNB_list = config_setting_get_member(setting_ru, CONFIG_STRING_RU_ENB_LIST))!=NULL,"No RU<->eNB mappings\n"); + + if (setting_eNB_list != NULL) num_eNB4RU = config_setting_length(setting_eNB_list); + else num_eNB4RU=0; + AssertFatal(num_eNB4RU>0,"Number of eNBs is zero\n"); + + printf("num_eNB4RU:%u\n", num_eNB4RU); + for (i=0;i<num_eNB4RU;i++) { + setting_eNB_list_elem = config_setting_get_elem(setting_eNB_list,i); + eNB_list[i] = config_setting_get_int(setting_eNB_list_elem); + printf("RU %d: eNB %d\n",j,eNB_list[i]); + } + } } config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_ATT_TX, &att_tx); config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_ATT_RX, &att_rx); if ( !( - config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_TX, &nb_tx) - && config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_RX, &nb_rx) - )) { + config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_TX, &nb_tx) + && config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_RX, &nb_rx) + )) { AssertFatal (0, "Failed to parse configuration file %s, RU %d config !\n", RC.config_file_name, j); @@ -293,7 +594,14 @@ void RCconfig_RU() { RC.ru[j]->if_timing = synch_to_ext_device; RC.ru[j]->num_eNB = num_eNB4RU; - for (i=0;i<num_eNB4RU;i++) RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0]; + printf("RC.ru[%d]->num_eNB:%u\n", j, RC.ru[j]->num_eNB); + + //for (i=0;i<num_eNB4RU;i++) RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0]; + for (i=0;i<num_eNB4RU;i++) + { + printf("Copying RC.ru[%d]->eNB_list[%d] = RC.eNB[eNB_list[%d][0]\n", j, i, i); + RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0]; + } if (strcmp(local_rf, "yes") == 0) { if (fronthaul_flag == CONFIG_FALSE) { @@ -336,6 +644,8 @@ void RCconfig_RU() { RC.ru[j]->max_pdschReferenceSignalPower = max_pdschReferenceSignalPower; RC.ru[j]->max_rxgain = max_rxgain; RC.ru[j]->num_bands = num_bands; + RC.ru[j]->att_tx = att_tx; + RC.ru[j]->att_rx = att_rx; for (i=0;i<num_bands;i++) RC.ru[j]->band[i] = band[i]; } else { @@ -398,98 +708,127 @@ void RCconfig_L1() { char* if_name_n = NULL; char* ipv4_n = NULL; char* ipv4_n_remote = NULL; - + char* tr_n_preference = NULL; libconfig_int local_n_portc = 0; libconfig_int remote_n_portc = 0; libconfig_int local_n_portd = 0; libconfig_int remote_n_portd = 0; + printf("%s()\n", __FUNCTION__); + load_config_file(&cfg); + printf("%s() RC.eNB:%p - NEED? malloc it\n", __FUNCTION__, RC.eNB); + + if (RC.eNB == NULL) { + RC.eNB = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***)); + LOG_I(PHY,"DJP - have malloced RC.eNB - RC.eNB = %p\n",RC.eNB); + memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***)); + RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); + printf("%s() RC.eNB:%p - RC.nb_L1_CC:%p\n", __FUNCTION__, RC.eNB, RC.nb_L1_CC); + } + +#if 0 + if (RC.nb_L1_inst==0) + { + RC.nb_L1_inst = 1; + printf("********\n\n\n*********** DJP - hard coding RC.nb_L1_inst = 1 \n\n\n\n"); + } +#endif + setting = config_lookup(&cfg, CONFIG_STRING_L1_LIST); - - if (setting != NULL) { - if (RC.eNB == NULL) { - RC.eNB = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***)); - LOG_I(PHY,"RC.eNB = %p\n",RC.eNB); - memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***)); - RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); + printf("%s() CONFIG_STRING_L1_LIST setting:%p\n", __FUNCTION__, setting); + + for (j = 0; j < RC.nb_L1_inst; j++) { + + if (RC.eNB[j] == NULL) { + RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**)); + LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); + memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***)); } - for (j = 0; j < RC.nb_L1_inst; j++) { + if (setting != NULL) { setting_l1 = config_setting_get_elem(setting, j); if (!config_setting_lookup_int (setting_l1,CONFIG_STRING_L1_CC,&RC.nb_L1_CC[j])) - AssertFatal (0, - "Failed to parse configuration file %s, L1 %d config !\n", - RC.config_file_name, j); - - if (RC.eNB[j] == NULL) { - RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**)); - LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); - memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***)); - } + AssertFatal (0, + "Failed to parse configuration file %s, L1 %d config !\n", + RC.config_file_name, j); + } + else + { +#if 0 + RC.nb_L1_CC[j] = 1; + printf("****DJP - hard coding nb_L1_CC[%d] = 1 *************\n", j, RC.nb_L1_CC[j]); +#endif + } - for (i=0;i<RC.nb_L1_CC[j];i++) { - if (RC.eNB[j][i] == NULL) { - RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB)); - memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB)); - LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]); - RC.eNB[j][i]->Mod_id = j; - RC.eNB[j][i]->CC_id = i; - } + for (i=0;i<RC.nb_L1_CC[j];i++) { + if (RC.eNB[j][i] == NULL) { + RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB)); + memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB)); + LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]); + RC.eNB[j][i]->Mod_id = j; + RC.eNB[j][i]->CC_id = i; } + } + printf("l1 %d/%d (nb CC %d)\n",j,RC.nb_inst,RC.nb_L1_CC[j]); - - printf("l1 %d/%d (nb CC %d)\n",j,RC.nb_inst,RC.nb_L1_CC[j]); - - + if (setting) + { printf("RU %d: Transport %s\n",j,tr_n_preference); if (!(config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, (const char **)&tr_n_preference))) { - AssertFatal (0, - "Failed to parse configuration file %s, L1 %d config !\n", - RC.config_file_name, j); + AssertFatal (0, + "Failed to parse configuration file %s, L1 %d config !\n", + RC.config_file_name, j); } if (strcmp(tr_n_preference, "local_mac") == 0) { } else if (strcmp(tr_n_preference, "nfapi") == 0) { - if ( !( - config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_IF_NAME, (const char **)&if_name_n) - && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_ADDRESS, (const char **)&ipv4_n) - && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_REMOTE_N_ADDRESS, (const char **)&ipv4_n_remote) - && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTC, &local_n_portc) - && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTC, &remote_n_portc) - && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTD, &local_n_portd) - && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTD, &remote_n_portd) - ) - ) { - AssertFatal (0, - "Failed to parse configuration file %s, L1 %d config !\n", - RC.config_file_name, j); - continue; // FIXME will prevent segfaults below, not sure what happens at function exit... - } - RC.eNB[j][0]->eth_params_n.local_if_name = strdup(if_name_n); - RC.eNB[j][0]->eth_params_n.my_addr = strdup(ipv4_n); - RC.eNB[j][0]->eth_params_n.remote_addr = strdup(ipv4_n_remote); - RC.eNB[j][0]->eth_params_n.my_portc = local_n_portc; - RC.eNB[j][0]->eth_params_n.remote_portc = remote_n_portc; - RC.eNB[j][0]->eth_params_n.my_portd = local_n_portd; - RC.eNB[j][0]->eth_params_n.remote_portd = remote_n_portd; - RC.eNB[j][0]->eth_params_n.transp_preference = ETH_UDP_MODE; + if ( !( + config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_IF_NAME, (const char **)&if_name_n) + && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_ADDRESS, (const char **)&ipv4_n) + && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_REMOTE_N_ADDRESS, (const char **)&ipv4_n_remote) + && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTC, &local_n_portc) + && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTC, &remote_n_portc) + && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTD, &local_n_portd) + && config_setting_lookup_int (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTD, &remote_n_portd) + ) + ) { + AssertFatal (0, + "Failed to parse configuration file %s, L1 %d config !\n", + RC.config_file_name, j); + continue; // FIXME will prevent segfaults below, not sure what happens at function exit... + } + RC.eNB[j][0]->eth_params_n.local_if_name = strdup(if_name_n); + RC.eNB[j][0]->eth_params_n.my_addr = strdup(ipv4_n); + RC.eNB[j][0]->eth_params_n.remote_addr = strdup(ipv4_n_remote); + RC.eNB[j][0]->eth_params_n.my_portc = local_n_portc; + RC.eNB[j][0]->eth_params_n.remote_portc = remote_n_portc; + RC.eNB[j][0]->eth_params_n.my_portd = local_n_portd; + RC.eNB[j][0]->eth_params_n.remote_portd = remote_n_portd; + RC.eNB[j][0]->eth_params_n.transp_preference = ETH_UDP_MODE; + + configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n.remote_portd); + + { + extern uint8_t nfapi_pnf; + nfapi_pnf = 1; + } } - else { // other midhaul } - }// j=0..num_inst - printf("Initializing northbound interface for L1\n"); - l1_north_init_eNB(); - } + } // setting + }// j=0..num_inst + printf("Initializing northbound interface for L1\n"); + l1_north_init_eNB(); + return; } @@ -614,6 +953,18 @@ void RCconfig_macrlc() { RC.mac[j]->eth_params_s.my_portd = local_s_portd; RC.mac[j]->eth_params_s.remote_portd = remote_s_portd; RC.mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; + + { + extern uint8_t nfapi_pnf; + nfapi_pnf = 2; + } + + { + printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); + configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc); + printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); + + } } else { // other midhaul @@ -2807,6 +3158,7 @@ void RCConfig(const char *config_file_name) { // Get num RU instances setting = config_lookup(&cfg, CONFIG_STRING_RU_LIST); if (setting != NULL) RC.nb_RU = config_setting_length(setting); + printf("RC.nb_RU may have been set to:%d setting:%p\n", RC.nb_RU, setting); } else { config_destroy(&cfg); diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 7913f1a60285396225fa82f80f4de3d6b62fab57..4137fe5f4c7c0a54718a0dd399eb1039ca7d677e 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -57,6 +57,9 @@ #endif extern RAN_CONTEXT_t RC; +extern int l2_init_eNB(void); +extern int mac_top_init_eNB(void); +extern void mac_init_cell_params(int Mod_idP,int CC_idP); /* sec 5.9, 36.321: MAC Reset Procedure */ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) @@ -217,32 +220,100 @@ void config_mib(int Mod_idP, uint32_t pbch_repetitionP) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; + + cfg->num_tlv=0; cfg->subframe_config.pcfich_power_offset.value = 6000; // 0dB + cfg->subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG; + cfg->num_tlv++; + cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP; + cfg->subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; + cfg->num_tlv++; + cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP; + cfg->subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; + cfg->num_tlv++; - LOG_I(MAC,"Ncp %d,p_eNB %d\n",NcpP,p_eNBP); + cfg->rf_config.dl_channel_bandwidth.value = to_prb(dl_BandwidthP); + cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; + cfg->num_tlv++; +LOG_E(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); + + cfg->rf_config.ul_channel_bandwidth.value = to_prb(dl_BandwidthP); + cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; + cfg->num_tlv++; - cfg->rf_config.dl_channel_bandwidth.value = dl_BandwidthP; - cfg->rf_config.ul_channel_bandwidth.value = dl_BandwidthP; cfg->rf_config.tx_antenna_ports.value = p_eNBP; + cfg->rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; + cfg->num_tlv++; + cfg->rf_config.rx_antenna_ports.value = 2; + cfg->rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; + cfg->num_tlv++; cfg->nfapi_config.earfcn.value = to_earfcn(eutra_bandP,dl_CarrierFreqP,bw_table[dl_BandwidthP]/100); + cfg->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; + cfg->num_tlv++; + cfg->nfapi_config.rf_bands.number_rf_bands = 1; cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; + cfg->nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; + cfg->num_tlv++; + cfg->phich_config.phich_resource.value = phich_configP->phich_Resource; + cfg->phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; + cfg->num_tlv++; + cfg->phich_config.phich_duration.value = phich_configP->phich_Duration; + cfg->phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; + cfg->num_tlv++; + cfg->phich_config.phich_power_offset.value = 6000; // 0dB + cfg->phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; + cfg->num_tlv++; cfg->sch_config.primary_synchronization_signal_epre_eprers.value = 6000; // 0dB + cfg->sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + cfg->num_tlv++; + cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB + cfg->sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + cfg->num_tlv++; + cfg->sch_config.physical_cell_id.value = Nid_cellP; + cfg->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; + cfg->num_tlv++; #ifdef Rel14 cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; + cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; + cfg->num_tlv++; #endif + + LOG_I(MAC, + "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" +#ifdef Rel14 + " PBCH repetition %d" +#endif + "\n" + ,__FUNCTION__ + ,cfg->num_tlv + ,cfg->rf_config.dl_channel_bandwidth.value + ,cfg->rf_config.ul_channel_bandwidth.value + ,NcpP,p_eNBP + ,cfg->nfapi_config.earfcn.value + ,cfg->nfapi_config.rf_bands.rf_band[0] + ,cfg->phich_config.phich_resource.value + ,cfg->phich_config.phich_duration.value + ,cfg->phich_config.phich_power_offset.value + ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.physical_cell_id.value +#ifdef Rel14 + ,cfg->emtc_config.pbch_repetitions_enable_r13.value +#endif + ); } void config_sib1(int Mod_idP, @@ -253,11 +324,21 @@ void config_sib1(int Mod_idP, if (tdd_ConfigP) { //TDD cfg->subframe_config.duplex_mode.value = 0; + cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + cfg->num_tlv++; + cfg->tdd_frame_structure_config.subframe_assignment.value = tdd_ConfigP->subframeAssignment; + cfg->tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG; + cfg->num_tlv++; + cfg->tdd_frame_structure_config.special_subframe_patterns.value = tdd_ConfigP->specialSubframePatterns; + cfg->tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG; + cfg->num_tlv++; } else { // FDD cfg->subframe_config.duplex_mode.value = 1; + cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + cfg->num_tlv++; // Note no half-duplex here } @@ -280,46 +361,117 @@ void config_sib2(int Mod_idP, nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; + cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; + cfg->num_tlv++; + cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower; + cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; + cfg->num_tlv++; + cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value]; + cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG; + cfg->num_tlv++; cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex; + cfg->prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex; + cfg->prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; + cfg->num_tlv++; + cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; + cfg->prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + cfg->num_tlv++; + cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag; + cfg->prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; + cfg->num_tlv++; + cfg->prach_config.frequency_offset.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset; + cfg->prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->pusch_config.hopping_mode.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; + cfg->pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG; + cfg->num_tlv++; + cfg->pusch_config.number_of_subbands.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; + cfg->pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG; + cfg->num_tlv++; + cfg->pusch_config.hopping_offset.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; + cfg->pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + cfg->pucch_config.delta_pucch_shift.value = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift; + cfg->pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG; + cfg->num_tlv++; + cfg->pucch_config.n_cqi_rb.value = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI; + cfg->pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG; + cfg->num_tlv++; + cfg->pucch_config.n_an_cs.value = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN; + cfg->pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG; + cfg->num_tlv++; + cfg->pucch_config.n1_pucch_an.value = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN; + cfg->pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; + cfg->num_tlv++; + if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) + { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; + } else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) + { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; + } else // No hopping + { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; + } + cfg->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; + cfg->num_tlv++; cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; + cfg->uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; + cfg->num_tlv++; + cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; + cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; + cfg->num_tlv++; + // how to enable/disable SRS? if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; + cfg->srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; + cfg->num_tlv++; + cfg->srs_config.srs_subframe_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; + cfg->srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG; + cfg->num_tlv++; + cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + cfg->srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; + cfg->num_tlv++; + - if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) + if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { cfg->srs_config.max_up_pts.value = 1; - else + } + else { cfg->srs_config.max_up_pts.value = 0; + } + cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; + cfg->num_tlv++; } #ifdef Rel14 @@ -327,59 +479,165 @@ void config_sib2(int Mod_idP, AssertFatal(radioResourceConfigCommon_BRP!=NULL,"radioResource rou is missing\n"); AssertFatal(radioResourceConfigCommon_BRP->ext4!=NULL,"ext4 is missing\n"); cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; + cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; + cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; + cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; + cfg->num_tlv++; struct PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; - int i; PRACH_ParametersCE_r13_t *p; cfg->emtc_config.prach_ce_level_0_enable.value=0; + cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_enable.value=0; + cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_enable.value=0; + cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_enable.value=0; + cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + cfg->num_tlv++; + switch (prach_ParametersListCE_r13->list.count) { case 4: p=prach_ParametersListCE_r13->list.array[3]; cfg->emtc_config.prach_ce_level_3_enable.value = 1; + cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + case 3: p=prach_ParametersListCE_r13->list.array[2]; cfg->emtc_config.prach_ce_level_2_enable.value = 1; + cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + case 2: p=prach_ParametersListCE_r13->list.array[1]; cfg->emtc_config.prach_ce_level_1_enable.value = 1; + cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + case 1: p=prach_ParametersListCE_r13->list.array[0]; cfg->emtc_config.prach_ce_level_0_enable.value = 1; + cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; + cfg->num_tlv++; } struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; @@ -390,9 +648,13 @@ void config_sib2(int Mod_idP, break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; break; } } @@ -403,9 +665,13 @@ void config_sib2(int Mod_idP, break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; break; } } @@ -582,7 +848,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, if (UE_id == -1) LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); else - UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated=physicalConfigDedicated; + config_dedicated(Mod_idP, CC_idP, UE_RNTI(Mod_idP, UE_id), physicalConfigDedicated); } @@ -658,20 +924,23 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, #endif - if (radioResourceConfigCommon!=NULL) { - AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); - PHY_Config_t phycfg; - phycfg.Mod_id = Mod_idP; - phycfg.CC_id = CC_idP; - phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; - - if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); + while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) { + // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); + usleep(100 * 1000); + printf("Waiting for PHY_config_req\n"); } + PHY_Config_t phycfg; + phycfg.Mod_id = Mod_idP; + phycfg.CC_id = CC_idP; + phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; + + if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); - - return(0); -} + return(0); + +} int rrc_mac_config_req_ue( module_id_t Mod_idP, @@ -710,8 +979,6 @@ rrc_mac_config_req_ue( int i; - int UE_id = -1; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); LOG_I(MAC,"[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",Mod_idP,eNB_index); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index aec302c36a032d58c04189460a3101789d1ed029..c67a07d09a8407af057ed645289c9e3d1a01a6c5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -100,6 +100,7 @@ schedule_SIB1_BR( int n_NB = 0; int TBS; int k=0,rvidx; + uint16_t sfn_sf = frameP << 4 | subframeP; for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { @@ -240,10 +241,11 @@ schedule_SIB1_BR( // Rel13 fields dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; @@ -252,8 +254,14 @@ schedule_SIB1_BR( TX_req->num_segments = 1; TX_req->segments[0].segment_length = bcch_sdu_length; TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", + __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus, + TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length); if (opt_enabled == 1) { @@ -314,6 +322,7 @@ schedule_SI_BR( int i; int rvidx; int absSF = (frameP*10)+subframeP; + uint16_t sfn_sf = frameP << 4 | subframeP; for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { @@ -400,10 +409,10 @@ schedule_SI_BR( vrb_map[first_rb+4] = 1; vrb_map[first_rb+5] = 1; - if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n", - module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx, - sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, - bcch_sdu_length); + if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %ld rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %ld : si_RepetitionPattern_r13 %ld) bcch_sdu_length %d\n", + module_idP,frameP,subframeP,CC_id,si_Narrowband_r13-1,rvidx, + sf_mod_period,si_WindowLength_BR_r13,si_RepetitionPattern_r13, + bcch_sdu_length); @@ -412,6 +421,7 @@ schedule_SI_BR( memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13>>3; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; @@ -443,6 +453,7 @@ schedule_SI_BR( // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; @@ -452,7 +463,14 @@ schedule_SI_BR( TX_req->segments[0].segment_length = bcch_sdu_length; TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i+1].payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", + __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus, + TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length); + if (opt_enabled == 1) { trace_pdu(1, &cc->BCCH_BR_pdu[i+1].payload[0], @@ -493,18 +511,22 @@ void schedule_mib(module_id_t module_idP, eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc; + nfapi_dl_config_request_t *dl_config_request; nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_pdu_t *TX_req; int mib_sdu_length; int CC_id; nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; - AssertFatal(subframeP==0,"Subframe must be 0\n"); - AssertFatal((frameP&3)==0,"Frame must be a multiple of 4\n"); +// DJP - commented out because I am going to try and send MIB every frame + //AssertFatal(subframeP==0,"Subframe must be 0\n"); + //AssertFatal((frameP&3)==0,"Frame must be a multiple of 4\n"); for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + dl_config_request = &eNB->DL_req[CC_id]; + dl_req = &dl_config_request->dl_config_request_body; cc = &eNB->common_channels[CC_id]; mib_sdu_length = mac_rrc_data_req(module_idP, @@ -516,36 +538,46 @@ void schedule_mib(module_id_t module_idP, module_idP, 0); // not used in this case - LOG_D(MAC,"Frame %d, subframe %d: BCH PDU length %d\n", + LOG_E(MAC,"Frame %d, subframe %d: BCH PDU length %d\n", frameP,subframeP,mib_sdu_length); if (mib_sdu_length > 0) { - LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", - frameP,subframeP,dl_req->number_pdu,mib_sdu_length); + LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP,subframeP,dl_req->number_pdu,mib_sdu_length); - if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",module_idP,frameP,CC_id,mib_sdu_length,(int)cc->mib->message.schedulingInfoSIB1_BR_r13); + if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %ld)\n",module_idP,frameP,CC_id,mib_sdu_length,cc->mib->message.schedulingInfoSIB1_BR_r13); dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE; dl_config_pdu->pdu_size = 2+sizeof(nfapi_dl_config_bch_pdu); + dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; dl_req->number_pdu++; - LOG_D(MAC,"eNB->DL_req[0].number_pdu %d (%p)\n", - dl_req->number_pdu,&dl_req->number_pdu); + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + + //LOG_E(MAC,"eNB->DL_req[0].number_pdu %d (%p) sfn_sf:%d\n", dl_req->number_pdu,&dl_req->number_pdu, NFAPI_SFNSF2DEC(dl_config_request->sfn_sf)); // DL request TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = 3; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 0; + TX_req->segments[0].segment_length = mib_sdu_length; TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", + __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus, + TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length); } } } @@ -569,9 +601,11 @@ schedule_SI( uint8_t *vrb_map; int first_rb = -1; int N_RB_DL; + nfapi_dl_config_request_t *dl_config_request; nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_pdu_t *TX_req; nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; start_meas(&eNB->schedule_si); @@ -583,9 +617,9 @@ schedule_SI( cc = &eNB->common_channels[CC_id]; vrb_map = (void*)&cc->vrb_map; N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_config_request = &eNB->DL_req[CC_id]; dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, @@ -596,7 +630,7 @@ schedule_SI( 0); // not used in this case if (bcch_sdu_length > 0) { - LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,CC_id,bcch_sdu_length); + LOG_D(MAC,"[eNB %d] Frame %d subframe %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,subframeP,CC_id,bcch_sdu_length); // Allocate 4 PRBs in a random location /* @@ -654,10 +688,20 @@ schedule_SI( } + //dl_req->number_pdcch_ofdm_symbols = &RC.mac[module_idP]->DL_req[CC_id].dl_config_request_body; + + + + + + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->pdu_size = (uint8_t)(sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_req->number_dci++; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; @@ -671,23 +715,22 @@ schedule_SI( dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4); - - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF - + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,SI_RNTI)) { - LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", - frameP,subframeP); - dl_req->number_dci++; + // DJP - dl_req->number_dci++; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + LOG_E(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP,subframeP); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->pdu_size = (uint8_t)(sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D @@ -705,13 +748,24 @@ schedule_SI( dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = 1; // DJP - wireshark whinges - get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 0; // DJP + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 0; // DJP // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; + dl_req->number_pdu++; + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG; + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel9.nscid = 0; + + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG; + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG; + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + // Program TX Request TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; @@ -720,7 +774,13 @@ schedule_SI( TX_req->segments[0].segment_length = bcch_sdu_length; TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", + __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus, + TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length); } else { LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI\n",module_idP, CC_id,frameP,subframeP); @@ -772,6 +832,4 @@ schedule_SI( #endif stop_meas(&eNB->schedule_si); - return; } - diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index ae4b52222d59daa436b61eedd5795a2ac13527e7..5d668ff3041f42e1132809b4aebd40a21a4648db 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -61,7 +61,7 @@ void dl_phy_sync_success(module_id_t module_idP, #endif if (first_sync==1 && !(mme_enabled==1)) { - layer2_init_UE(module_idP); + //DJP layer2_init_UE(module_idP); openair_rrc_ue_init(module_idP,eNB_index); } else { @@ -148,7 +148,7 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, } -int mac_top_init_eNB() +int mac_top_init_eNB(void) { module_id_t Mod_id,i,j; @@ -379,7 +379,7 @@ int l2_init_ue(int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8 return(1); } -int l2_init_eNB() +int l2_init_eNB(void) { diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index b05e983c30f99dfb2d76d1a2ddcdc63fe8053605..a7e4439e458106536df1822847fac89c15ff9b50 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -207,7 +207,7 @@ void UL_indication(UL_IND_t *UL_info) sched_info->TX_req = &mac->TX_req[CC_id]; AssertFatal(ifi->schedule_response!=NULL, - "UL_indication is null (mod %d, cc %d)\n", + "schedule_response is null (mod %d, cc %d)\n", module_id, CC_id); ifi->schedule_response(sched_info); diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index 5c9d06f98630effb5175fd414decdd1c5953d20f..45b3822cd936687a7a02520cab1dc13d9c29e8ea 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -65,7 +65,7 @@ openair_rrc_on( int CC_id; if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" OPENAIR RRC IN....\n", + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1); @@ -74,7 +74,7 @@ openair_rrc_on( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1; } } else { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" OPENAIR RRC IN....\n", + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); for (i = 0; i < NB_eNB_INST; i++) { diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index a8769c2690cd1c5e8a76c751bc927fe6b3f14538..85b12c431e94987240586f9f830534b191f274d7 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -147,7 +147,7 @@ init_SI( #ifdef Rel14 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id]; #endif - LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", + LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %ld,phich_Duration %ld)\n", configuration->N_RB_DL[CC_id], configuration->phich_resource[CC_id], configuration->phich_duration[CC_id]); @@ -282,6 +282,8 @@ init_SI( } #endif + LOG_I(RRC, "About to call rrc_mac_config_req_eNB"); + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index b63eef9c7e6bd8764e1df05abfe38e2618175cf8..94b9d02016ebd1ab2ce42d79d168413f78ccc36d 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -99,7 +99,7 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP); void *udp_eNB_task(void *args_p); -int udp_enb_init(); +int udp_enb_init(void); /* @brief Retrieve the descriptor associated with the task_id */ static @@ -427,7 +427,7 @@ on_error: return NULL; } -int udp_enb_init() +int udp_enb_init(void) { LOG_I(UDP_, "Initializing UDP task interface\n"); STAILQ_INIT(&udp_socket_list); diff --git a/openair3/UDP/udp_eNB_task.h b/openair3/UDP/udp_eNB_task.h index 0f6461dda7f03c58e997c5a7f3ecac979a46c54d..2265a7a8b83bca6a71c549d8970ae7765c3aefa1 100644 --- a/openair3/UDP/udp_eNB_task.h +++ b/openair3/UDP/udp_eNB_task.h @@ -93,6 +93,6 @@ void *udp_eNB_task(void *args_p); * \param enb_config_p configuration of eNB * @returns always 0 */ -int udp_enb_init(); +int udp_enb_init(void); #endif /* UDP_ENB_TASK_H_ */ diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 177a6455d3d9fea73ae3cd1324a2e76f54a428a2..de2ad05fae07d603ecc8bee0ed2370f58ce54f4c 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -138,10 +138,10 @@ static void trx_usrp_end(openair0_device *device) { /*! \brief Called to send samples to the USRP RF target @param device pointer to the device structure specific to the RF hardware target - @param timestamp The timestamp at whicch the first sample MUST be sent + @param timestamp The timestamp at which the first sample MUST be sent @param buff Buffer which holds the samples @param nsamps number of samples to be sent - @param antenna_id index of the antenna if the device has multiple anteannas + @param antenna_id index of the antenna if the device has multiple antennas @param flags flags must be set to TRUE if timestamp parameter needs to be applied */ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { @@ -515,6 +515,8 @@ extern "C" { openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); + switch ((int)openair0_cfg[0].sample_rate) { case 30720000: // from usrp_time_offset @@ -648,6 +650,8 @@ extern "C" { s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i); s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i); + + LOG_I(PHY,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]); } } diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index ef3124ff248b3878886b2111179691cf2268fd2f..b3533d94bae63249c4db2998b88bfe7af9ab32d6 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -42,6 +42,8 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) { + LOG_E(ENB_APP, "%s(enb_nb:%d ue_nb:%d)\n", __FUNCTION__, enb_nb, ue_nb); + itti_wait_ready(1); if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { LOG_E(PDCP, "Create task for L2L1 failed\n"); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index 1e4933f859425856a5eb37e893241ed54899a529..842f32a70ea3dea8d747cc77290c1887b0a320fc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -17,7 +17,8 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "93"; + #mobile_network_code = "93"; + mobile_network_code = "92"; tr_s_preference = "local_mac" @@ -140,7 +141,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "127.0.0.3"; + mme_ip_address = ( { ipv4 = "192.168.1.78"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -150,10 +151,10 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; - ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.1.74/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.1.74/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; @@ -200,6 +201,8 @@ RUs = ( att_tx = 0 att_rx = 0; bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; eNB_instances = [0]; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf index f97cd0ad8ba0c0e4a82d1c11520dfea2a71634cc..1710121d78534b8539a2a1f0fa805b1334c0bdc6 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf @@ -2,13 +2,14 @@ L1s = ( { num_cc = 1; tr_n_preference = "nfapi"; - local_n_if_name = "lo"; - remote_n_address = "127.0.0.2"; - local_n_address = "127.0.0.1"; - local_n_portc = 50000; - remote_n_portc = 50000; - local_n_portd = 50001; - remote_n_portd = 50001; + local_n_if_name = "eno1"; + #remote_n_address = "192.168.1.78"; + remote_n_address = "192.168.1.28"; + local_n_address = "192.168.1.74"; + local_n_portc = 50000; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; } ); @@ -17,11 +18,10 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 0 + att_tx = 90 att_rx = 0; bands = [7,38,42,43]; max_pdschReferenceSignalPower = -27; max_rxgain = 125; - eNB_instances = [0]; } -); +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index 1e2cd126168553bad3d65b67b331a063a90da2d7..ca76f42ee0aadb82b0017668b953b97fd46b5888 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -17,7 +17,8 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "93"; + #mobile_network_code = "93"; + mobile_network_code = "92"; tr_s_preference = "local_mac" @@ -36,7 +37,8 @@ eNBs = downlink_frequency = 2685000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; - N_RB_DL = 50; + #N_RB_DL = 50; + N_RB_DL = 25; Nid_cell_mbsfn = 0; nb_antenna_ports = 1; nb_antennas_tx = 1; @@ -53,7 +55,8 @@ eNBs = pucch_nRB_CQI = 1; pucch_nCS_AN = 0; pucch_n1_AN = 32; - pdsch_referenceSignalPower = -27; + #pdsch_referenceSignalPower = -27; + pdsch_referenceSignalPower = -30; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; @@ -89,7 +92,8 @@ eNBs = rach_messagePowerOffsetGroupB = ; */ rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -108; + #rach_preambleInitialReceivedTargetPower = -108; + rach_preambleInitialReceivedTargetPower = -104; rach_preambleTransMax = 10; rach_raResponseWindowSize = 10; rach_macContentionResolutionTimer = 48; @@ -140,7 +144,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "127.0.0.3"; + mme_ip_address = ( { ipv4 = "192.168.1.78"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -150,22 +154,22 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; - ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.1.28/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.1.28/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; log_config : { - global_log_level ="info"; - global_log_verbosity ="medium"; + global_log_level ="debug"; + global_log_verbosity ="high"; hw_log_level ="info"; hw_log_verbosity ="medium"; - phy_log_level ="info"; - phy_log_verbosity ="medium"; - mac_log_level ="info"; + phy_log_level ="trace"; + phy_log_verbosity ="high"; + mac_log_level ="debug"; mac_log_verbosity ="high"; rlc_log_level ="info"; rlc_log_verbosity ="medium"; @@ -180,15 +184,15 @@ eNBs = MACRLCs = ( { num_cc = 1; - local_s_if_name = "lo"; - remote_s_address = "127.0.0.1"; - local_s_address = "127.0.0.2"; - local_s_portc = 50000; + local_s_if_name = "eno1"; + remote_s_address = "192.168.1.74"; + #local_s_address = "192.168.1.78"; + local_s_address = "192.168.1.28"; + local_s_portc = 50001; remote_s_portc = 50000; - local_s_portd = 50001; - remote_s_portd = 50001; + local_s_portd = 50011; + remote_s_portd = 50010; tr_s_preference = "nfapi"; tr_n_preference = "local_RRC"; } ); - diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index ec818ae0f4e6eeb1c312fe4255532146adffc0a1..bccd5b57e7538db03991b254d42575b45bf73cbd 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -148,30 +148,54 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif +void oai_subframe_ind(uint16_t frame, uint16_t subframe); +extern uint8_t nfapi_pnf; + static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); + if (nfapi_pnf) + { + oai_subframe_ind(proc->frame_tx, proc->subframe_tx); // PNF ---> P7:subframe_ind --> VNF + } + else + { + } + // ******************************************************************* + + //if (proc->subframe_tx==0) LOG_W(PHY, "sfn/sf:%d:%d eNB:%p eNB[0]:%p eNB[0][0]:%p dlsch:%p:%p:%p rnti:%d\n", proc->frame_tx, proc->subframe_tx, RC.eNB, RC.eNB[0], RC.eNB[0][0], RC.eNB[0][0]->dlsch, RC.eNB[0][0]->dlsch[0], RC.eNB[0][0]->dlsch[0][0], RC.eNB[0][0]->dlsch[0][0]->rnti); + if ( proc->frame_tx == 22 && proc->subframe_tx==5) { LOG_D(PHY,"22/5\n"); } + // **************************************** // Common RX procedures subframe n // if this is IF5 or 3GPP_eNB - if (eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { + if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { + LOG_D(PHY,"%s:%s() %u/%u Before wakeup_prach_eNB() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx); + LOG_D(PHY,"%s:%s() %u/%u Before wakeup_prach_eNB_br() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); #ifdef Rel14 wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx); + LOG_D(PHY,"%s:%s() %u/%u proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); #endif } // UE-specific RX processing for subframe n + LOG_D(PHY,"%s:%s() %u/%u Before phy_procedures_eNB_uespec_RX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); phy_procedures_eNB_uespec_RX(eNB, proc, no_relay ); + LOG_D(PHY,"%s:%s() %u/%u Before UL_INFO_mutex proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); pthread_mutex_lock(&eNB->UL_INFO_mutex); + LOG_D(PHY,"%s:%s() %u/%u After UL_INFO_mutex proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); eNB->UL_INFO.frame = proc->frame_rx; eNB->UL_INFO.subframe = proc->subframe_rx; eNB->UL_INFO.module_id = eNB->Mod_id; eNB->UL_INFO.CC_id = eNB->CC_id; + LOG_D(PHY,"%s:%s() %u/%u Before UL_ind proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); eNB->if_inst->UL_indication(&eNB->UL_INFO); + LOG_D(PHY,"%s:%s() %u/%u After UL_ind proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); pthread_mutex_unlock(&eNB->UL_INFO_mutex); + LOG_D(PHY,"%s:%s() %u/%u After UL_INFO_mutex unlock proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); // ***************************************** // TX processing for subframe n+4 // run PHY TX procedures the one after the other for all CCs to avoid race conditions @@ -183,10 +207,16 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam if (oai_exit) return(-1); + LOG_D(PHY,"%s:%s() %u/%u Before phy_procedures_eNB_TX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1); + LOG_D(PHY,"%s:%s() %u/%u After phy_procedures_eNB_TX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); + LOG_D(PHY,"%s:%s() %u/%u Before release_thread() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); + if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); + LOG_D(PHY,"%s:%s() %u/%u AFTER release_thread() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); + stop_meas( &softmodem_stats_rxtx_sf ); return(0); @@ -208,28 +238,35 @@ static void* eNB_thread_rxtx( void* param ) { char thread_name[100]; + //LOG_D(PHY,"%s()\n", __FUNCTION__); // set default return value eNB_thread_rxtx_status = 0; - sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); + sprintf(thread_name,"RXn_TXnp4_%d",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); thread_top_init(thread_name,1,850000L,1000000L,2000000L); + //LOG_D(PHY,"%s() thread_name:%s\n", __FUNCTION__, thread_name); + while (!oai_exit) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); + LOG_D(PHY,"%s:%s() %u/%u About to wait on proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + LOG_D(PHY,"%s:%s() %u/%u - WOKEN on proc->instance_cnt_rxtx proc->instance_cnt_rxtx:%d \n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); - - if (oai_exit) break; + LOG_D(PHY,"%s:%s() %u/%u About to rxtx()\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx); if (eNB->CC_id==0) if (rxtx(eNB,proc,thread_name) < 0) break; + LOG_D(PHY,"%s:%s() %u/%u DONE rxtx()\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx); + } // while !oai_exit VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); @@ -355,6 +392,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { } ++proc_rxtx->instance_cnt_rxtx; + LOG_E(PHY,"%s() %u/%u Just incremented proc->instance_cnt_rxtx:%d\n", __FUNCTION__, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx); // We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired @@ -596,10 +634,12 @@ void init_eNB_proc(int inst) { pthread_attr_t *attr_prach_br=NULL; #endif + LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]); + for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) { eNB = RC.eNB[inst][CC_id]; #ifndef OCP_FRAMEWORK - LOG_I(PHY,"Initializing eNB processes %d CC_id %d \n",inst,CC_id); + LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id); #endif proc = &eNB->proc; @@ -658,6 +698,8 @@ void init_eNB_proc(int inst) { attr_te = &proc->attr_te; #endif + LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); + if (eNB->single_thread_flag==0) { pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); @@ -801,8 +843,8 @@ void init_transport(PHY_VARS_eNB *eNB) { LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i); exit(-1); } else { - LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,eNB->dlsch[i][j]); eNB->dlsch[i][j]->rnti=0; + LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti); } } @@ -854,13 +896,18 @@ void init_eNB_afterRU() { int inst,CC_id,ru_id,i,aa; PHY_VARS_eNB *eNB; + LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst); for (inst=0;inst<RC.nb_inst;inst++) { + LOG_I(PHY,"RC.nb_CC[inst]:%d\n", RC.nb_CC[inst]); for (CC_id=0;CC_id<RC.nb_CC[inst];CC_id++) { + + LOG_I(PHY,"RC.nb_CC[inst:%d][CC_id:%d]:%d\n", inst, CC_id, RC.eNB[inst][CC_id]); + eNB = RC.eNB[inst][CC_id]; phy_init_lte_eNB(eNB,0,0); // map antennas and PRACH signals to eNB RX - AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); + if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id); eNB->frame_parms.nb_antennas_rx = 0; eNB->prach_vars.rxsigF[0] = (int16_t*)malloc16(64*sizeof(int16_t*)); @@ -868,6 +915,9 @@ void init_eNB_afterRU() { for (int ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level] = (int16_t*)malloc16(64*sizeof(int16_t*)); #endif + + LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU); + for (ru_id=0,aa=0;ru_id<eNB->num_RU;ru_id++) { eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; @@ -885,6 +935,25 @@ void init_eNB_afterRU() { eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i]; } } + + + + + if (eNB->frame_parms.nb_antennas_rx < 1) + { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx); + eNB->frame_parms.nb_antennas_rx = 1; + } + + if (eNB->frame_parms.nb_antennas_tx < 1) + { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx); + eNB->frame_parms.nb_antennas_tx = 1; + } + + + + AssertFatal(eNB->frame_parms.nb_antennas_rx >0, "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); @@ -892,9 +961,12 @@ void init_eNB_afterRU() { init_transport(eNB); init_precoding_weights(RC.eNB[inst][CC_id]); } + printf("RC.nb_CC[inst:%d]:%d CC_id:%d AFTER LOOP - About to init_eNB_proc\n", inst, RC.nb_CC[inst], CC_id); init_eNB_proc(inst); } + printf("%s() RC.nb_inst:%d AFTER LOOP\n", __FUNCTION__, RC.nb_inst); + printf("%s:%d RC.nb_RU:%d\n", __FILE__, __LINE__, RC.nb_RU); for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id); @@ -904,6 +976,8 @@ void init_eNB_afterRU() { RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; RC.ru[ru_id]->eNB_top = eNB_top; } + + LOG_I(PHY,"%s() Exitting\n", __FUNCTION__); } void init_eNB(int single_thread_flag,int wait_for_sync) { @@ -912,7 +986,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { int inst; PHY_VARS_eNB *eNB; + LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated\n"); + if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **)); + LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n"); for (inst=0;inst<RC.nb_L1_inst;inst++) { if (RC.eNB[inst] == NULL) RC.eNB[inst] = (PHY_VARS_eNB**) malloc(RC.nb_CC[inst]*sizeof(PHY_VARS_eNB *)); for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) { @@ -948,11 +1025,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { } - LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n"); - - - } diff --git a/targets/RT/USER/lte-ran.c b/targets/RT/USER/lte-ran.c index 597ceb0654c6a621df341e84637990efb1aa1b74..4f9f45df8672fd33548297dcf5c3adaa67460dce 100644 --- a/targets/RT/USER/lte-ran.c +++ b/targets/RT/USER/lte-ran.c @@ -1278,6 +1278,8 @@ void init_eNB_proc(int inst) { eNB_rxtx_proc_t *proc_rxtx; pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te; + printf("%s()\n", __FUNCTION__); + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { eNB = PHY_vars_eNB_g[inst][CC_id]; LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]); @@ -1673,10 +1675,15 @@ void init_RAN(RAN_CONTEXT *rc,eNB_func_t node_function[], eNB_timing_t node_timi PHY_VARS_eNB *eNB; int ret; + printf("%s() rc->nb_inst:%d\n", __FUNCTION__, rc->nb_inst); + for (inst=0;inst<rc->nb_inst;inst++) { + printf("%s() rc->nb_inst:%d rc->nb_CC:%d\n", __FUNCTION__, rc->nb_inst, rc->nb_CC); for (CC_id=0;CC_id<rc->nb_CC;CC_id++) { eNB = rc->eNB[inst][CC_id]; + printf("%s() rc->nb_inst:%d rc->nb_CC:%d eNB:%p rc->eNB[%d][%d]:%p\n", __FUNCTION__, rc->nb_inst, rc->nb_CC, eNB, inst, CC_id, rc->eNB[inst][CC_id]); if (eNB) { + eNB->node_function = node_function[CC_id]; eNB->node_timing = node_timing[CC_id]; eNB->abstraction_flag = 0; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index ee7d73263a9c5ce72c0aa50497e686b844b7d6c5..4a3078be9f4bfe6d8bebe6b6d76e3c6dfc2e01a1 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -592,12 +592,14 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { uint32_t symbol_number,symbol_mask,symbol_mask_full; int subframe_tx,frame_tx; +LOG_E(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru); symbol_number = 0; symbol_mask = 0; symbol_mask_full = (1<<fp->symbols_per_tti)-1; do { recv_IF4p5(ru, &frame_tx, &subframe_tx, &packet_type, &symbol_number); + LOG_E(PHY, "%s(ru:%p frame, subframe) frame_tx:%d/%d packet_type:%u symbol_number:%u proc->first_tx:%d\n", __FUNCTION__, ru, frame_tx, subframe_tx, packet_type, symbol_number, proc->first_tx); if (proc->first_tx != 0) { *frame = frame_tx; *subframe = subframe_tx; @@ -777,14 +779,80 @@ void tx_rf(RU_t *ru) { lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10); lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10); lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_tx+1)%10); + + //LOG_E(PHY,"%s() nb_tx:%d sf:%d tti:%d\n", __FUNCTION__, ru->nb_tx, proc->subframe_tx, fp->samples_per_tti); + if ((SF_type == SF_DL) || (SF_type == SF_S)) { for (i=0; i<ru->nb_tx; i++) + { txp[i] = (void*)&ru->common.txdata[i][proc->subframe_tx*fp->samples_per_tti]; + if (0) + { + if ( + (proc->frame_tx % 10 ==0 && proc->subframe_tx==0) || + (proc->frame_tx % 10 ==0 && proc->subframe_tx==5) + ) + { + LOG_E(PHY,"%s() nb_tx:%d i:%d samples_per_tti:%u subframe_tx:%u txp[i]\n", __FUNCTION__, ru->nb_tx, i, fp->samples_per_tti, proc->subframe_tx, txp[i]); + } + } + } int siglen=fp->samples_per_tti,flags=1; + if (0 && + ( + (proc->frame_tx % 300 ==0 && proc->subframe_tx==0) || + (proc->frame_tx % 300 ==0 && proc->subframe_tx==5) + ) + ) + { + uint32_t *tx0p = &txp[0]; + + LOG_E(PHY,"%s() nb_tx:%d first_carrier_offset:%u samples_per_tti:%u subframe_tx:%u sf:%u(%u) txp:%2x %2x %2x %2x %2x %2x %2x %2x\n", + __FUNCTION__, ru->nb_tx, fp->first_carrier_offset, fp->samples_per_tti, proc->subframe_tx, + SF_type, SF_type==SF_S, + tx0p[fp->first_carrier_offset], + tx0p[fp->first_carrier_offset+1], + tx0p[fp->first_carrier_offset+2], + tx0p[fp->first_carrier_offset+3], + tx0p[fp->first_carrier_offset+4], + tx0p[fp->first_carrier_offset+5], + tx0p[fp->first_carrier_offset+6], + tx0p[fp->first_carrier_offset+7] + ); + } + if ( 0 && + ( + (proc->frame_tx % 300 ==0 && proc->subframe_tx==0) || + (proc->frame_tx % 300 ==0 && proc->subframe_tx==5) + ) + ) + { + int32_t *txpbuf = RC.ru[0]->common.txdata[0]; + + char *buf = malloc(fp->symbols_per_tti * 3 + 100); + char *pbuf = buf; + + for (int i=0;i<10;i++) + { + buf[0]='\0'; + pbuf = buf; + + pbuf += sprintf(pbuf, "SF%d:", proc->subframe_tx); + + for (int k=0;k<fp->symbols_per_tti;k++) + { + pbuf += sprintf(pbuf, "%2x ", txpbuf[k]); + } + LOG_E(PHY, "%s\n", buf); + + } + free(buf); + } + if (SF_type == SF_S) { siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); flags=3; // end of burst @@ -813,12 +881,14 @@ void tx_rf(RU_t *ru) { ru->nb_tx, flags); - LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx,proc); + if (0 && proc->frame_tx % 10 ==0 && proc->subframe_tx==0) + LOG_E(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d flags:%d siglen:%d\n", + ru->idx, + proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx, flags, siglen); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - if (txs != fp->samples_per_tti) { LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); exit_fun( "problem transmitting samples" ); @@ -1109,7 +1179,7 @@ void wakeup_eNBs(RU_t *ru) { LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d\n",ru->num_eNB,ru->idx); - if (ru->num_eNB==1) { + if (ru->num_eNB==1 && ru->eNB_top!=0) { // call eNB function directly char string[20]; @@ -1120,7 +1190,7 @@ void wakeup_eNBs(RU_t *ru) { else { for (i=0;i<ru->num_eNB;i++) - if (ru->wakeup_rxtx(eNB_list[i],ru->proc.frame_rx,ru->proc.subframe_rx) < 0) + if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru->proc.frame_rx,ru->proc.subframe_rx) < 0) LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); } } @@ -1181,6 +1251,8 @@ static inline int wakeup_prach_ru_br(RU_t *ru) { } #endif +void oai_subframe_ind(uint16_t frame, uint16_t subframe); + static void* ru_thread( void* param ) { static int ru_thread_status; @@ -1216,6 +1288,11 @@ static void* ru_thread( void* param ) { phy_init_RU(ru); // } +ru->openair0_cfg.tx_gain[0]=0.0; +ru->openair0_cfg.tx_gain[1]=0.0; +ru->openair0_cfg.tx_gain[2]=0.0; +ru->openair0_cfg.tx_gain[3]=0.0; + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); if (setup_RU_buffers(ru)!=0) { printf("Exiting, cannot initialize RU Buffers\n"); @@ -1278,6 +1355,7 @@ static void* ru_thread( void* param ) { if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe); else AssertFatal(1==0, "No fronthaul interface at south port"); + oai_subframe_ind(frame, subframe); LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", ru->do_prach, @@ -1304,13 +1382,15 @@ static void* ru_thread( void* param ) { // If this proc is to provide synchronization, do so wakeup_slaves(proc); - LOG_D(PHY,"RU %d/%d frame_tx %d, subframe_tx %d\n",0,ru->idx,proc->frame_tx,proc->subframe_tx); + //LOG_E(PHY,"RU %d/%d frame_tx %d, subframe_tx %d\n",0,ru->idx,proc->frame_tx,proc->subframe_tx); // wakeup all eNB processes waiting for this RU if (ru->num_eNB>0) wakeup_eNBs(ru); + //LOG_E(PHY,"%s() Before wait_on_condition()\n", __FUNCTION__); // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread"); - + //LOG_E(PHY,"%s() AFTER wait_on_condition() ru->feptx_prec:%p ru->fh_north_asynch_in:%p ru->feptx_ofdm:%p ru->fh_south_out:%p ru->fh_north_out:%p\n", + //__FUNCTION__, ru->feptx_prec, ru->fh_north_asynch_in, ru->feptx_ofdm, ru->fh_south_out, ru->fh_north_out); // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1544,6 +1624,8 @@ int setup_RU_buffers(RU_t *ru) { */ + printf("%s() nb_rx:%d dma:%d\n", __FUNCTION__, ru->nb_rx, ru->openair0_cfg.mmapped_dma); + if (ru->openair0_cfg.mmapped_dma == 1) { // replace RX signal buffers with mmaped HW versions @@ -1578,6 +1660,7 @@ int setup_RU_buffers(RU_t *ru) { } else { // not memory-mapped DMA //nothing to do, everything already allocated in lte_init + printf("%s() Not memory-mapped DMA - nothing to do\n", __FUNCTION__); } return(0); } @@ -1637,15 +1720,20 @@ void fill_rf_config(RU_t *ru,const char *rf_config_file) { cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; +//fp->att_tx = 0; +//printf("%s() DJP - HARD CODE ALERT - fp->att_tx:%d\n", __FUNCTION__); + cfg->tx_gain[i] = (double)fp->att_tx; cfg->rx_gain[i] = ru->max_rxgain-(double)fp->att_rx; cfg->configFilename = rf_config_file; - printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", + printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f configFilename:%s fp->att_tx:%d\n", i, cfg->tx_gain[i], cfg->rx_gain[i], cfg->tx_freq[i], - cfg->rx_freq[i]); + cfg->rx_freq[i], + cfg->configFilename, + fp->att_tx); } } @@ -1835,8 +1923,9 @@ void init_RU(const char *rf_config_file) { RCconfig_RU(); printf("number of L1 instances %d, number of RU %d\n",RC.nb_L1_inst,RC.nb_RU); - for (i=0;i<RC.nb_L1_inst;i++) - for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0; + if (RC.nb_CC != 0) + for (i=0;i<RC.nb_L1_inst;i++) + for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0; for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { ru = RC.ru[ru_id]; @@ -1846,24 +1935,47 @@ void init_RU(const char *rf_config_file) { // use eNB_list[0] as a reference for RU frame parameters // NOTE: multiple CC_id are not handled here yet! - - eNB0 = ru->eNB_list[0]; - if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) - AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); + printf("%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); - if (eNB0) { - LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); - memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + if (ru->eNB_list[0] == 0) + { + LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__); + ru->eNB_list[0] = RC.eNB[0][0]; + ru->num_eNB=1; + // + // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU + // + } - // attach all RU to all eNBs in its list/ - for (i=0;i<ru->num_eNB;i++) { - eNB0 = ru->eNB_list[i]; - eNB0->RU_list[eNB0->num_RU++] = ru; + eNB0 = ru->eNB_list[0]; + printf("RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); + printf("eNB0:%p\n", eNB0); + if (eNB0) + { + if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) + AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); + + if (eNB0) { + LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); + memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + + // attach all RU to all eNBs in its list/ + for (i=0;i<ru->num_eNB;i++) { + eNB0 = ru->eNB_list[i]; + eNB0->RU_list[eNB0->num_RU++] = ru; + } } } + else + { + printf("eNB0 was NULL - DJP - missing out of copying of frame_params - NOT A GOOD THING TO MISS\n\n\n\n\n"); + //extern uint8_t n_rb_dl; + //ru->frame_parms.N_RB_DL = n_rb_dl; + //printf("ru->frame_parms.N_RB_DL:%d\n", ru->frame_parms.N_RB_DL); + } // LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); - + switch (ru->if_south) { case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) if (ru->function == NGFI_RRU_IF5) { // IF5 RRU @@ -1934,7 +2046,8 @@ void init_RU(const char *rf_config_file) { if (setup_RU_buffers(ru)!=0) { printf("Exiting, cannot initialize RU Buffers\n"); exit(-1); - }*/ + } + */ break; case REMOTE_IF5: // the remote unit is IF5 RRU diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index aaaaf82647f826a5b1da774a6bc41633e250f7f4..005ae9bc87e23efe8aef105beed3c92deb86566c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -109,6 +109,10 @@ unsigned char scope_enb_num_ue = 2; static pthread_t forms_thread; //xforms #endif //XFORMS +pthread_cond_t nfapi_sync_cond; +pthread_mutex_t nfapi_sync_mutex; +int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex + pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. @@ -204,8 +208,8 @@ int16_t glog_level = LOG_INFO; int16_t glog_verbosity = LOG_MED; int16_t hw_log_level = LOG_INFO; int16_t hw_log_verbosity = LOG_MED; -int16_t phy_log_level = LOG_INFO; -int16_t phy_log_verbosity = LOG_MED; +int16_t phy_log_level = LOG_TRACE; +int16_t phy_log_verbosity = LOG_FULL; int16_t mac_log_level = LOG_INFO; int16_t mac_log_verbosity = LOG_MED; int16_t rlc_log_level = LOG_INFO; @@ -1257,18 +1261,38 @@ void wait_eNBs() { while (waiting==1) { printf("Waiting for eNB L1 instances to all get configured ... sleeping 500ms (nb_L1_inst %d)\n",RC.nb_L1_inst); - usleep(500000); + usleep(5000000); waiting=0; - for (i=0;i<RC.nb_L1_inst;i++) - for (j=0;j<RC.nb_L1_CC[i];j++) + for (i=0;i<RC.nb_L1_inst;i++) { + + printf("RC.nb_L1_CC[%d]:%d\n", i, RC.nb_L1_CC[i]); + + for (j=0;j<RC.nb_L1_CC[i];j++) { if (RC.eNB[i][j]->configured==0) { waiting=1; break; - } + } + } + } } printf("eNB L1 are configured\n"); } +static inline void wait_nfapi_init(char *thread_name) { + + printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); + pthread_mutex_lock( &nfapi_sync_mutex ); + + while (nfapi_sync_var<0) + pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); + + pthread_mutex_unlock(&nfapi_sync_mutex); + + printf( "NFAPI: got sync (%s)\n", thread_name); +} + +uint8_t nfapi_pnf = 0; + int main( int argc, char **argv ) { int i,j,k,aa,re; @@ -1397,6 +1421,7 @@ int main( int argc, char **argv ) log_set_instance_type (LOG_INSTANCE_ENB); } + printf("ITTI init\n"); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); // initialize mscgen log after ITTI @@ -1416,6 +1441,7 @@ int main( int argc, char **argv ) } #ifdef PDCP_USE_NETLINK + printf("PDCP netlink\n"); netlink_init(); #if defined(PDCP_USE_NETLINK_QUEUES) pdcp_netlink_init(); @@ -1449,6 +1475,7 @@ int main( int argc, char **argv ) + printf("Before CC \n"); for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { if (UE_flag==1) { @@ -1510,6 +1537,7 @@ int main( int argc, char **argv ) } } + printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); cpuf=get_cpu_freq_GHz(); @@ -1517,6 +1545,7 @@ int main( int argc, char **argv ) #ifndef DEADLINE_SCHEDULER + printf("NO deadline scheduler\n"); /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ cpu_set_t cpuset; @@ -1557,7 +1586,10 @@ int main( int argc, char **argv ) #if defined(ENABLE_ITTI) + printf("ITTI enabled\n"); + printf("UE_flag:%d\n", UE_flag); + printf("RC.nb_inst:%d\n", RC.nb_inst); if ((UE_flag == 1)|| (RC.nb_inst > 0)) { @@ -1586,6 +1618,7 @@ int main( int argc, char **argv ) + printf("mlock\n"); mlockall(MCL_CURRENT | MCL_FUTURE); pthread_cond_init(&sync_cond,NULL); @@ -1594,6 +1627,8 @@ int main( int argc, char **argv ) #ifdef XFORMS int UE_id; + printf("XFORMS\n"); + if (do_forms==1) { fl_initialize (&argc, argv, NULL, 0, 0); @@ -1650,8 +1685,15 @@ int main( int argc, char **argv ) rt_sleep_ns(10*100000000ULL); + printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + if (nfapi_pnf==2) + wait_nfapi_init("main?"); + + printf("START MAIN THREADS\n"); // start the main threads if (UE_flag == 1) { @@ -1673,8 +1715,10 @@ int main( int argc, char **argv ) // for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0); } + printf("wait_eNBs()\n"); wait_eNBs(); + printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); if (RC.nb_RU >0) { printf("Initializing RU threads\n"); init_RU(rf_config_file); @@ -1684,10 +1728,16 @@ int main( int argc, char **argv ) } } + printf("wait RUs\n"); wait_RUs(); + printf("ALL RUs READY!\n"); + printf("RC.nb_RU:%d\n", RC.nb_RU); // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration) - init_eNB_afterRU(); + printf("ALL RUs ready - init eNBs\n"); + printf("DJP - commented out call to init_eNB_afterRU() will be called by nFAPI\n\n\n\n"); + //init_eNB_afterRU(); + printf("ALL RUs ready - ALL eNBs ready\n"); } @@ -1721,30 +1771,21 @@ int main( int argc, char **argv ) //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; } else { - - - + printf("eNB mode\n"); } - - - printf("Sending sync to all threads\n"); - - pthread_mutex_lock(&sync_mutex); sync_var=0; pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); - // wait for end of program printf("TYPE <CTRL-C> TO TERMINATE\n"); //getchar(); - #if defined(ENABLE_ITTI) printf("Entering ITTI signals handler\n"); itti_wait_tasks_end(); @@ -1795,6 +1836,9 @@ int main( int argc, char **argv ) pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); + pthread_cond_destroy(&nfapi_sync_cond); + pthread_mutex_destroy(&nfapi_sync_mutex); + // *** Handle per CC_id openair0