Commit d83251d4 authored by Calvin's avatar Calvin

implement rrc list module, declair in rrc_inst and initialization, finish part...

implement rrc list module, declair in rrc_inst and initialization, finish part of l12 FAPI messages, DCI0, DCI1, DCI2 and UCI, part of DCI_IND messages
parent 73cfa6bb
/*
* 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 _NFAPI_INTERFACE_NR_EXTENSION_H_
#define _NFAPI_INTERFACE_NR_EXTENSION_H_
#define _NFAPI_INTERFACE_H_
#include "stddef.h"
// Constants - update based on implementation
#define NR_NFAPI_MAX_PHY_RF_INSTANCES 2
#define NR_NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH 16
#define NR_NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH 3
#define NR_NFAPI_MAX_NUM_RF_BANDS 16
// The following definition control the size of arrays used in the interface.
// These may be changed if desired. They are used in the encoder to make sure
// that the user has not specified a 'count' larger than the max array, and also
// used by the decoder when decode an array. If the 'count' received is larger
// than the array it is to be stored in the decode fails.
#define NR_NFAPI_MAX_NUM_ANTENNAS 8
#define NR_NFAPI_MAX_NUM_SUBBANDS 13
#define NR_NFAPI_MAX_BF_VECTORS 8
#define NR_NFAPI_MAX_CC 1
#define NR_NFAPI_MAX_NUM_PHYSICAL_ANTENNAS 8
#define NR_NFAPI_MAX_RSSI 8
#define NR_NFAPI_MAX_PSC_LIST 32
#define NR_NFAPI_MAX_PCI_LIST 32
#define NR_NFAPI_MAX_CARRIER_LIST 32
#define NR_NFAPI_MAX_ARFCN_LIST 128
#define NR_NFAPI_MAX_LTE_CELLS_FOUND 8
#define NR_NFAPI_MAX_UTRAN_CELLS_FOUND 8
#define NR_NFAPI_MAX_GSM_CELLS_FOUND 8
#define NR_NFAPI_MAX_NB_IOT_CELLS_FOUND 8
#define NR_NFAPI_MAX_SI_PERIODICITY 8
#define NR_NFAPI_MAX_SI_INDEX 8
#define NR_NFAPI_MAX_MIB_LENGTH 32
#define NR_NFAPI_MAX_SIB_LENGTH 256
#define NR_NFAPI_MAX_SI_LENGTH 256
#define NR_NFAPI_MAX_OPAQUE_DATA 64
#define NR_NFAPI_MAX_NUM_SCHEDULED_UES 8 // Used in the TPM structure
#define NR_NFAPI_MAX_PNF_PHY 5
#define NR_NFAPI_MAX_PNF_PHY_RF_CONFIG 5
#define NR_NFAPI_MAX_PNF_RF 5
#define NR_NFAPI_MAX_NMM_FREQUENCY_BANDS 32
#define NR_NFAPI_MAX_RECEIVED_INTERFERENCE_POWER_RESULTS 100
#define NR_NFAPI_MAX_UL_DL_CONFIGURATIONS 5
#define NR_NFAPI_MAX_CSI_RS_RESOURCE_CONFIG 4
#define NR_NFAPI_MAX_ANTENNA_PORT_COUNT 8
#define NR_NFAPI_MAX_EPDCCH_PRB 8
#define NR_NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS 8
#define NR_NFAPI_MAX_NUMBER_ACK_NACK_TDD 8
#define NR_NFAPI_MAX_RO_DL 8
#define NR_NFAPI_HEADER_LENGTH 8
#define NR_NFAPI_P7_HEADER_LENGTH 16
#define NR_NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE 0xF000
#define NR_NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE 0xFFFF
#define NR_NFAPI_VERSION_3_0_11 0x000
#define NR_NFAPI_VERSION_3_0_12 0x001
#define NR_NFAPI_HALF_FRAME_INDEX_FIRST_HALF 0
#define NR_NFAPI_HALF_FRAME_INDEX_SECOND_HALF 1
// The IANA agreed port definition of the P5 SCTP VNF enpoint
// http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=7701
#define NR_NFAPI_P5_SCTP_PORT 7701
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef signed int int32_t;
typedef signed short int16_t;
typedef signed char int8_t;
typedef struct {
uint16_t phy_id;
uint16_t message_id;
uint16_t message_length;
uint16_t spare;
} nr_nfapi_p4_p5_message_header_t;
typedef struct {
uint16_t phy_id;
uint16_t message_id;
uint16_t message_length;
uint16_t m_segment_sequence; /* This consists of 3 fields - namely, M, Segement & Sequence number*/
uint32_t checksum;
uint32_t transmit_timestamp;
} nr_nfapi_p7_message_header_t;
typedef struct {
uint16_t tag;
uint16_t length;
} nr_nfapi_tl_t;
#define NR_NFAPI_TAG_LENGTH_PACKED_LEN 4
typedef struct {
nr_nfapi_tl_t tl;
// common C-RNTI
uint8_t dci_format;
uint8_t frequency_domain_resouce_assignment; // 38.214 chapter 5.1.2.2
uint8_t time_domain_resource_assignment; // 38.214 chapter 5.1.2.1
uint8_t frequency_hopping_enabled_flag;
uint8_t frequency_hopping_bits;
uint8_t mcs;
uint8_t new_data_indication;
uint8_t redundancy_version;
uint8_t harq_process;
uint8_t tpc_command;
// format 0_0 C-RNTI
uint8_t ul_sul_ind;
// format 0_1 C-RNTI
uint8_t carrier_indicator;
uint8_t bwp_indndicator;
uint8_t vrb_to_prb_mapping;
uint8_t downlink_assignment_index_1;
uint8_t downlink_assignment_index_2;
uint8_t srs_resource_indicator;
uint8_t precoding_information;
uint8_t antenna_ports;
uint8_t srs_request;
uint8_t cqi_csi_request;
uint8_t cbg_transmission_information;
uint8_t ptrs_dmrs_association;
// format 0_1 CS-RNTI
// format 0_1 SP-CSI-RNTI
} nr_nfapi_dci0_pdu_rel15_t;
#define NR_NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG 0x2020
typedef struct {
nr_nfapi_tl_t tl;
// common C-RNTI, TC-RNTI and RA-RNTI
uint8_t dci_format;
uint8_t frequency_domain_resouce_assignment;
uint8_t time_domain_resource_assignment;
uint8_t vrb_to_prb_mapping;
uint8_t mcs;
uint8_t new_data_indication;
uint8_t redundancy_version;
uint8_t harq_process;
uint8_t downlink_assignment_index;
uint8_t tpc_command;
uint8_t pucch_resource_indicator;
uint8_t pdsch_to_harq_feedback_timing_indicator;
// format 1_0 P-RNTI
uint8_t short_messages_indicator;
// format 1_0 SI-RNTI
// format 1_0 CS-RNTI
// format 1_1 C-RNTI
uint8_t carrier_indicator;
uint8_t bwp_indndicator;
uint8_t prb_bundling_size_indicator; // 38.214 chapter 5.1.2.3
uint8_t rate_matching_indicator;
uint8_t zp_csi_rs_trigger;
uint8_t antenna_ports;
uint8_t transmission_configuration_indication;
uint8_t srs_request;
uint8_t cbg_transmission_information;
uint8_t cbg_flushing_out_information;
// format 1_1 CS-RNTI
} nr_nfapi_dci1_pdu_rel15_t;
#define NR_NFAPI_DCI1_REQUEST_DCI_PDU_REL8_TAG 0x2020
typedef struct {
nr_nfapi_tl_t tl;
// common
uint8_t dci_format;
// format 2_0 SFI-RNTI (SFI)
uint8_t slot_format_count;
uint8_t *slot_format_indicators; // 38.213 chapter 11.1.1
// format 2_1 INT-RNTI (INT)
uint8_t preemption_indication_count;
uint8_t *preemption_indications; // 38.213 chapter 11.2
// format 2_2 TPC-PUSCH-RNTI and TPC-PUCCH-RNTI (TPC for PUSCH, PUCCH)
uint8_t tpc_command_count;
uint8_t *tpc_command_numbers;
// format 2_3 TPC-SRS-RNTI (TPC for SRS)
uint8_t block_number_count;
uint8_t *block_numbers;
// 38.212 chapter 7.3.1.3.4
uint8_t srs_request; // 38.212 table 7.3.1.1.2-5
uint8_t tpc_command;
} nr_nfapi_dci2_pdu_rel15_t;
typedef struct {
nr_nfapi_tl_t tl;
uint8_t uci_format;
uint8_t uci_channel;
uint8_t harq_ack_bits;
uint32_t harq_ack;
uint8_t csi_bits;
uint32_t csi;
uint8_t sr_bits;
uint32_t sr;
} nr_nfapi_uci_pdu_rel15_t;
//
// Top level NFAPI messages
//
//
// P7
//
typedef struct {
uint16_t rnti;
uint8_t dci_type;
uint8_t dci_size;
union {
nr_nfapi_dci0_pdu_rel15_t dci0;
nr_nfapi_dci1_pdu_rel15_t dci1;
nr_nfapi_dci2_pdu_rel15_t dci2;
} ;
}nr_nfapi_dci_indication_pdu_t;
typedef struct {
nr_nfapi_tl_t tl;
uint16_t number_of_dcis;
nr_nfapi_dci_indication_pdu_t* dci_list;
} nr_nfapi_dci_indication_body_t;
///
typedef struct {
nr_nfapi_p7_message_header_t header;
uint16_t sfn_sf_slot;
nr_nfapi_dci_indication_body_t dci_indication_body;
} nr_nfapi_dci_indication_t;
#define NR_NFAPI_TX_MAX_PDU 100
typedef struct {
nr_nfapi_tl_t tl;
uint8_t* data;
} nr_nfapi_rx_request_body_t;
#define NR_NFAPI_TX_REQUEST_BODY_TAG 0x2022
///
typedef struct {
nr_nfapi_p7_message_header_t header;
uint16_t sfn_sf_slot;
nr_nfapi_rx_request_body_t rx_request_body;
} nr_nfapi_rx_indication_t;
typedef struct {
nr_nfapi_tl_t tl;
uint8_t ul_cqi;
uint16_t timing_advance;
} nr_nfapi_tx_indication_t;
#define NR_NFAPI_TX_MAX_SEGMENTS 32
typedef struct {
uint16_t pdu_length;
uint16_t pdu_index;
uint8_t num_segments;
struct {
uint32_t segment_length;
uint8_t* segment_data;
} segments[NR_NFAPI_TX_MAX_SEGMENTS];
} nr_nfapi_tx_indication_pdu_t;
#define NR_NFAPI_RX_IND_MAX_PDU 100
typedef struct {
nr_nfapi_tl_t tl;
nr_nfapi_tx_indication_t tx_indication;
uint16_t number_of_pdus;
nr_nfapi_tx_indication_pdu_t* tx_pdu_list;
} nr_nfapi_tx_indication_body_t;
#define NR_NFAPI_RX_INDICATION_BODY_TAG 0x2023
///
typedef struct {
nr_nfapi_p7_message_header_t header;
uint16_t sfn_sf_slot;
nr_nfapi_tx_indication_body_t tx_indication_body;
} nr_nfapi_tx_request_t;
typedef struct {
uint8_t pdu_type;
uint8_t pdu_size;
union {
/*nr_nfapi_ul_config_ulsch_pdu ulsch_pdu;
nr_nfapi_ul_config_ulsch_cqi_ri_pdu ulsch_cqi_ri_pdu;
nr_nfapi_ul_config_ulsch_harq_pdu ulsch_harq_pdu;
nr_nfapi_ul_config_ulsch_cqi_harq_ri_pdu ulsch_cqi_harq_ri_pdu;
nr_nfapi_ul_config_uci_cqi_pdu uci_cqi_pdu;
nr_nfapi_ul_config_uci_sr_pdu uci_sr_pdu;
nr_nfapi_ul_config_uci_harq_pdu uci_harq_pdu;
nr_nfapi_ul_config_uci_sr_harq_pdu uci_sr_harq_pdu;
nr_nfapi_ul_config_uci_cqi_harq_pdu uci_cqi_harq_pdu;
nr_nfapi_ul_config_uci_cqi_sr_pdu uci_cqi_sr_pdu;
nr_nfapi_ul_config_uci_cqi_sr_harq_pdu uci_cqi_sr_harq_pdu;
nr_nfapi_ul_config_srs_pdu srs_pdu;
nr_nfapi_ul_config_harq_buffer_pdu harq_buffer_pdu;
nr_nfapi_ul_config_ulsch_uci_csi_pdu ulsch_uci_csi_pdu;
nr_nfapi_ul_config_ulsch_uci_harq_pdu ulsch_uci_harq_pdu;
nr_nfapi_ul_config_ulsch_csi_uci_harq_pdu ulsch_csi_uci_harq_pdu;*/
};
} nr_nfapi_ul_config_request_pdu_t;
typedef struct {
nr_nfapi_tl_t tl;
nr_nfapi_ul_config_request_pdu_t ul_config_pdu_list;
} nr_nfapi_ul_config_request_body_t;
///
typedef struct {
nr_nfapi_p7_message_header_t header;
uint16_t sfn_sf_slot;
nr_nfapi_ul_config_request_body_t ul_config_request_body;
} nr_nfapi_ul_config_request_t;
typedef struct {
uint32_t frequency_domain_resource;
uint8_t duration;
uint8_t cce_reg_mapping_type;
uint8_t cce_reg_interleaved_reg_bundle_size; // valid if CCE to REG mapping type is interleaved type
uint8_t cce_reg_interleaved_interleaver_size; // valid if CCE to REG mapping type is interleaved type
uint8_t cce_reg_interleaved_shift_index; // valid if CCE to REG mapping type is interleaved type
uint8_t precoder_granularity;
uint8_t tci_state_pdcch;
uint8_t tci_present_in_dci;
uint16_t pdcch_dmrs_scrambling_id;
}nr_nfapi_coreset_t;
typedef struct {
uint8_t monitoring_slot_peridicity;
uint8_t monitoring_slot_offset;
uint16_t monitoring_symbols_within_slot;
uint8_t aggregation_level;
uint8_t number_of_candidates;
uint8_t search_space_type;
union {
struct {
uint8_t dci_0_0_and_1_0;
uint8_t dci_2_0_aggregation_level;
uint8_t dci_2_0_number_of_candidates;
uint8_t dci_2_1; // empty now
uint8_t dci_2_2; // empty now
uint8_t dci_2_3_monitorying_periodicity;
uint8_t dci_2_3_number_of_candidates;
} css;
struct {
uint8_t dci_formats;
} uss;
};
}nr_nfapi_search_space_t;
typedef struct {
nr_nfapi_search_space_t search_space_sib1;
nr_nfapi_search_space_t search_space_others_sib;
nr_nfapi_search_space_t search_space_paging;
nr_nfapi_coreset_t coreset_ra;
nr_nfapi_search_space_t search_space_ra;
} nr_nfapi_pdcch_config_common_t;
typedef struct {
uint8_t k0;
uint8_t mapping_type;
uint8_t start_symbol;
uint8_t length_symbol;
} nr_nfapi_pdsch_config_common_t;
typedef struct {
} nr_nfapi_rach_config_common_t;
typedef struct {
} nr_nfapi_pusch_config_common_t;
typedef struct {
uint8_t scs_common;
uint8_t ssb_subcarrier_offset;
uint8_t dmrs_type_a_position;
uint8_t pdcch_config_sib1;
uint8_t cell_barred;
uint8_t intra_frquency_reselection;
} nr_nfapi_pbch_config_t;
typedef struct {
nr_nfapi_tl_t tl;
nr_nfapi_pbch_config_t pbch_config_common; //MIB
nr_nfapi_pdcch_config_common_t pdcch_config_common;
nr_nfapi_pdsch_config_common_t pdsch_config_common;
nr_nfapi_rach_config_common_t rach_config_common;
nr_nfapi_pusch_config_common_t pusch_config_common;
} nr_nfapi_dl_config_dci_dl_pdu;
typedef struct {
uint8_t pdu_type;
uint8_t pdu_size;
union {
/*nr_nfapi_dl_config_dlsch_pdu dlsch_pdu;
nr_nfapi_dl_config_prs_pdu prs_pdu;
nr_nfapi_dl_config_csi_rs_pdu csi_rs_pdu;*/
};
} nr_nfapi_dl_config_request_pdu_t;
///
typedef struct {
nr_nfapi_p7_message_header_t header;
uint16_t sfn_sf_slot;
nr_nfapi_dl_config_request_pdu_t dl_config_request_body;
} nr_nfapi_dl_config_request_t;
//
// P5
//
typedef struct {
nr_nfapi_p4_p5_message_header_t header;
uint8_t num_tlv;
nr_nfapi_dl_config_dci_dl_pdu dci_dl_pdu;
} nr_nfapi_config_request_t;
#endif /* _NFAPI_INTERFACE_H_ */
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file fapi_l1.c
* \brief functions for FAPI L1 interface
* \author R. Knopp
* \date 2017
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "SCHED/sched_eNB.h"
#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);
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req);
extern uint8_t nfapi_mode;
void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,
int frame, int subframe,
eNB_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu)
{
int idx = subframe&1;
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[idx];
nfapi_dl_config_dci_dl_pdu *pdu = &dl_config_pdu->dci_dl_pdu;
LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,subframe, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci);
// copy dci configuration into eNB structure
fill_dci_and_dlsch(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],pdu);
LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci);
}
#ifdef Rel14
void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu)
{
int idx = proc->subframe_tx&1;
LTE_eNB_MPDCCH *mpdcch_vars = &eNB->mpdcch_vars[idx];
nfapi_dl_config_mpdcch_pdu *pdu = &dl_config_pdu->mpdcch_pdu;
LOG_D(PHY,"Frame %d, Subframe %d: MDCI processing\n",proc->frame_tx,proc->subframe_tx);
// copy dci configuration into eNB structure
fill_mdci_and_dlsch(eNB,proc,&mpdcch_vars->mdci_alloc[mpdcch_vars->num_dci],pdu);
}
#endif
void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu)
{
int idx = subframe&1;
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[idx];
//LOG_D(PHY,"%s() SFN/SF:%04d%d Before num_dci:%d\n", __FUNCTION__,frame,subframe,pdcch_vars->num_dci);
// copy dci configuration in to eNB structure
fill_dci0(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu);
}
void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu)
{
LTE_eNB_PHICH *phich = &eNB->phich_vars[subframe&1];
// copy dci configuration in to eNB structure
LOG_D(PHY,"Received HI PDU with value %d (rbstart %d,cshift %d)\n",
hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value,
hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start,
hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms);
// DJP - TODO FIXME - transmission power ignored
phich->config[phich->num_hi].hi = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value;
phich->config[phich->num_hi].first_rb = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start;
phich->config[phich->num_hi].n_DMRS = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms;
phich->num_hi++;
AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n");
}
void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t *sdu)
{
nfapi_dl_config_bch_pdu_rel8_t *rel8 = &dl_config_pdu->bch_pdu.bch_pdu_rel8;
AssertFatal(rel8->length == 3, "BCH PDU has length %d != 3\n",rel8->length);
//LOG_D(PHY,"bch_pdu: %x,%x,%x\n",sdu[0],sdu[1],sdu[2]);
eNB->pbch_pdu[0] = sdu[2];
eNB->pbch_pdu[1] = sdu[1];
eNB->pbch_pdu[2] = sdu[0];
// adjust transmit amplitude here based on NFAPI info
}
#ifdef Rel14
extern uint32_t localRIV2alloc_LUT6[32];
extern uint32_t localRIV2alloc_LUT25[512];
extern uint32_t localRIV2alloc_LUT50_0[1600];
extern uint32_t localRIV2alloc_LUT50_1[1600];
extern uint32_t localRIV2alloc_LUT100_0[6000];
extern uint32_t localRIV2alloc_LUT100_1[6000];
extern uint32_t localRIV2alloc_LUT100_2[6000];
extern uint32_t localRIV2alloc_LUT100_3[6000];
#endif
void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t codeword_index,
uint8_t *sdu)
{
nfapi_dl_config_dlsch_pdu_rel8_t *rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8;
#ifndef Rel8
nfapi_dl_config_dlsch_pdu_rel10_t *rel10 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10;
#endif
#ifdef Rel14
nfapi_dl_config_dlsch_pdu_rel13_t *rel13 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13;
#endif
LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
int UE_id;
int harq_pid;
UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
dlsch0 = eNB->dlsch[UE_id][0];
dlsch1 = eNB->dlsch[UE_id][1];
#ifdef Rel14
if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[subframe] = 0;
#endif
harq_pid = dlsch0->harq_ids[subframe];
AssertFatal((harq_pid>=0) && (harq_pid<8),"harq_pid %d not in 0...7 frame:%d subframe:%d subframe(TX):%d rnti:%x UE_id:%d dlsch0[harq_ids:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d]\n",
harq_pid,
frame,subframe,
proc->subframe_tx,rel8->rnti,UE_id,
dlsch0->harq_ids[0],
dlsch0->harq_ids[1],
dlsch0->harq_ids[2],
dlsch0->harq_ids[3],
dlsch0->harq_ids[4],
dlsch0->harq_ids[5],
dlsch0->harq_ids[6],
dlsch0->harq_ids[7],
dlsch0->harq_ids[8],
dlsch0->harq_ids[9]
);
dlsch0_harq = dlsch0->harq_processes[harq_pid];
dlsch1_harq = dlsch1->harq_processes[harq_pid];
AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n");
// compute DL power control parameters
eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa;
if (dlsch0->active){
computeRhoA_eNB(rel8->pa, dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off);
}
if (dlsch1->active){
computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off);
}
dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols;
if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU
AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n",
frame,subframe,
proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start);
if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n",
frame,subframe,proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid);
if (codeword_index == 0) dlsch0_harq->pdu = sdu;
else dlsch1_harq->pdu = sdu;
}
else {
if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round %d, rnti %x, UE_id %d, harq_pid %d\n",
frame,subframe,proc->frame_tx,proc->subframe_tx,dlsch0_harq->round,
rel8->rnti,UE_id,harq_pid);
}
#ifdef Rel14
dlsch0->sib1_br_flag=0;
if ((rel13->pdsch_payload_type <2) && (rel13->ue_type>0)) { // this is a BR/CE UE and SIB1-BR/SI-BR
dlsch0->rnti = 0xFFFF;
dlsch0->Kmimo = 1;
dlsch0->Mdlharq = 4;
dlsch0->Nsoft = 25344;
if (rel13->pdsch_payload_type == 0) dlsch0->sib1_br_flag=1;
// configure PDSCH
switch (eNB->frame_parms.N_RB_DL) {
case 6:
dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rel8->resource_block_coding];
break;
case 15:
AssertFatal(1==0,"15 PRBs not supported for now\n");
break;
case 25:
dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rel8->resource_block_coding];
break;
case 50:
dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rel8->resource_block_coding];
dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rel8->resource_block_coding];
break;
case 75:
AssertFatal(1==0,"75 PRBs not supported for now\n");
break;
case 100:
dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rel8->resource_block_coding];
dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rel8->resource_block_coding];
dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rel8->resource_block_coding];
dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rel8->resource_block_coding];
}
dlsch0->active = 1;
dlsch0_harq->nb_rb = 6;
dlsch0_harq->vrb_type = LOCALIZED;
dlsch0_harq->rvidx = rel8->redundancy_version;
dlsch0_harq->Nl = 1;
dlsch0_harq->mimo_mode = (eNB->frame_parms.nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI;
dlsch0_harq->dl_power_off = 1;
dlsch0_harq->round = 0;
dlsch0_harq->status = ACTIVE;
dlsch0_harq->TBS = rel8->length<<3;
dlsch0_harq->Qm = rel8->modulation;
dlsch0_harq->codeword = 0;
dlsch0_harq->pdsch_start = rel10->pdsch_start;
}
dlsch0->i0 = rel13->initial_transmission_sf_io;
#endif
#ifdef Rel14
LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n",
dlsch0->i0,
dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0],
rel8->length
);
#else
LOG_D(PHY,"dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n",
dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0],
rel8->length
);
#endif
}
uint16_t to_beta_offset_harqack[16]={16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8};
void handle_ulsch_harq_pdu(
PHY_VARS_eNB *eNB,
int UE_id,
nfapi_ul_config_request_pdu_t *ul_config_pdu,
nfapi_ul_config_ulsch_harq_information *harq_information,
uint16_t frame,
uint8_t subframe)
{
nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8;
LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq;
int harq_pid = rel8->harq_process_number;
ulsch_harq = ulsch->harq_processes[harq_pid];
ulsch_harq->frame = frame;
ulsch_harq->subframe = subframe;
ulsch_harq->O_ACK = harq_information->harq_information_rel10.harq_size;
ulsch->beta_offset_harqack_times8 = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq];
}
uint16_t to_beta_offset_ri[16]={9,13,16,20,25,32,40,50,64,80,101,127,160,0,0,0};
uint16_t to_beta_offset_cqi[16]={0,0,9,10,11,13,14,16,18,20,23,25,28,32,40,50};
void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe)
{
nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9;
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number;
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
ulsch_harq->frame = frame;
ulsch_harq->subframe = subframe;
ulsch_harq->O_RI = rel9->aperiodic_cqi_pmi_ri_report.cc[0].ri_size;
ulsch_harq->Or1 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0];
if (ulsch_harq->O_RI>1) ulsch_harq->Or2 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[1];
ulsch->beta_offset_ri_times8 = to_beta_offset_ri[rel9->delta_offset_ri];
ulsch->beta_offset_cqi_times8 = to_beta_offset_cqi[rel9->delta_offset_cqi];
LOG_D(PHY,"Filling ulsch_cqi_ri information for frame %d, subframe %d : O_RI %d, Or1 %d, beta_offset_cqi_times8 %d (%d)\n",
frame,subframe,ulsch_harq->O_RI,ulsch_harq->Or1,ulsch->beta_offset_cqi_times8,
rel9->delta_offset_cqi);
}
void handle_ulsch_cqi_harq_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe)
{
nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information.cqi_ri_information_rel9;
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number;
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
nfapi_ul_config_ulsch_harq_information *harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information;
ulsch_harq->frame = frame;
ulsch_harq->subframe = subframe;
ulsch_harq->O_RI = rel9->aperiodic_cqi_pmi_ri_report.cc[0].ri_size;
ulsch_harq->Or1 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0];
ulsch_harq->O_ACK = harq_information->harq_information_rel10.harq_size;
if (ulsch_harq->O_RI>1) ulsch_harq->Or2 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[1];
ulsch->beta_offset_harqack_times8 = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq];
ulsch->beta_offset_ri_times8 = to_beta_offset_ri[rel9->delta_offset_ri];
ulsch->beta_offset_cqi_times8 = to_beta_offset_cqi[rel9->delta_offset_cqi];
}
void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_config_harq_information *harq_information)
{
if (eNB->frame_parms.frame_type == FDD) {
uci->num_pucch_resources = harq_information->harq_information_rel9_fdd.number_of_pucch_resources;
LOG_D(PHY,"Programming UCI HARQ mode %d : size %d in (%d,%d)\n",
harq_information->harq_information_rel9_fdd.ack_nack_mode,
harq_information->harq_information_rel9_fdd.harq_size,
uci->frame,uci->subframe);
if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
(harq_information->harq_information_rel9_fdd.harq_size == 1)) {
uci->pucch_fmt = pucch_format1a;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
}
else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
(harq_information->harq_information_rel9_fdd.harq_size == 2)) {
uci->pucch_fmt = pucch_format1b;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
}
else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) &&
(harq_information->harq_information_rel9_fdd.harq_size == 2)) {
uci->pucch_fmt = pucch_format1b_csA2;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1;
uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
}
else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) &&
(harq_information->harq_information_rel9_fdd.harq_size == 3)) {
uci->pucch_fmt = pucch_format1b_csA3;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1;
uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2;
uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2;
}
else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) &&
(harq_information->harq_information_rel9_fdd.harq_size == 4)) {
uci->pucch_fmt = pucch_format1b_csA4;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1;
uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2;
uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2;
}
else if (harq_information->harq_information_rel9_fdd.ack_nack_mode == 2) {
uci->pucch_fmt = pucch_format3;
uci->n_pucch_3[0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0;
}
else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel9_fdd.ack_nack_mode);
}
else { // TDD
uci->num_pucch_resources = harq_information->harq_information_rel10_tdd.number_of_pucch_resources;
if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) {//bundling
uci->pucch_fmt = harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b;
uci->tdd_bundling = 1;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
}
else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing
(uci->num_pucch_resources == 1)) {
uci->pucch_fmt = harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b;
uci->tdd_bundling = 0;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
}
else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing M>1
(uci->num_pucch_resources > 1)) {
uci->pucch_fmt = pucch_format1b;
uci->tdd_bundling = 0;
uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
uci->n_pucch_1[1][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_1;
uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
uci->n_pucch_1[2][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_2;
uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2;
uci->n_pucch_1[3][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_3;
uci->n_pucch_1[3][1] = harq_information->harq_information_rel11.n_pucch_2_3;
}
else if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 2) {
uci->pucch_fmt = pucch_format3;
uci->n_pucch_3[0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0;
}
else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel10_tdd.ack_nack_mode);
}
}
void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active)
{
LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
uci->frame = frame;
uci->subframe = subframe;
uci->rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
uci->type = SR;
uci->pucch_fmt = pucch_format1;
uci->num_antenna_ports = 1;
uci->num_pucch_resources = 1;
uci->n_pucch_1_0_sr[0] = ul_config_pdu->uci_sr_pdu.sr_information.sr_information_rel8.pucch_index;
uci->srs_active = srs_active;
uci->active = 1;
LOG_D(PHY,"Programming UCI SR rnti %x, pucch1_0 %d for (%d,%d)\n",
uci->rnti,uci->n_pucch_1_0_sr[0],frame,subframe);
}
void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active)
{
LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
uci->frame = frame;
uci->subframe = subframe;
uci->rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
uci->type = HARQ_SR;
uci->num_antenna_ports = 1;
uci->num_pucch_resources = 1;
uci->n_pucch_1_0_sr[0] = ul_config_pdu->uci_sr_harq_pdu.sr_information.sr_information_rel8.pucch_index;
uci->srs_active = srs_active;
uci->active = 1;
handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_sr_harq_pdu.harq_information);
}
void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active)
{
LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
LOG_D(PHY,"Frame %d, Subframe %d: Programming UCI_HARQ process (type %d)\n",frame,subframe,HARQ);
uci->frame = frame;
uci->subframe = subframe;
uci->rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
uci->type = HARQ;
uci->srs_active = srs_active;
uci->num_antenna_ports = ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel11.num_ant_ports;
handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_harq_pdu.harq_information);
uci->active=1;
}
void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe)
{
int i;
for (i=0;i<NUMBER_OF_UE_MAX;i++) {
if (eNB->soundingrs_ul_config_dedicated[i].active==1) continue;
eNB->soundingrs_ul_config_dedicated[i].active = 1;
eNB->soundingrs_ul_config_dedicated[i].frame = frame;
eNB->soundingrs_ul_config_dedicated[i].subframe = subframe;
eNB->soundingrs_ul_config_dedicated[i].rnti = ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti;
eNB->soundingrs_ul_config_dedicated[i].srs_Bandwidth = ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth;
eNB->soundingrs_ul_config_dedicated[i].srs_HoppingBandwidth = ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth;
eNB->soundingrs_ul_config_dedicated[i].freqDomainPosition = ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position;
eNB->soundingrs_ul_config_dedicated[i].transmissionComb = ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb;
eNB->soundingrs_ul_config_dedicated[i].srs_ConfigIndex = ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs;
eNB->soundingrs_ul_config_dedicated[i].cyclicShift = ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift;
break;
}
AssertFatal(i<NUMBER_OF_UE_MAX,"No room for SRS processing\n");
}
void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
nfapi_ul_config_request_pdu_t *ul_config_pdu,
uint16_t frame,uint8_t subframe,uint8_t srs_present)
{
nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8;
int8_t UE_id;
// check if we have received a dci for this ue and ulsch descriptor is configured
if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) {
AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
"No existing UE ULSCH for rnti %x\n",rel8->rnti);
LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d, modulation %d, rvidx %d\n", UE_id,rel8->rnti,frame,subframe,rel8->modulation_type,rel8->redundancy_version);
fill_ulsch(eNB,&ul_config_pdu->ulsch_pdu,frame,subframe);
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) {
AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
"No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
fill_ulsch(eNB,&ul_config_pdu->ulsch_harq_pdu.ulsch_pdu,frame,subframe);
handle_ulsch_harq_pdu(eNB, UE_id, ul_config_pdu,
&ul_config_pdu->ulsch_harq_pdu.harq_information, frame, subframe);
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) {
AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
eNB,SEARCH_EXIST_OR_FREE))>=0,
"No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu,frame,subframe);
handle_ulsch_cqi_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe);
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) {
AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
eNB,SEARCH_EXIST_OR_FREE))>=0,
"No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu,frame,subframe);
handle_ulsch_cqi_harq_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe);
handle_ulsch_harq_pdu(eNB, UE_id, ul_config_pdu,
&ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information, frame, subframe);
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
AssertFatal((UE_id = find_uci(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,
proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
"No available UE UCI for rnti %x\n",ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti);
handle_uci_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present);
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) {
AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n");
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) {
AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n");
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) {
AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n");
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
AssertFatal((UE_id = find_uci(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,
proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
"No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti);
handle_uci_sr_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present);
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) {
AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
"No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti);
handle_uci_sr_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present);
}
else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_SRS_PDU_TYPE) {
handle_srs_pdu(eNB,ul_config_pdu,frame,subframe);
}
}
void TX_request(){
}
void DL_config(){
}
void UL_config(){
}
void CONFIG_request(){
}
void schedule_response(Sched_Rsp_t *Sched_INFO)
{
PHY_VARS_eNB *eNB;
eNB_rxtx_proc_t *proc;
// copy data from L2 interface into L1 structures
module_id_t Mod_id = Sched_INFO->module_id;
uint8_t CC_id = Sched_INFO->CC_id;
nfapi_dl_config_request_t *DL_req = Sched_INFO->DL_req;
nfapi_hi_dci0_request_t *HI_DCI0_req = Sched_INFO->HI_DCI0_req;
nfapi_ul_config_request_t *UL_req = Sched_INFO->UL_req;
nfapi_tx_request_t *TX_req = Sched_INFO->TX_req;
frame_t frame = Sched_INFO->frame;
sub_frame_t subframe = Sched_INFO->subframe;
LTE_DL_FRAME_PARMS *fp;
uint8_t ul_subframe;
int ul_frame;
int harq_pid;
LTE_UL_eNB_HARQ_t *ulsch_harq;
AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n");
AssertFatal(RC.eNB[Mod_id]!=NULL,"RC.eNB[%d] is null\n",Mod_id);
AssertFatal(RC.eNB[Mod_id][CC_id]!=NULL,"RC.eNB[%d][%d] is null\n",Mod_id,CC_id);
eNB = RC.eNB[Mod_id][CC_id];
fp = &eNB->frame_parms;
proc = &eNB->proc.proc_rxtx[0];
/* TODO: check that following line is correct - in the meantime it is disabled */
//if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return;
ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe);
// 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_pdcch_ofdm_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols;
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;
uint8_t number_ul_pdu = UL_req!=NULL ? UL_req->ul_config_request_body.number_of_pdus : 0;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu;
nfapi_ul_config_request_pdu_t *ul_config_pdu;
int i;
eNB->pdcch_vars[subframe&1].num_pdcch_symbols = number_pdcch_ofdm_symbols;
eNB->pdcch_vars[subframe&1].num_dci = 0;
eNB->phich_vars[subframe&1].num_hi = 0;
LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d hi_dci0:SFN/SF:%04d%d:pdus:%d ul_cfg:SFN/SF:%04d%d:pdus:%d num_pdcch_symbols:%d\n",
frame,subframe,
NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu,
NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus,
NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),number_hi_dci0_pdu,
NFAPI_SFNSF2SFN(UL_req->sfn_sf),NFAPI_SFNSF2SF(UL_req->sfn_sf),number_ul_pdu,
eNB->pdcch_vars[subframe&1].num_pdcch_symbols);
int do_oai =0;
int dont_send =0;
/* TODO: check the following test - in the meantime it is put back as it was before */
//if ((ul_subframe<10)&&
// (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is an ul_subframe that can be configured here
if (ul_subframe<10) { // This means that there is an ul_subframe that can be configured here
LOG_D(PHY,"NFAPI: Clearing dci allocations for potential UL subframe %d\n",ul_subframe);
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
// clear DCI allocation maps for new subframe
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
if (eNB->ulsch[i]) {
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
ulsch_harq->dci_alloc=0;
ulsch_harq->rar_alloc=0;
}
}
}
for (i=0;i<number_dl_pdu;i++) {
dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i];
//LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type);
switch (dl_config_pdu->pdu_type) {
case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu);
eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++;
//LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_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,
"bch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n",
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;
case NFAPI_DL_CONFIG_MCH_PDU_TYPE:
// handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu);
break;
case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE:
{
nfapi_dl_config_dlsch_pdu_rel8_t *dlsch_pdu_rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8;
uint16_t pdu_index = dlsch_pdu_rel8->pdu_index;
uint16_t tx_pdus = TX_req->tx_request_body.number_of_pdus;
uint16_t invalid_pdu = pdu_index == -1;
uint8_t *sdu = invalid_pdu ? NULL : pdu_index >= tx_pdus ? NULL : TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data;
LOG_D(PHY,"%s() [PDU:%d] NFAPI_DL_CONFIG_DLSCH_PDU_TYPE SFN/SF:%04d%d TX:%d/%d RX:%d/%d transport_blocks:%d pdu_index:%d sdu:%p\n",
__FUNCTION__, i,
NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),
proc->frame_tx, proc->subframe_tx,
proc->frame_rx, proc->subframe_rx,
dlsch_pdu_rel8->transport_blocks, pdu_index, sdu);
/*
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,
TX_req->tx_request_body.number_of_pdus);
*/
AssertFatal((dlsch_pdu_rel8->transport_blocks<3) &&
(dlsch_pdu_rel8->transport_blocks>0),
"dlsch_pdu_rel8->transport_blocks = %d not in [1,2]\n",
dlsch_pdu_rel8->transport_blocks);
if (1)//sdu != NULL)
{
handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu);
}
else
{
dont_send=1;
LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index, NFAPI_SFNSF2DEC(TX_req->sfn_sf), tx_pdus);
}
// 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;
/*
if (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == eNB->preamble_list[0].preamble_rel8.rnti) {// is RAR pdu
LOG_D(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n",frame,subframe);
generate_eNB_ulsch_params_from_rar(eNB,
TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
frame,
subframe);
} */
}
break;
case NFAPI_DL_CONFIG_PCH_PDU_TYPE:
// handle_nfapi_pch_pdu(eNB,dl_config_pdu);
break;
case NFAPI_DL_CONFIG_PRS_PDU_TYPE:
// handle_nfapi_prs_pdu(eNB,dl_config_pdu);
break;
case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE:
// handle_nfapi_csi_rs_pdu(eNB,dl_config_pdu);
break;
case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE:
// handle_nfapi_epdcch_pdu(eNB,dl_config_pdu);
break;
#ifdef Rel14
case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE:
#ifdef Rel14
handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu);
eNB->mpdcch_vars[subframe&1].num_dci++;
#endif
break;
#endif
}
}
if (nfapi_mode && do_oai && !dont_send) {
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
}
if (nfapi_mode && number_hi_dci0_pdu!=0) {
oai_nfapi_hi_dci0_req(HI_DCI0_req);
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci=0;
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_pdcch_symbols=0;
}
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];
LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type);
switch (hi_dci0_req_pdu->pdu_type) {
case NFAPI_HI_DCI0_DCI_PDU_TYPE:
handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++;
break;
case NFAPI_HI_DCI0_HI_PDU_TYPE:
handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
break;
}
}
if (nfapi_mode) {
if (number_ul_pdu>0)
{
//LOG_D(PHY, "UL_CONFIG to send to PNF\n");
oai_nfapi_ul_config_req(UL_req);
UL_req->ul_config_request_body.number_of_pdus=0;
number_ul_pdu=0;
}
}
else {
for (i=0;i<number_ul_pdu;i++) {
ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i];
LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type);
AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE ||
ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE ||
ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE ||
ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE ||
ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE ||
ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE ||
ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE
,
"Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type);
handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu,UL_req->sfn_sf>>4,UL_req->sfn_sf&0xf,UL_req->ul_config_request_body.srs_present);
}
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file fapi_l1.h
* \brief function prototypes for FAPI L1 interface
* \author R. Knopp
* \date 2017
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs_eNB.h"
#include "PHY/phy_extern.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "SCHED/sched_eNB.h"
#include "SCHED/sched_common.h"
#include "nfapi_interface.h"
void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask);
void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling);
void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti);
void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat);
void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe);
void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag);
void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t codeword_index,
uint8_t *sdu);
void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
nfapi_ul_config_request_pdu_t *ul_config_pdu,
uint16_t frame,uint8_t subframe,uint8_t srs_present);
void handle_ulsch_harq_pdu(
PHY_VARS_eNB *eNB,
int UE_id,
nfapi_ul_config_request_pdu_t *ul_config_pdu,
nfapi_ul_config_ulsch_harq_information *harq_information,
uint16_t frame,
uint8_t subframe);
void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_config_harq_information *harq_information);
void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active);
void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active);
void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active);
void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
void schedule_response(Sched_Rsp_t *Sched_INFO);
......@@ -527,6 +527,16 @@ static void dump_dl(Sched_Rsp_t *d)
/* debug utility functions end */
/****************************************************************************/
void DCI_indication(nr_nfapi_dci_indication_t dci_indication){
}
void RX_request(){
}
void UL_indication(UL_IND_t *UL_info)
{
......
......@@ -61,36 +61,35 @@ typedef struct{
sub_frame_t subframe;
/// harq indication list
nfapi_harq_indication_t harq_ind;
//nfapi_harq_indication_t harq_ind;
/// crc indication list
nfapi_crc_indication_t crc_ind;
//nfapi_crc_indication_t crc_ind;
/// SR indication list
nfapi_sr_indication_t sr_ind;
//nfapi_sr_indication_t sr_ind;
/// CQI indication list
nfapi_cqi_indication_body_t cqi_ind;
//nfapi_cqi_indication_body_t cqi_ind;
/// RACH indication list
nfapi_rach_indication_t rach_ind;
//nfapi_rach_indication_t rach_ind;
#ifdef Rel14
/// RACH indication list for BR UEs
nfapi_rach_indication_t rach_ind_br;
#endif
/// SRS indication list
nfapi_srs_indication_body_t srs_ind;
//nfapi_srs_indication_body_t srs_ind;
/// RX indication
nfapi_rx_indication_t rx_ind;
//nfapi_rx_indication_t rx_ind;
} UL_IND_t;
// Downlink subframe P7
typedef struct{
/// Module ID
module_id_t module_id;
......
......@@ -35,6 +35,8 @@
#include <stdlib.h>
#include <string.h>
#include "rrc_list.h"
#include "collection/tree.h"
#include "rrc_types.h"
#include "PHY/defs.h"
......@@ -68,7 +70,6 @@
/* for ImsiMobileIdentity_t */
#include "MobileIdentity.h"
typedef struct NR_UE_RRC_INST_s {
nr_rrc_state_t rrc_state;
nr_rrc_sub_state_t rrc_sub_state;
......@@ -148,10 +149,61 @@ typedef struct NR_UE_RRC_INST_s {
e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
#endif
MeasConfig_t *meas_config;
CellGroupConfig_t *cell_group_config;
RadioBearerConfig_t *radio_bearer_config;
NR_MeasConfig_t *meas_config;
NR_CellGroupConfig_t *cell_group_config;
NR_RadioBearerConfig_t *radio_bearer_config;
// lists
// CellGroupConfig.rlc-BearerToAddModList
RRC_LIST_TYPE(NR_RLC_Bearer_Config_t, NR_maxLC_ID) RLC_Bearer_Config_list;
// CellGroupConfig.mac-CellGroupConfig.schedulingrequest
RRC_LIST_TYPE(NR_SchedulingRequestToAddMod_t, NR_maxNrofSR_ConfigPerCellGroup) SchedulingRequest_list;
// CellGroupConfig.mac-CellGroupConfig.TAG
RRC_LIST_TYPE(NR_TAG_ToAddMod_t, NR_maxNrofTAGs) TAG_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated.tdduldlslotconfig
RRC_LIST_TYPE(NR_TDD_UL_DL_SlotConfig_t, NR_maxNrofSlots) TDD_UL_DL_SlotConfig_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated.bwps
RRC_LIST_TYPE(NR_BWP_Downlink_t, NR_maxNrofBWPs) BWP_Downlink_list;
//BWP-DownlinkDedicated 0=INIT-DL-BWP, 1..4 for DL-BWPs
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdcchconfig.controlresourceset
RRC_LIST_TYPE(NR_ControlResourceSet_t, 3) ControlResourceSet_list[5];
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdcchconfig.searchspace
RRC_LIST_TYPE(NR_SearchSpace_t, 10) SearchSpace_list[5];
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdcchconfig.slotformatindicator
RRC_LIST_TYPE(NR_SlotFormatCombinationsPerCell_t, NR_maxNrofAggregatedCellsPerCellGroup) SlotFormatCombinationsPerCell_list[5];
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdschconfig
RRC_LIST_TYPE(NR_TCI_State_t, NR_maxNrofTCI_States) TCI_State_list[5];
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdschconfig
RRC_LIST_TYPE(NR_RateMatchPattern_t, NR_maxNrofRateMatchPatterns) RateMatchPattern_list[5];
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdschconfig
RRC_LIST_TYPE(NR_ZP_CSI_RS_Resource_t, NR_maxNrofZP_CSI_RS_Resources) ZP_CSI_RS_Resource_list[5];
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdschconfig
RRC_LIST_TYPE(NR_ZP_CSI_RS_ResourceSet_t, NR_maxNrofZP_CSI_RS_Sets) Aperidic_ZP_CSI_RS_ResourceSet_list[5];
// CellGroupConfig.spCellConfig.spCellConfigDedicated.initialdlbwp.pdschconfig
RRC_LIST_TYPE(NR_ZP_CSI_RS_ResourceSet_t, NR_maxNrofZP_CSI_RS_Sets) SP_ZP_CSI_RS_ResourceSet_list[5];
// TODO check the way to implement mutiple list inside bwps
// uplink bwp also
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_NZP_CSI_RS_Resource_t, NR_maxNrofNZP_CSI_RS_Resources) NZP_CSI_RS_Resource_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_NZP_CSI_RS_ResourceSet_t, NR_maxNrofNZP_CSI_RS_ResourceSets) NZP_CSI_RS_ResourceSet_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_CSI_IM_Resource_t, NR_maxNrofCSI_IM_Resources) CSI_IM_Resource_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_CSI_IM_ResourceSet_t, NR_maxNrofCSI_IM_ResourceSets) CSI_IM_ResourceSet_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_CSI_SSB_ResourceSet_t, NR_maxNrofCSI_SSB_ResourceSets) CSI_SSB_ResourceSet_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_CSI_ResourceConfig_t, NR_maxNrofCSI_ResourceConfigurations) CSI_ResourceConfig_list;
// CellGroupConfig.spCellConfig.spCellConfigDedicated
RRC_LIST_TYPE(NR_CSI_ReportConfig_t, NR_maxNrofCSI_ReportConfigurations) CSI_ReportConfig_list;
} NR_UE_RRC_INST_t;
#include "proto.h"
......
......@@ -31,7 +31,7 @@
#define RRC_UE
#define RRC_UE_C
#include "rrc_list.h"
// header files for RRC message for NR might be change to add prefix in from of the file name.
#include "assertions.h"
#include "hashtable.h"
......@@ -88,10 +88,10 @@ uint8_t nr_rrc_ue_decode_dcch(
){
// uper_decode by nr R15 rrc_connection_reconfiguration
NR_RRC_DL_DCCH_Message_t *nr_dl_dcch_msg = (NR_RRC_DL_DCCH_Message_t *)0;
NR_DL_DCCH_Message_t *nr_dl_dcch_msg = (NR_DL_DCCH_Message_t *)0;
uper_decode(NULL,
&asn_DEF_NR_RRC_DL_DCCH_Message, //might be added prefix later
&asn_DEF_NR_DL_DCCH_Message,
(void**)&nr_dl_dcch_msg,
(uint8_t *)buffer,
size, 0, 0);
......@@ -148,7 +148,7 @@ uint8_t nr_rrc_ue_decode_secondary_cellgroup_config(
const uint8_t *buffer,
const uint32_t size
){
CellGroupConfig_t *cellGroupConfig = (CellGroupConfig_t *)0;
NR_CellGroupConfig_t *cellGroupConfig = (NR_CellGroupConfig_t *)0;
uper_decode(NULL,
&asn_DEF_CellGroupConfig, //might be added prefix later
......@@ -156,7 +156,7 @@ uint8_t nr_rrc_ue_decode_secondary_cellgroup_config(
(uint8_t *)buffer,
size, 0, 0);
if(NR_UE_rrc_inst->cell_group_config == (CellGroupConfig_t *)0){
if(NR_UE_rrc_inst->cell_group_config == (NR_CellGroupConfig_t *)0){
NR_UE_rrc_inst->cell_group_config = cellGroupConfig;
nr_rrc_ue_process_scg_config(cellGroupConfig);
}else{
......@@ -170,12 +170,12 @@ uint8_t nr_rrc_ue_decode_secondary_cellgroup_config(
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded)
// RRCReconfiguration
uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfiguration){
uint8_t nr_rrc_ue_process_rrcReconfiguration(NR_RRCReconfiguration_t *rrcReconfiguration){
switch(rrcReconfiguration.criticalExtensions.present){
case RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration:
if(rrcReconfiguration.criticalExtensions.rrcReconfiguration->radioBearerConfig != (RadioBearerConfig_t *)0){
if(NR_UE_rrc_inst->radio_bearer_config == (RadioBearerConfig_t *)0){
if(rrcReconfiguration.criticalExtensions.rrcReconfiguration->radioBearerConfig != (NR_RadioBearerConfig_t *)0){
if(NR_UE_rrc_inst->radio_bearer_config == (NR_RadioBearerConfig_t *)0){
NR_UE_rrc_inst->radio_bearer_config = rrcReconfiguration->radioBearerConfig;
}else{
nr_rrc_ue_process_radio_bearer_config(rrcReconfiguration->radioBearerConfig);
......@@ -183,14 +183,14 @@ uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfigur
}
if(rrcReconfiguration.criticalExtensions.rrcReconfiguration->secondaryCellGroup != (OCTET_STRING_t *)0){
CellGroupConfig_t *cellGroupConfig = (CellGroupConfig_t *)0;
NR_CellGroupConfig_t *cellGroupConfig = (NR_CellGroupConfig_t *)0;
uper_decode(NULL,
&asn_DEF_CellGroupConfig, //might be added prefix later
(void **)&cellGroupConfig,
(uint8_t *)rrcReconfiguration->secondaryCellGroup->buffer,
rrcReconfiguration->secondaryCellGroup.size, 0, 0);
if(NR_UE_rrc_inst->cell_group_config == (CellGroupConfig_t *)0){
if(NR_UE_rrc_inst->cell_group_config == (NR_CellGroupConfig_t *)0){
// first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time.
NR_UE_rrc_inst->cell_group_config = cellGroupConfig;
nr_rrc_ue_process_scg_config(cellGroupConfig);
......@@ -203,7 +203,7 @@ uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfigur
}
if(rrcReconfiguration.criticalExtensions.rrcReconfiguration->measConfig != (MeasConfig *)0){
if(NR_UE_rrc_inst->meas_config == (MeasConfig_t *)0){
if(NR_UE_rrc_inst->meas_config == (NR_MeasConfig_t *)0){
NR_UE_rrc_inst->meas_config = rrcReconfiguration->measConfig;
}else{
// if some element need to be updated
......@@ -228,14 +228,53 @@ uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfigur
nr_rrc_mac_config_req_ue();
}
uint8_t nr_rrc_ue_process_meas_config(MeasConfig_t *meas_config){
uint8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){
}
uint8_t nr_rrc_ue_process_scg_config(CellGroupConfig_t *cell_group_config){
uint8_t nr_rrc_ue_process_scg_config(NR_CellGroupConfig_t *cell_group_config){
int i;
void *listobj;
if(NR_UE_rrc_inst->cell_group_config==NULL){
// initial list
if(cell_group_config->spCellConfig != NULL){
if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){
if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){
listobj = cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
for(i=0; i<((struct NR_ServingCellConfig__downlinkBWP_ToAddModList)listobj)->list.count; ++i){
RRC_LIST_MOD_ADD(NR_UE_rrc_inst.BWP_Downlink_list, ((struct NR_ServingCellConfig__downlinkBWP_ToAddModList)listobj)->list.array[i]);
}
}
}
}
}else{
// maintain list
if(cell_group_config->spCellConfig != NULL){
if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){
// process element of list to be add by RRC message
if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){
listobj = cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
for(i=0; i<((struct NR_ServingCellConfig__downlinkBWP_ToAddModList)listobj)->list.count; ++i){
RRC_LIST_MOD_ADD(NR_UE_rrc_inst.BWP_Downlink_list, ((struct NR_ServingCellConfig__downlinkBWP_ToAddModList)listobj)->list.array[i]);
}
}
// process element of list to be release by RRC message
if(cell_group_config->spCellConfig->spCellconfigDedicated->downlinkBWP_ToReleaseList != NULL){
listobj = cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList;
for(i=0; i<((struct NR_ServingCellconfig__downlinkBWP_ToReleaseList)listobj)->list.count; ++i){
RRC_LIST_MOD_REL(NR_UE_rrc_inst.BWP_Downlink_list, ((struct NR_ServingCellConfig__downlinkBWP_ToReleaseList)listlbj)->list.array[i]);
}
}
}
}
}
}
uint8_t nr_rrc_ue_process_radio_bearer_config(RadioBearerConfig_t *radio_bearer_config){
uint8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_bearer_config){
}
......@@ -248,29 +287,53 @@ uint8_t openair_rrc_top_init_ue_nr(void){
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
// init RRC lists
RRC_LIST_INIT(NR_UE_rrc_inst->RLC_Bearer_Config_list, NR_maxLC_ID);
RRC_LIST_INIT(NR_UE_rrc_inst->SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup);
RRC_LIST_INIT(NR_UE_rrc_inst->TAG_list, NR_maxNrofTAGs);
RRC_LIST_INIT(NR_UE_rrc_inst->TDD_UL_DL_SlotConfig_list, NR_maxNrofSlots);
RRC_LIST_INIT(NR_UE_rrc_inst->BWP_Downlink_list, NR_maxNrofBWPs);
RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[0], 3); // for init-dl-bwp
RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[1], 3); // for dl-bwp id=0
RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[2], 3); // for dl-bwp id=1
RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[3], 3); // for dl-bwp id=2
RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[4], 3); // for dl-bwp id=3
RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list, 10);
RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list, NR_maxNrofAggregatedCellsPerCellGroup);
RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list, NR_maxNrofTCI_States);
RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list, NR_maxNrofRateMatchPatterns);
RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list, NR_maxNrofZP_CSI_RS_Resources);
RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list, NR_maxNrofZP_CSI_RS_Sets);
RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list, NR_maxNrofZP_CSI_RS_Sets);
RRC_LIST_INIT(NR_UE_rrc_inst->NZP_CSI_RS_Resource_list, NR_maxNrofNZP_CSI_RS_Resources);
RRC_LIST_INIT(NR_UE_rrc_inst->NZP_CSI_RS_ResourceSet_list, NR_maxNrofNZP_CSI_RS_ResourceSets);
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_IM_Resource_list, NR_maxNrofCSI_IM_Resources);
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_IM_ResourceSet_list, NR_maxNrofCSI_IM_ResourceSets);
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_SSB_ResourceSet_list, NR_maxNrofCSI_SSB_ResourceSets);
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations);
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
}else{
NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)0;
}
}
uint8_t nr_ue_process_rlc_bearer_list(CellGroupConfig_t *cell_group_config){
uint8_t nr_ue_process_rlc_bearer_list(NR_CellGroupConfig_t *cell_group_config){
};
uint8_t nr_ue_process_secondary_cell_list(CellGroupConfig_t *cell_group_config){
uint8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){
};
uint8_t nr_ue_process_mac_cell_group_config(MAC_CellGroupConfig_t *mac_cell_group_config){
uint8_t nr_ue_process_mac_cell_group_config(NR_MAC_CellGroupConfig_t *mac_cell_group_config){
};
uint8_t nr_ue_process_physical_cell_group_config(PhysicalCellGroupConfig_t *phy_cell_group_config){
uint8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *phy_cell_group_config){
};
uint8_t nr_ue_process_spcell_config(SpCellConfig_t *spcell_config){
uint8_t nr_ue_process_spcell_config(NR_SpCellConfig_t *spcell_config){
};
#define RRC_LIST_TYPE(T, N) \
struct { \
T *entries[N]; \
int next[N]; \
int prev[N]; \
int start; \
int count; \
}
// initial function for the certain list, storage number of entry, initial pointer and corresponding links
#define RRC_LIST_INIT(list, c) \
do { \
int iterator; \
(list).count = (c); \
for(iterator=0; iterator<c; ++iterator){ \
(list).entries[iterator] = NULL; \
(list).next[iterator] = -1; \
(list).prev[iterator] = -1; \
(list).start = -1; \
} \
}while(0)
// check the entry by id first then update or create new entry.
#define RRC_LIST_MOD_ADD(list, new, id_name) \
do { \
int iterator; \
for(iterator=(list).start; iterator!=-1; iterator=(list).next[iterator]){ \
if((new)->id_name == (list).entries[iterator]->id_name){ \
(list).entries[iterator] = (new); \
break; \
} \
} \
if(iterator==-1){ \
for(iterator=0; iterator<(list).count; ++iterator){ \
if((list).entries[iterator] == NULL){ \
(list).next[iterator] = (list).start; \
(list).prev[iterator] = -1; \
if((list).start != -1){ \
(list).prev[list.start] = iterator; \
} \
(list).start = iterator; \
(list).entries[iterator] = (new); \
break; \
} \
} \
} \
}while(0)
// search entries by id, unlink from the list and output free pointer for upper function to release memory
#define RRC_LIST_MOD_REL(list, id_name, id, free) \
do{ \
int iterator; \
for(iterator=(list).start; iterator!=-1; iterator=(list).next[iterator]){ \
if(id == (list).entries[iterator]->id_name){ \
if((list).prev[iterator] == -1){ \
(list).start = (list).next[iterator]; \
}else{ \
(list).next[(list).prev[iterator]] = (list).next[iterator]; \
} \
if((list).next[iterator] != -1){ \
(list).prev[(list).next[iterator]] = (list).prev[iterator]; \
} \
(free) = (list).entries[iterator]; \
(list).entries[iterator] = NULL; \
break; \
} \
} \
}while(0)
#define RRC_LIST_FOREACH(list, i) \
for((i)=(list).start; (i) != -1; (i)=(list).next[i])
#define RRC_LIST_ENTRY(list, i) \
list.entries[i]
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