Commit 5e1065e8 authored by rmagueta's avatar rmagueta

Merge remote-tracking branch 'origin/develop' into bandwidth-testing-abs

# Conflicts:
#	executables/nr-uesoftmodem.c
#	executables/nr-uesoftmodem.h
#	executables/softmodem-common.h
#	openair1/PHY/MODULATION/slot_fep_nr.c
#	openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
#	openair1/SCHED_NR/fapi_nr_l1.c
#	openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
#	openair2/LAYER2/NR_MAC_UE/mac_proto.h
#	openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
#	openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
parents 7be39f71 11477c7a
......@@ -236,9 +236,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
......
......@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
......
......@@ -231,10 +231,11 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 6;
}
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
......
......@@ -97,7 +97,7 @@
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
......@@ -105,7 +105,7 @@
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
......@@ -114,7 +114,7 @@
<iperf_args>-u -b 20M -t 60</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>3</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
......@@ -124,7 +124,7 @@
<iperf_args>-u -b 3M -t 60</iperf_args>
<direction>UL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
......
......@@ -457,8 +457,8 @@ include_directories ("${RRC_FULL_DIR}")
#NR RRC
#######
set (NR_RRC_ASN1_VERSION "NR_Rel16" )
make_version(NR_RRC_VERSION 16 1 0)
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.1.0.asn1)
make_version(NR_RRC_VERSION 16 4 1)
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.4.1.asn1)
add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION})
set (NR_RRC_FULL_DIR ${asn1_generated_dir}/RRC_${NR_RRC_ASN1_VERSION})
......
# global
xnf is pnf or vnf
The xnf starting functions are configure_nfapi_xnf()
The OAI code that read the configuration parameters call these functions that will create autonomous thread for xnf control part
These control threads create a SCTP socket by Linux API call (no use of OpenAir internal architecture with SCTP itti thread).
The main() function of softmodem has to create and start the other threads+loop on event for appropriate work: RF Rx in pnf, NGAP, GTP-U, X2, RLC, PDCP for vnf
NFAPI has it's own code directly on Linux+Posix, it doesn't reuse any piece of the OpenAir framework: SCTP thread, thread creation and management, ...
## signaling (P5) xnf main loop
nfapi_vnf_start() create the SCTP socket, then do event waiting in a infinite loop while(vnf->terminate == 0). It accepts the pnf connections, then process the messages on reception
nfapi_pnf_start() initiate connection to vnf until it has a link. Then it enter a similar infinite loop in pnf_message_pump()
After some checks, when a message is obtained, it calls pnf_handle_p5_message() or vnf_handle_p4_p5_message() that have a switch on each p5 message types: the enum nfapi_message_id_e
Each message type has it's own processing function in the switch, like
```
case NFAPI_START_RESPONSE:
vnf_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
```
These loops are autonomous in their thread waiting incoming message.
## P7 xnf main loop
When the p5 interface receives appropriate message, it starts the p7 interface by launching a thread (see the calls to pthread_create() in nfapi/oai_integration/nfapi_xnf.c)
The p7 main loops starting is a bit simpler, thanks to UDP non connected protocol. The xnf_dispatch_p7_message() do p7 fragments re-assembly, then
calls xnf_dispatch_p7_message() that have the big switch on message type (as in p5 above description)
So, we have the logic for UL reception in vnf, and DL reception in pnf
## P7 UL transmission by PNF
RF samples are received, and decoding is done by the PNF using control data transmitted by the VNF to the PNF through downlink p7 messages (UL_TTI_req and UL_DCI_req).
After decoding, results are accumulated into the xNB->UL_INFO structure at the PNF.
The data in the UL_INFO struct is transmitted through a socket in the form of 'uplink indication functions' from the PNF to the VNF. Each uplink indication message is transmitted from their respective handle functions in NR_UL_indication(). For example,
```
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if(NFAPI_MODE == NFAPI_MODE_PNF) {
if (UL_info->rach_ind.number_of_pdus>0) {
oai_nfapi_nr_rach_indication(&UL_info->rach_ind); //This function calls the routines required for packing + transmission through socket
UL_info->rach_ind.number_of_pdus = 0;
}
}
```
## P7 UL reception at VNF
Through the infinite loop [while(vnf_p7->terminate == 0)] running in nfapi_nr_vnf_p7_start(), the VNF receives and unpacks the uplink indication message received on its socket. Based on the unpacked messages, UL_INFO struct on the VNF side gets populated.
```
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
```
vnf_nr_dispatch_p7_message() is the function that contains the switch on various message headers so that the appropriate unpack function is called.
## P7 DL Transmission by VNF
DL messages are scheduled at the VNF, through NR_UL_indication(). NR_UL_indication() is called when the SFN/slot in the UL_info structure changes (this acts as a trigger for next slot processing, instead of running a separate clock at the VNF). The SFN/slot at the VNF in UL_info is updated using the slot_indication uplink p7 message, which is sent at the beginning of every slot by the PNF. The slot_indication message contains SFN/slot of the TX_thread, so that the scheduler operates slot_ahead slots ahead of the RX thread. This ensures that UL_tti_req is received before RX slot processing at the PNF.
The function NR_schedule_response calls oai_nfapi_[DL P7 msg]_req(), which contains the routines for packing + transmission of scheduled messages through the socket to the PNF. For example, to send the 'TX_data_req' p7 message
```
if (Sched_INFO->TX_req->Number_of_PDUs > 0)
{
oai_nfapi_tx_data_req(Sched_INFO->TX_req);
}
```
```mermaid
graph TD
pselect[VNF socket pselect] -- timed out : end of slot --> call_sched[Call Scheduler NR_UL_indication] -- oai_nfapi_***_req sends the DL p7 msg--> slot_inc[Increment sfn/slot];
pselect[VNF socket pselect] -- UL p7 xyz msg recvd --> msg_recvd[Read message vnf_nr_p7_read_dispatch_message] --> header_unpack[Unpack Header] -- switch cases on header --> unpack_msg[Handle Message vnf_handle_nr_xyz] --> fill_ul_info[Fill UL info struct with fn pointer vnf_p7->_public.nr_rx_xyz];
fill_ul_info -- update pselect_timeout: next_slot_start - time_xyz_msg_recvd-->pselect;
slot_inc -- next slot --> pselect
```
Note that since DL P7 message reception and TX/RX processing are done on separate threads, there is the issue of the L1 processing threads trying to do their job before the required P7 message is received. In the case of RX processing, since the scheduler operates slot_ahead slots ahead of the RX thread, the required messages conveniently arrive earlier than they are required. However, in the case of TX processing, this cannot be ensured if the scheduler is exactly in sync with the TX thread.
Therefore, we operate the VNF vnf_slot_ahead (which is currently 2) slots ahead of the PNF. This is to ensure that the DL fapi structures for a particular TX slot are all received before TX processing for that slot.
## P7 DL Reception at PNF
Through the infinite loop [while(pnf_p7->terminate == 0)] running in pnf_nr_p7_message_pump(), the PNF receives and unpacks the downlink P7 message received on its socket. Based on the unpacked message, the appropriate message structures are filled in the PNF, and these are used further down the pipeline for processing.
While receiving the DL P7 message, we check whether the message was received within a timing window from which it was sent. The duration of the window can be set by the user (set as a parameter for xnf in the p5 messages). Note that the DL information must be received by the PNF within a timing window at least lesser than the duration of slot_ahead variable (timing_window <= slot_ahead * slot_duration).
```mermaid
graph TB
pselect[PNF socket pselect] -- timed out : end of slot --> slot_inc[Increment sfn/slot];
pselect[PNF socket pselect] -- DL p7 xyz msg recvd --> msg_recvd[Read message pnf_nr_nfapi_p7_read_dispatch_message] --> header_unpack[Unpack Header] -- switch cases on header --> unpack_msg[Unpack Message pnf_handle_nr_xyz] --> fill_pnf_p7[Fill pnf_p7 global structure pnf_handle_nr_xyz] --Data from pnf_p7 struct copied to fapi structures using pnf_phy_***_req. Called every slot from handle_nr_slot_ind-->pselect;
slot_inc -- next slot --> pselect
```
Once the messages are received, they are filled into slot buffers, and are stored until the processing of the slot that they were meant for.
# Procedure to run nFAPI in 5G NR
## Conributed by 5G Testbed IISC
### Developers: Sudhakar B,Mahesh K,Gokul S,Aniq U.R
## Contributed by 5G Testbed IISc
### Developers: Gokul S, Mahesh A, Aniq U R
## Procedure to Build gNB and UE
The regular commands to build gNB and UE can be used
```
sudo ./build_oai --gNB --UE
sudo ./build_oai --gNB --nrUE
```
## Procedure to run NR nFAPI using RF-Simulator
### Bring up another loopback interface
If running for the first time on your computer, or you have restarted your computer, bring up another loopback interface with this command:
sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up
### VNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
......@@ -27,9 +34,21 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d
```
## Procedure to run NR nFAPI using Hardware
Will be updated as we have not yet currently tested on hardware
## Procedure to run NR nFAPI using Hardware (tested with USRP x310)
### VNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
```
### PNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --nfapi 1 --phy-test
```
### UE command
```
sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test --rrc_config_path ../../../ci-scripts/rrc-files
```
## Notes
* In order to acheive the synchronization between VNF and PNF and receive the P7 messages within the timing window the order in which we should run the modules on different terminals is UE->VNF->PNF
* Currently only downlink is functional and working as we are still working on uplink functionality
......@@ -85,6 +85,7 @@
#include "T.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "executables/softmodem-common.h"
#include <nfapi/oai_integration/nfapi_pnf.h>
#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
#include <openair1/PHY/NR_TRANSPORT/nr_dlsch.h>
......@@ -147,15 +148,12 @@ void rx_func(void *param) {
start_meas(&softmodem_stats_rxtx_sf);
// *******************************************************************
// NFAPI not yet supported for NR - this code has to be revised
if (NFAPI_MODE == NFAPI_MODE_PNF) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
//add_subframe(&frame, &subframe, 4);
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
//LOG_D(PHY, "oai_nfapi_slot_ind(frame:%u, slot:%d) ********\n", frame_rx, slot_rx);
start_meas(&nfapi_meas);
// oai_subframe_ind(frame_rx, slot_rx);
oai_slot_ind(frame_rx, slot_rx);
handle_nr_slot_ind(frame_rx, slot_rx);
stop_meas(&nfapi_meas);
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
......@@ -453,6 +451,8 @@ void init_eNB_afterRU(void) {
PHY_VARS_gNB *gNB;
LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);
if(NFAPI_MODE == NFAPI_MODE_PNF)
RC.nb_nr_inst = 1;
for (inst=0; inst<RC.nb_nr_inst; inst++) {
LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
gNB = RC.gNB[inst];
......@@ -537,6 +537,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
gNB->prach_energy_counter = 0;
gNB->prb_interpolation = get_softmodem_params()->prb_interpolation;
}
......
......@@ -253,6 +253,7 @@ void init_tpools(uint8_t nun_dlsch_threads) {
}
static void get_options(void) {
nrUE_params.ofdm_offset_divisor = 8;
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
config_process_cmdline( cmdline_params,numparams,NULL);
......@@ -318,8 +319,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->rf_map.card = card_offset;
UE->rf_map.chain = CC_id + chain_offset;
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction);
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, do_prb_interpolation %d\n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->prb_interpolation);
// Set FP variables
......@@ -330,6 +331,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier);
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
}
void init_openair0(void) {
......@@ -487,6 +490,7 @@ int main( int argc, char **argv ) {
}
init_symbol_rotation(&UE[CC_id]->frame_parms);
init_timeshift_rotation(&UE[CC_id]->frame_parms);
init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
#ifdef FR2_TEST
......
......@@ -8,7 +8,8 @@
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
......@@ -29,6 +30,7 @@
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \
......@@ -61,11 +63,13 @@
{"s" , CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&(UE->prb_interpolation), defintval:0, TYPE_INT, 0}, \
}
typedef struct {
uint64_t optmask; //mask to store boolean config options
uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol
uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
tpool_t Tpool; // thread pool
} nrUE_params_t;
......
......@@ -72,6 +72,7 @@ extern "C"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n"
#define CONFIG_HLP_PRBINTER "Do PRB based averaging of channel estimates. Frequency domain linear interpolation by default\n"
#define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
......@@ -119,6 +120,7 @@ extern "C"
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
#define USIM_TEST softmodem_params.usim_test
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
#define PRB_INTERPOLATION softmodem_params.prb_interpolation
#define NFAPI softmodem_params.nfapi
#define NON_STOP softmodem_params.non_stop
......@@ -153,9 +155,10 @@ extern int usrp_tx_thread;
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config",CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
}
......@@ -246,6 +249,7 @@ typedef struct {
int hw_timing_advance;
uint32_t send_dmrs_sync;
int use_256qam_table;
int prb_interpolation;
uint8_t nfapi;
int non_stop;
} softmodem_params_t;
......
This diff is collapsed.
......@@ -19,13 +19,20 @@
* contact@openairinterface.org
*/
#if !defined(NFAPI_PNF_H__)
#define NFAPI_PNF_H__
extern nfapi_ue_release_request_body_t release_rntis;
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
void oai_slot_ind(uint16_t sfn, uint16_t slot);
#endif
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot);
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
......@@ -33,10 +33,10 @@
#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi_vnf.h"
#include "nfapi.h"
#include "vendor_ext.h"
#include "nfapi_vnf.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
......@@ -239,6 +239,18 @@ void oai_enb_init(void) {
void oai_create_gnb(void) {
int bodge_counter=0;
if (RC.gNB == NULL) {
RC.gNB = (PHY_VARS_gNB **) calloc(1, sizeof(PHY_VARS_gNB *));
LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
}
if (RC.gNB[0] == NULL) {
RC.gNB[0] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",0,RC.gNB[0]);
}
PHY_VARS_gNB *gNB = RC.gNB[0];
RC.nb_nr_CC = (int *)malloc(sizeof(int)); // TODO: find a better function to place this in
......@@ -584,7 +596,7 @@ 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) {
printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
//printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
if (sync==1 && nfapi_sync_var!=0) {
......@@ -1002,6 +1014,124 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
return 1;
}
//NR phy indication
int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
uint8_t vnf_slot_ahead = 2;
uint32_t vnf_sfn_slot = sfnslot_add_slot(ind->sfn, ind->slot, vnf_slot_ahead);
uint16_t vnf_sfn = NFAPI_SFNSLOT2SFN(vnf_sfn_slot);
uint8_t vnf_slot = NFAPI_SFNSLOT2SLOT(vnf_sfn_slot); //offsetting the vnf from pnf by vnf_slot_head slots
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = vnf_sfn;
gNB->UL_INFO.slot = vnf_slot;
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", gNB->UL_INFO.frame, gNB->UL_INFO.slot);
return 1;
}
int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.crc_ind = *ind;
if (ind->number_crcs > 0)
gNB->UL_INFO.crc_ind.crc_list = malloc(sizeof(nfapi_nr_crc_t)*ind->number_crcs);
for (int i=0; i<ind->number_crcs; i++)
memcpy(&gNB->UL_INFO.crc_ind.crc_list[i], &ind->crc_list[i], sizeof(ind->crc_list[0]));
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.rx_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.rx_ind.pdu_list = malloc(sizeof(nfapi_nr_rx_data_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++)
memcpy(&gNB->UL_INFO.rx_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.uci_ind = *ind;
if (ind->num_ucis > 0)
gNB->UL_INFO.uci_ind.uci_list = malloc(sizeof(nfapi_nr_uci_t)*ind->num_ucis);
for (int i=0; i<ind->num_ucis; i++)
memcpy(&gNB->UL_INFO.uci_ind.uci_list[i], &ind->uci_list[i], sizeof(ind->uci_list[0]));
//printf("UCI ind written to UL_info: num_ucis: %d, PDU_type : %d. \n", ind->num_ucis, ind->uci_list[0].pdu_type);
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.srs_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.srs_ind.pdu_list = malloc(sizeof(nfapi_nr_srs_indication_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++) {
memcpy(&gNB->UL_INFO.srs_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d SRS_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
__FUNCTION__,
ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.srs_ind.number_of_pdus
);
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.rach_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.rach_ind.pdu_list = malloc(sizeof(nfapi_nr_prach_indication_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++) {
memcpy(&gNB->UL_INFO.rach_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d RACH_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
__FUNCTION__,
ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.rach_ind.number_of_pdus
);
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
//end NR phy indication
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);
......@@ -1167,6 +1297,12 @@ void *vnf_nr_p7_thread_start(void *ptr) {
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->nr_crc_indication = &phy_nr_crc_indication;
p7_vnf->config->nr_slot_indication = &phy_nr_slot_indication;
p7_vnf->config->nr_rx_data_indication = &phy_nr_rx_data_indication;
p7_vnf->config->nr_uci_indication = &phy_nr_uci_indication;
p7_vnf->config->nr_rach_indication = &phy_nr_rach_indication;
p7_vnf->config->nr_srs_indication = &phy_nr_srs_indication;
p7_vnf->config->malloc = &vnf_allocate;
p7_vnf->config->free = &vnf_deallocate;
p7_vnf->config->trace = &vnf_trace;
......@@ -1501,8 +1637,8 @@ void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
nfapi_setmode(NFAPI_MODE_VNF);
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].timing_window = 30;
vnf.p7_vnfs[0].periodic_timing_enabled = 0;
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();
......@@ -1620,7 +1756,7 @@ int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
//LOG_I(PHY, "sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
//printf("\nEntering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req);
......
......@@ -19,9 +19,9 @@
* contact@openairinterface.org
*/
#if !defined(NFAPI_VNF_H__)
#define NFAPI_VNF_H__
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
#endif
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
/*
* 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.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#define MAX_MSG_LENGTH 2096
#define TRACE_HEADER_LENGTH 44
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
// initialize the trace function to 0
void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
void nfapi_set_trace_level(nfapi_trace_level_t new_level)
{
nfapi_trace_level_g = new_level;
}
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
{
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
uint32_t num_chars;
va_list p_args;
struct timeval tv;
pthread_t tid = pthread_self();
(void)gettimeofday(&tv, NULL);
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
if (num_chars > TRACE_HEADER_LENGTH)
{
printf("trace_dbg: Error, num_chars is too large: %u", num_chars);
return;
}
va_start(p_args, format);
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
{
if (level <= NFAPI_TRACE_WARN)
{
printf("%s", trace_buff);
}
printf("%s", trace_buff);
}
va_end(p_args);
}
/*
* 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.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#define MAX_MSG_LENGTH 2096
#define TRACE_HEADER_LENGTH 44
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
// initialize the trace function to 0
void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
void nfapi_set_trace_level(nfapi_trace_level_t new_level)
{
nfapi_trace_level_g = new_level;
}
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
{
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
uint32_t num_chars;
va_list p_args;
struct timeval tv;
pthread_t tid = pthread_self();
(void)gettimeofday(&tv, NULL);
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
if (num_chars > TRACE_HEADER_LENGTH)
{
printf("trace_dbg: Error, num_chars is too large: %d", num_chars);
return;
}
va_start(p_args, format);
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
{
if (level <= NFAPI_TRACE_WARN)
{
printf("%s", trace_buff);
}
printf("%s", trace_buff);
}
va_end(p_args);
}
......@@ -673,6 +673,7 @@ typedef struct {
#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_3 125 //us
typedef struct {
nfapi_p7_message_header_t header;
uint16_t sfn; //0->1023
uint16_t slot;//0->319
......@@ -1492,10 +1493,11 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t number_of_pdus;
nfapi_nr_rx_data_pdu_t* pdu_list;
nfapi_nr_rx_data_pdu_t *pdu_list;
} nfapi_nr_rx_data_indication_t;
......@@ -1518,6 +1520,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t number_crcs;
......@@ -1653,6 +1656,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t num_ucis;
......@@ -1689,6 +1693,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint8_t number_of_pdus;
......@@ -1721,6 +1726,7 @@ typedef struct{
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint8_t number_of_pdus;
......
This diff is collapsed.
This diff is collapsed.
......@@ -153,10 +153,17 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind);
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind);
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind);
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind);
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind);
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind);
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len);
#endif /* _PNF_P7_H_ */
......@@ -27,6 +27,7 @@ extern "C" {
#include <openair2/PHY_INTERFACE/IF_Module.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
#include <sys/types.h>
#include "openair1/PHY/defs_gNB.h"
......
This diff is collapsed.
......@@ -265,3 +265,77 @@ int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_re
return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t));
}
//NR UPLINK INDICATION
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
}
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
}
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
}
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
}
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
}
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
}
......@@ -278,7 +278,7 @@ void *fapi_thread_start(void *ptr) {
if(instance->tick == 1000) {
if(instance->tx_byte_count > 0) {
printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count);
printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count);
instance->tx_byte_count = 0;
}
......@@ -319,7 +319,7 @@ void *fapi_thread_start(void *ptr) {
millisec = now_ts.tv_nsec / 1e6;
if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) {
printf("*** missing millisec %u %u\n", last_millisec, millisec);
printf("*** missing millisec %d %d\n", last_millisec, millisec);
catchup = millisec - last_millisec - 1;
}
......
......@@ -25,7 +25,6 @@
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
typedef struct {
uint8_t* buffer;
uint16_t length;
......
......@@ -852,7 +852,15 @@ typedef struct nfapi_vnf_p7_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*nrach_indication)(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind);
//The NR indication functions below copy uplink information received at the VNF into the UL info struct
int (*nr_slot_indication)(nfapi_nr_slot_indication_scf_t* ind);
int (*nr_crc_indication)(nfapi_nr_crc_indication_t* ind);
int (*nr_rx_data_indication)(nfapi_nr_rx_data_indication_t* ind);
int (*nr_uci_indication)(nfapi_nr_uci_indication_t* ind);
int (*nr_rach_indication)(nfapi_nr_rach_indication_t* ind);
int (*nr_srs_indication)(nfapi_nr_srs_indication_t* ind);
/*! A callback for any vendor extension messages
* \param config A pointer to the vnf p7 configuration
* \param msg A data structure for the decoded vendor extention message allocated
......
This diff is collapsed.
This diff is collapsed.
......@@ -460,6 +460,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
nr_init_frame_parms(gNB_config, fp);
fp->ofdm_offset_divisor = UINT_MAX;
gNB->configured = 1;
LOG_I(PHY,"gNB configured\n");
}
......@@ -511,7 +512,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
// }
RC.gNB[Mod_id]->configured = 1;
fp->ofdm_offset_divisor = RC.gNB[Mod_id]->ofdm_offset_divisor;
init_symbol_rotation(fp);
init_timeshift_rotation(fp);
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
......
......@@ -124,7 +124,7 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch,
AssertFatal( pusch, "pusch==0" );
for (int i=0; i<NR_MAX_NB_LAYERS; i++) {
pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *));
pusch->txdataF_layers[i] = (int32_t *)malloc16_clear(NR_MAX_PUSCH_ENCODED_LENGTH*sizeof(int32_t));
}
}
......
......@@ -49,7 +49,7 @@ void PHY_ofdm_mod(int *input,
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms);
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot);
void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
......
......@@ -745,6 +745,23 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
}
}
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp)
{
for (int i = 0; i < fp->ofdm_symbol_size; i++) {
double poff = -i * 2.0 * M_PI * 144.0 / 2048.0 / fp->ofdm_offset_divisor;
double exp_re = cos(poff);
double exp_im = sin(-poff);
fp->timeshift_symbol_rotation[i*2] = (int16_t)round(exp_re * 32767);
fp->timeshift_symbol_rotation[i*2+1] = (int16_t)round(exp_im * 32767);
if (i < 10)
LOG_I(PHY,"Timeshift symbol rotation %d => (%d,%d) %f\n",i,
fp->timeshift_symbol_rotation[i*2],
fp->timeshift_symbol_rotation[i*2+1],
poff);
}
}
int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset)
{
int32_t precodatatx_F = 0;
......
......@@ -117,6 +117,8 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp);
void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF,
int slot,
......
......@@ -63,20 +63,62 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
}
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms)
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot)
{
PHY_ofdm_mod(txdataF, // input
txdata, // output
frame_parms->ofdm_symbol_size,
1, // number of symbols
frame_parms->nb_prefix_samples0, // number of prefix samples
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0, // output
frame_parms->ofdm_symbol_size,
nsymb - 1,
frame_parms->nb_prefix_samples, // number of prefix samples
CYCLIC_PREFIX);
// This function works only slot wise. For more generic symbol generation refer nr_feptx0()
if (frame_parms->numerology_index != 0) { // case where numerology != 0
if (!(slot%(frame_parms->slots_per_subframe/2))) {
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
nsymb - 1,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
else {
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
nsymb,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
}
else { // numerology = 0, longer CP for every 7th symbol
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
6,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF + 7*frame_parms->ofdm_symbol_size,
txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) +
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF + 8*frame_parms->ofdm_symbol_size,
txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) +
2*(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0),
frame_parms->ofdm_symbol_size,
6,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
}
void PHY_ofdm_mod(int *input, /// pointer to complex input
......
......@@ -107,7 +107,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
rx_offset += frame_parms->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= nb_prefix_samples / 8;
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
//#ifdef DEBUG_FEP
// if (ue->frame <100)
......@@ -157,6 +157,15 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
frame_parms->ofdm_symbol_size,
15);
int16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
shift_rot,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1,
frame_parms->ofdm_symbol_size,
15);
}
#ifdef DEBUG_FEP
......@@ -292,14 +301,15 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
// offset of first OFDM symbol
int32_t rxdata_offset = slot_offset + nb_prefix_samples0;
// offset of n-th OFDM symbol
rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples);
unsigned int rxdata_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rxdata_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rxdata_offset += frame_parms->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rxdata_offset -= nb_prefix_samples / 8;
rxdata_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
int16_t *rxdata_ptr;
......@@ -333,9 +343,6 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size],
1);
// clear DC carrier from OFDM symbols
rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
return 0;
}
......@@ -349,7 +356,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
for (int symbol=0;symbol<nsymb;symbol++) {
for (int symbol=first_symbol;symbol<nsymb;symbol++) {
uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
......@@ -359,5 +366,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
(int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)],
length,
15);
int16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
shift_rot,
(int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
1,
length,
15);
}
}
......@@ -39,23 +39,22 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
{
int i, aa, max_pos = 0, max_val = 0;
int max_pos = 0, max_val = 0;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id];
int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
int sync_pos = frame_parms->nb_prefix_samples / 8;
for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
const int sync_pos = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
int temp = 0;
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
int Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
int Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
if (temp > max_val) {
max_pos = i;
max_val = temp;
......@@ -65,7 +64,6 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
if (max_pos > frame_parms->ofdm_symbol_size/2)
max_pos = max_pos - frame_parms->ofdm_symbol_size;
return max_pos - sync_pos;
}
......
......@@ -174,7 +174,11 @@ void rx_nr_prach_ru(RU_t *ru,
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
int sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
int sample_offset_slot;
if (!(slot%(fp->slots_per_subframe/2)))
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
else
sample_offset_slot = (prachStartSymbol==0?0:prachStartSymbol*(fp->ofdm_symbol_size+fp->nb_prefix_samples));
//to be checked for mu=0;
LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion);
......
......@@ -48,6 +48,8 @@
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "T.h"
//#define DEBUG_NR_PUCCH_RX 1
......@@ -1446,7 +1448,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
corr_tmp += corr_re*corr_re + corr_im*corr_im;
} // aa loop
}// group loop
LOG_D(PHY,"cw %d, metric %f dB\n",cw,10*log10(corr_tmp));
if (corr_tmp > corr) {
corr = corr_tmp;
cw_ML=cw;
......
......@@ -239,3 +239,24 @@ short filt8_dcll2[8] = {
short filt8_dclh2[8] = {
0,0,0,0,1489,2979,4468,5958};
short filt8_avlip0[8] = {
16384,16384,16384,16384,16384,16384,16384,15019};
short filt8_avlip1[8] = {
13653,12288,10923,9557,8192,6827,5461,4096};
short filt8_avlip2[8] = {
2731,1365,0,0,0,0,0,0};
short filt8_avlip3[8] = {
2731,4096,5461,6827,8192,9557,10923,12288};
short filt8_avlip4[8] = {
13653,15019,16384,15019,13653,12288,10923,9557};
short filt8_avlip5[8] = {
8192,6827,5461,4096,2731,1365,0,0};
short filt8_avlip6[8] = {
13653,15019,16384,16384,16384,16384,16384,16384};
......@@ -169,4 +169,17 @@ extern short filt8_dcll2[8];
extern short filt8_dclh2[8];
#endif
\ No newline at end of file
extern short filt8_avlip0[8];
extern short filt8_avlip1[8];
extern short filt8_avlip2[8];
extern short filt8_avlip3[8];
extern short filt8_avlip4[8];
extern short filt8_avlip5[8];
extern short filt8_avlip6[8];
#endif
......@@ -45,25 +45,23 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
static int max_pos_fil = 0;
static int count_max_pos_ok = 0;
static int first_time = 1;
int temp = 0, i, aa, max_val = 0, max_pos = 0;
int diff;
short Re,Im,ncoef;
int max_val = 0, max_pos = 0;
const int sync_pos = 0;
uint8_t sync_offset = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
ncoef = 32767 - coef;
short ncoef = 32767 - coef;
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
// we only use channel estimates from tx antenna 0 here
for (i = 0; i < frame_parms->nb_prefix_samples; i++) {
temp = 0;
for (int i = 0; i < frame_parms->nb_prefix_samples; i++) {
int temp = 0;
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
int Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
int Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
......@@ -73,6 +71,9 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
}
}
if (max_pos > frame_parms->ofdm_symbol_size/2)
max_pos = max_pos - frame_parms->ofdm_symbol_size;
// filter position to reduce jitter
if (clear == 1)
max_pos_fil = max_pos;
......@@ -82,61 +83,58 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
// do not filter to have proactive timing adjustment
//max_pos_fil = max_pos;
diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
if(abs(diff)<5)
count_max_pos_ok ++;
else
count_max_pos_ok = 0;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if(count_max_pos_ok > 10 && first_time == 1)
{
first_time = 0;
ue->time_sync_cell = 1;
if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else {
ue->UE_mode[0] = PUSCH;
}
}
if (ue->rx_offset < 0)
ue->rx_offset += frame_parms->samples_per_frame;
if (ue->rx_offset >= frame_parms->samples_per_frame)
ue->rx_offset -= frame_parms->samples_per_frame;
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
subframe,
diff,
ue->rx_offset,
clear,
max_pos,
max_pos_fil,
temp,max_val,
(frame_parms->nb_prefix_samples>>3));
#endif //DEBUG_PHY
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
int diff = max_pos_fil - sync_pos;
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
if(abs(diff)<5)
count_max_pos_ok ++;
else
count_max_pos_ok = 0;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if(count_max_pos_ok > 10 && first_time == 1)
{
first_time = 0;
ue->time_sync_cell = 1;
if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else {
ue->UE_mode[0] = PUSCH;
}
}
if (ue->rx_offset < 0)
ue->rx_offset += frame_parms->samples_per_frame;
if (ue->rx_offset >= frame_parms->samples_per_frame)
ue->rx_offset -= frame_parms->samples_per_frame;
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
subframe,
diff,
ue->rx_offset,
clear,
max_pos,
max_pos_fil,
max_val,
sync_pos);
#endif //DEBUG_PHY
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
}
......@@ -984,6 +984,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
}
}
}
pdcch_vars->nb_search_space = 0;
return(dci_ind->number_of_dcis);
}
......
......@@ -445,8 +445,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh);
if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
......@@ -461,8 +459,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
avgs = cmax(avgs, median[aatx*n_rx + aarx]);
}
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh);
}
LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
frame%1024,
......
......@@ -102,7 +102,11 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
ue->X_u);
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
if (slot % (fp->slots_per_subframe / 2) == 0)
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
else
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol;
prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot;
//printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start);
......
......@@ -1044,7 +1044,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
unsigned int G);
......
......@@ -215,11 +215,13 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
}
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
unsigned int G)
{
start_meas(&ue->ulsch_encoding_stats);
/////////////////////////parameters and variables declaration/////////////////////////
///////////
......@@ -332,6 +334,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_segmentation_stats);
Kb=nr_segmentation(harq_process->b,
harq_process->c,
harq_process->B,
......@@ -340,6 +343,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
pz,
&harq_process->F,
harq_process->BG);
stop_meas(&ue->ulsch_segmentation_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT);
F = harq_process->F;
......@@ -374,14 +378,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//for (int i=0;i<68*384;i++)
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
int temp_opp = 0;
if (opp_enabled) {
opp_enabled = 0;
temp_opp = 1;
}
/*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]);
for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
printf("%d \n", harq_process->d[0][cnt]);
......@@ -397,11 +393,13 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_ldpc_encoding_stats);
for(int j = 0; j < (harq_process->C/8 + 1); j++)
{
impp.macro_num = j;
nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,harq_process->BG,&impp);
}
stop_meas(&ue->ulsch_ldpc_encoding_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT);
......@@ -412,8 +410,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
#endif
if (temp_opp) opp_enabled = 1;
///////////
///////////////////////////////////////////////////////////////////////////////
LOG_D(PHY,"setting ndi to %d from pusch_data\n", harq_process->pusch_pdu.pusch_data.new_data_indicator);
......@@ -449,6 +445,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_rate_matching_stats);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
harq_process->BG,
......@@ -460,6 +457,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Kr-F-2*(*pz),
harq_process->pusch_pdu.pusch_data.rv_index,
E);
stop_meas(&ue->ulsch_rate_matching_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_OUT);
......@@ -481,10 +479,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//start_meas(i_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_interleaving_stats);
nr_interleaving_ldpc(E,
mod_order,
harq_process->e+r_offset,
harq_process->f+r_offset);
stop_meas(&ue->ulsch_interleaving_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT);
//stop_meas(i_stats);
......@@ -509,5 +509,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
stop_meas(&ue->ulsch_encoding_stats);
return(0);
}
......@@ -159,7 +159,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G);
///////////
////////////////////////////////////////////////////////////////////
......@@ -529,7 +529,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
nr_normal_prefix_mod(txdataF[ap],
&txdata[ap][tx_offset],
14,
frame_parms);
frame_parms,
slot);
}
}
......
......@@ -264,7 +264,7 @@ double signal_energy_fp(double *s_re[2],double *s_im[2],uint32_t nb_antennas,uin
return(V/length/nb_antennas);
}
double signal_energy_fp2(struct complex *s,uint32_t length)
double signal_energy_fp2(struct complexd *s,uint32_t length)
{
int32_t i;
......@@ -273,7 +273,7 @@ double signal_energy_fp2(struct complex *s,uint32_t length)
for (i=0; i<length; i++) {
// printf("signal_energy_fp2 : %f,%f => %f\n",s[i].x,s[i].y,V);
// V= V + (s[i].y*s[i].x) + (s[i].y*s[i].x);
V= V + (s[i].x*s[i].x) + (s[i].y*s[i].y);
V= V + (s[i].r*s[i].r) + (s[i].i*s[i].i);
}
return(V/length);
......
......@@ -39,11 +39,6 @@ extern "C" {
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
struct complex {
double x;
double y;
};
struct complexd {
double r;
double i;
......@@ -468,7 +463,7 @@ double signal_energy_fp(double *s_re[2], double *s_im[2], uint32_t nb_antennas,
/*!\fn double signal_energy_fp2(struct complex *, uint32_t);
\brief Computes the signal energy per subcarrier
*/
double signal_energy_fp2(struct complex *s, uint32_t length);
double signal_energy_fp2(struct complexd *s, uint32_t length);
int32_t iSqrt(int32_t value);
......
......@@ -822,6 +822,8 @@ typedef struct PHY_VARS_gNB_s {
uint32_t max_peak_val;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
/// \brief sinr for all subcarriers of the current link (used only for abstraction).
/// first index: ? [0..N_RB_DL*12[
double *sinr_dB;
......@@ -841,6 +843,8 @@ typedef struct PHY_VARS_gNB_s {
int **dl_precoder_SgNB[3];
char log2_maxp; /// holds the maximum channel/precoder coefficient
int prb_interpolation;
/// if ==0 enables phy only test mode
int mac_enabled;
/// counter to average prach energh over first 100 prach opportunities
......
......@@ -868,7 +868,9 @@ typedef struct {
uint32_t perfect_ce;
// flag to activate PRB based averaging of channel estimates
// when off, defaults to frequency domain interpolation
int prb_interpolation;
int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX];
UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX];
......@@ -1005,6 +1007,7 @@ typedef struct {
time_stats_t ofdm_mod_stats;
time_stats_t ulsch_encoding_stats;
time_stats_t ulsch_ldpc_encoding_stats;
time_stats_t ulsch_modulation_stats;
time_stats_t ulsch_segmentation_stats;
time_stats_t ulsch_rate_matching_stats;
......
......@@ -234,8 +234,6 @@ typedef struct {
int RA_PCMAX;
/// Corresponding RA-RNTI for UL-grant
uint16_t ra_RNTI;
/// Pointer to Msg3 payload for UL-grant
uint8_t *Msg3;
/// Frame of last completed synch
uint16_t sync_frame;
/// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync
......@@ -331,6 +329,9 @@ struct NR_DL_FRAME_PARMS {
/// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211
/// First dimension is for the direction of the link (0 DL, 1 UL)
int16_t symbol_rotation[2][224*2];
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths
int16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// shift of pilot position in one RB
uint8_t nushift;
/// SRS configuration from TS 38.331 RRC
......@@ -364,6 +365,8 @@ struct NR_DL_FRAME_PARMS {
uint8_t ssb_index;
/// PBCH polar encoder params
t_nrPolar_params pbch_polar_params;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
};
......
......@@ -17,6 +17,10 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
......
......@@ -17,6 +17,10 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
......
This diff is collapsed.
......@@ -119,6 +119,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples,
CYCLIC_PREFIX);
slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size;
slot_offsetF += fp->ofdm_symbol_size;
}
else {
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
......@@ -128,6 +129,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples0,
CYCLIC_PREFIX);
slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size;
slot_offsetF += fp->ofdm_symbol_size;
}
}
}
......
......@@ -147,14 +147,14 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
for (int i=0; i<fp->Lmax; i++) {
if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
}
for (int i=0; i<fp->Lmax; i++) {
if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
int pdcch_pdu_id=find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST);
......@@ -421,7 +421,13 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
timing_advance_update = sync_pos / bw_scaling;
int sync_pos_rounded;
// do some integer rounding to improve TA accuracy
if (sync_pos > 0)
sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1;
else
sync_pos_rounded = sync_pos - (bw_scaling / 2) - 1;
timing_advance_update = sync_pos_rounded / bw_scaling;
// put timing advance command in 0..63 range
timing_advance_update += 31;
......
......@@ -70,7 +70,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
for (i = 0; i < dl_config->number_pdus; ++i){
AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
AssertFatal(dl_config->dl_config_list[i].pdu_type<=FAPI_NR_DL_CONFIG_TYPES,"pdu_type %d > 2\n",dl_config->dl_config_list[i].pdu_type);
LOG_D(PHY, "In %s: received 1 DL %s PDU of %d total DL PDUs:\n", __FUNCTION__, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus);
LOG_D(PHY, "In %s: frame %d slot %d received 1 DL %s PDU of %d total DL PDUs:\n",
__FUNCTION__, scheduled_response->frame, slot, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus);
if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) {
......@@ -227,9 +228,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
break;
}
}
memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t));
}
}
return 0;
......
......@@ -480,8 +480,8 @@ unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb
#ifdef NR_PDCCH_SCHED
int nr_ue_pdcch_procedures(uint8_t gNB_id,
PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int n_ss)
{
int frame_rx = proc->frame_rx;
......@@ -1682,7 +1682,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d (energy %d dB)****** \n",
LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d (energy %d dB)****** \n",
frame_rx%1024, nr_slot_rx,
dB_fixed(signal_energy(ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0],2048*14)));
......@@ -2141,7 +2141,8 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
int16_t ra_preamble_rx_power = (int16_t)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power);
LOG_D(PHY,"DEBUG [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n",
LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n",
__FUNCTION__,
mod_id,
frame_tx,
nr_slot_tx,
......
This diff is collapsed.
This diff is collapsed.
......@@ -1111,8 +1111,8 @@ int main(int argc, char **argv) {
for (aarx=0; aarx<UE2eNB->nb_rx; aarx++) {
for (aatx=0; aatx<UE2eNB->nb_tx; aatx++) {
// abs_channel = (eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x + eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y);
channelx = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].x;
channely = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].y;
channelx = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].r;
channely = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].i;
// if(transmission_m==5){
fprintf(csv_fdUL,"%e+i*(%e),",channelx,channely);
// }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment