Commit 4757a1b6 authored by matzakos's avatar matzakos

Added remaining fill_harq indication functions + the functionality to handle...

Added remaining fill_harq indication functions + the functionality to handle ul_config request pdus arriving from nfapi-vnf: trigger the appropriate UE_MAC and fill_indication functions to prepare the UL_indications which will be put into the socket for transfer back to vnf. Main changes within phy_stub_UE().
parent 6719eefb
/*
* 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 _DEBUG_H_
#define _DEBUG_H_
/*! The trace levels used by the nfapi libraries */
typedef enum nfapi_trace_level
{
NFAPI_TRACE_ERROR = 1,
NFAPI_TRACE_WARN,
NFAPI_TRACE_NOTE,
NFAPI_TRACE_INFO,
NFAPI_TRACE_LEVEL_MAX
} nfapi_trace_level_t;
/*! The trace function pointer */
typedef void (*nfapi_trace_fn_t)(nfapi_trace_level_t level, const char* format, ...);
/*! Global trace function */
extern nfapi_trace_fn_t nfapi_trace_g;
/*! Global trace level */
extern nfapi_trace_level_t nfapi_trace_level_g;
/*! NFAPI trace macro */
#define NFAPI_TRACE(level, format, ...) { if(nfapi_trace_g && ((nfapi_trace_level_t)level <= nfapi_trace_level_g)) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); }
/*! Function to change the trace level
* \param new_level The modified trace level
*/
void nfapi_set_trace_level(nfapi_trace_level_t new_level);
#endif /* _DEBUG_H_ */
/*
* 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_PNF_INTERFACE_H_
#define _NFAPI_PNF_INTERFACE_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include "nfapi_interface.h"
#include "debug.h"
#include <sys/types.h>
/*! This enum is used to describe the states of the pnf
*/
typedef enum
{
NFAPI_PNF_IDLE = 0,
NFAPI_PNF_CONFIGURED,
NFAPI_PNF_RUNNING
} nfapi_pnf_state_e;
/*! This enum is used to describe the states of a phy instance of a pnf
*/
typedef enum
{
NFAPI_PNF_PHY_IDLE = 0,
NFAPI_PNF_PHY_CONFIGURED = 1,
NFAPI_PNF_PHY_RUNNING = 2
} nfapi_pnf_phy_state_e;
typedef struct nfapi_pnf_phy_config nfapi_pnf_phy_config_t;
/*! Configuration information for a pnf phy instance
*/
typedef struct nfapi_pnf_phy_config
{
/*! The PHY id*/
uint16_t phy_id;
/*! The state of the PNF PHY instance*/
nfapi_pnf_phy_state_e state;
/*! Optional user defined data that will be passed back in the callbacks*/
void* user_data;
/*! Pointer for use in a linked list */
struct nfapi_pnf_phy_config* next;
} nfapi_pnf_phy_config_t;
typedef struct nfapi_pnf_config nfapi_pnf_config_t;
/*! Configuration information for the pnf created by calling nfapi_pnf_create
*/
typedef struct nfapi_pnf_config
{
/*! A user define callback to override the default memory allocation
* \param size The size of the data buffer to allocate
* \return A pointer to a data buffer
*/
void* (*malloc)(size_t size);
/*! A user define callback to override the default memory deallocation
* \param ptr Pointer to a data buffer to be deallocated
*/
void (*free)(void* ptr);
/*! A user define callback to handle trace from the pnf
* \param level The trace level
* \param message The trace string
*
* This is a vardic function.
*/
void (*trace)(nfapi_trace_level_t level, const char* message, ...);
/*! The ip address of the VNF
*
*/
char* vnf_ip_addr;
/*! The ip port of the VNF
*/
int vnf_p5_port;
/*! The state of the PNF */
nfapi_pnf_state_e state;
/*! List of PHY instances configured for this PNF */
nfapi_pnf_phy_config_t* phys;
/*! Configuation option of the p4 p5 encode decode functions */
nfapi_p4_p5_codec_config_t codec_config;
/*! Optional user defined data that will be passed back in the callbacks*/
void* user_data;
/*! A callback for the PNF_PARAM.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_PARAM.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_PARAM.response after receiving the
* PNF_PARAM.request. This can be done in the call back.
*/
int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req);
/*! A callback for the PNF_CONFIG.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_CONFIG.response after receiving the
* PNF_CONFIG.request. This can be done in the call back.
*/
int (*pnf_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req);
/*! A callback for the PNF_START.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_START.response after receiving the
* PNF_START.request. This can be done in the call back.
*/
int (*pnf_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req);
/*! A callback for the PNF_STOP.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_STOP.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_STOP.response after receiving the
* PNF_STOP.request. This can be done in the call back.
*/
int (*pnf_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req);
/*! A callback for the PARAM.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded PARAM.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PARAM.response after receiving the
* PARAM.request. This can be done in the call back.
*/
int (*param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req);
/*! A callback for the CONFIG.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded CONFIG.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the CONFIG.response after receiving the
* CONFIG.request. This can be done in the call back.
*/
int (*config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req);
/*! A callback for the START.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded START.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the START.response after the client has received the
* first subframe indication from FAPI.
*/
int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
/*! A callback for the STOP.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded STOP.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the STOP.response after receiving the
* STOP.request. This can be done in the call back.
*/
int (*stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req);
/*! A callback for the MEASUREMENT.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded MEASUREMENT.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the MEASUREMENT.response after receiving the
* MEASUREMENT.request. This can be done in the call back.
*/
int (*measurement_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req);
/*! A callback for the RSSI.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded RSSI.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the RSSI.response after receiving the
* RSSI.request. This can be done in the call back.
*/
int (*rssi_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req);
/*! A callback for the CELL_SEARCH.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded CELL_SEARCH.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the CELL_SEARCH.response after receiving the
* CELL_SEARCH.request. This can be done in the call back.
*/
int (*cell_search_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req);
/*! A callback for the BROADCAST_DETECT.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded BROADCAST_DETECT.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the BROADCAST_DETECT.response after receiving the
* BROADCAST_DETECT.request. This can be done in the call back.
*/
int (*broadcast_detect_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req);
/*! A callback for the SYSTEM_INFORMATION_SCHEDULE.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded SYSTEM_INFORMATION_SCHEDULE.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the SYSTEM_INFORMATION_SCHEDULE.response after receiving the
* SYSTEM_INFORMATION_SCHEDULE.request. This can be done in the call back.
*/
int (*system_information_schedule_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req);
/*! A callback for the SYSTEM_INFORMATION.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded SYSTEM_INFORMATION.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the SYSTEM_INFORMATION.response after receiving the
* SYSTEM_INFORMATION.request. This can be done in the call back.
*/
int (*system_information_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req);
/*! A callback for the NMM_STOP.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded NMM_STOP.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the NMM_STOP.response after receiving the
* NMM_STOP.request. This can be done in the call back.
*/
int (*nmm_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req);
/*! A callback for any vendor extension messages recevied
* \param config A pointer to the pnf configuration
* \param msg A pointer to the decode P4/P5 message
* \return not current used
*/
int (*vendor_ext)(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg);
/*! A callback to allocate vendor extension message
* \param message_id The message id from the decode P4/P5 message header
* \param msg_size A pointer a the size of the allocated message structure. The callee should set this
* \return A pointer to a allocated P4/P5 message structure
*/
nfapi_p4_p5_message_header_t* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
/*! A callback to deallocate vendor extension message
* \param header A pointer to an P4/P5 message structure
*/
void (*deallocate_p4_p5_vendor_ext)(nfapi_p4_p5_message_header_t* header);
} nfapi_pnf_config_t;
/*! Create a pnf configuration
* \return A pointer to a pnf configuration struture
*
* This function will create and initialize a pnf instance. It is expected that
* the client will set the callback and parameters need before calling nfapi_pnf_start
*
* 0 will be returned if it fails.
*
* \code
* nfapi_pnf_config_t* config = nfapi_pnf_config_create(void);
* \endcode
*/
nfapi_pnf_config_t* nfapi_pnf_config_create(void);
/*! Delete a pnf configuration
* \param config A pointer to a pnf configuraiton
* \return 0 is success, -1 for failure
*/
int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config);
/*! Start the PNF library.
* \param config A pointer to the pnf configuration
* \return 0 is success, -1 for failure
*
* This function will not return until nfapi_pnf_stop is called
*
* \code
* // Create the pnf config
* nfapi_pnf_config_t* config = nfapi_pnf_config_create(void);
*
* // Assumed that the vnf_address and vnf_port are provided over the P9 interface
* config->vnf_ip_addr = vnf_address;
* config->vnf_p5_port = vnf_port;
*
* // Set the required callbacks
* config->pnf_param_req = &pnf_param_request;
* ...
*
* // Call start for the PNF to initiate a connection to the VNF
* nfai_pnf_start(config);
*
* \endcode
*/
int nfapi_pnf_start(nfapi_pnf_config_t* config);
/*! Stop the PNF library.
* \param config A pointer to the pnf configuration
* \return 0 is success, -1 for failure
*
* This function will cause the nfapi_pnf_start function to return
*/
int nfapi_pnf_stop(nfapi_pnf_config_t* config);
/*! Send the PNF_PARAM.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp);
/*! Send the PNF_CONFIG.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp);
/*! Send the PNF_START.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp);
/*! Send the PNF_STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp);
/*! Send the PARAM.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp);
/*! Send the CONFIG.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp);
/*! Send the START.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp);
/*! Send the STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp);
/*! Send the MEASUREMENT.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_measurement_resp(nfapi_pnf_config_t* config, nfapi_measurement_response_t* resp);
/*! Send the RSSI.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_rssi_resp(nfapi_pnf_config_t* config, nfapi_rssi_response_t* resp);
/*! Send the RSSI.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_rssi_ind(nfapi_pnf_config_t* config, nfapi_rssi_indication_t* ind);
/*! Send the CELL_SEARCH.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_cell_search_resp(nfapi_pnf_config_t* config, nfapi_cell_search_response_t* resp);
/*! Send the CELL_SEARCH.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_cell_search_ind(nfapi_pnf_config_t* config, nfapi_cell_search_indication_t* ind);
/*! Send the BROADCAST_DETECT.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_broadcast_detect_resp(nfapi_pnf_config_t* config, nfapi_broadcast_detect_response_t* resp);
/*! Send the BROADCAST_DETECT.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_broadcast_detect_ind(nfapi_pnf_config_t* config, nfapi_broadcast_detect_indication_t* ind);
/*! Send the SYSTEM_INFORMATION_SCHEDULE.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_schedule_resp(nfapi_pnf_config_t* config, nfapi_system_information_schedule_response_t* resp);
/*! Send the SYSTEM_INFORMATION_SCHEDULE.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_schedule_ind(nfapi_pnf_config_t* config, nfapi_system_information_schedule_indication_t* ind);
/*! Send the SYSTEM_INFORMATION.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_resp(nfapi_pnf_config_t* config, nfapi_system_information_response_t* resp);
/*! Send the SYSTEM_INFORMATION.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_ind(nfapi_pnf_config_t* config, nfapi_system_information_indication_t* ind);
/*! Send the NMM_STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_nmm_stop_resp(nfapi_pnf_config_t* config, nfapi_nmm_stop_response_t* resp);
/*! Send a vendor extension message
* \param config A pointer to a pnf configuraiton
* \param msg A pointer to the vendor extention message structure
* \param msg_len The size of the vendor extention message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
//--------------------------
/*! A subframe buffer structure which can be used by the client to
* to configure the dummy information
*/
typedef struct
{
uint16_t sfn_sf;
nfapi_dl_config_request_t* dl_config_req;
nfapi_ul_config_request_t* ul_config_req;
nfapi_hi_dci0_request_t* hi_dci0_req;
nfapi_tx_request_t* tx_req;
nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
} nfapi_pnf_p7_subframe_buffer_t;
typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t;
/*! The nfapi PNF PHY P7 configuration information created using the nfapi_pnf_p7_create function
*/
typedef struct nfapi_pnf_p7_config
{
/*! A user define callback to override the default memory allocation
* \param size The size of the buffer to allocate
* \return An allocated buffer. 0 in the case of failure
*
* If not set malloc will be used
*/
void* (*malloc)(size_t size);
/*! A user define callback to override the default memory deallocation
* \param ptr Pointer to a buffer to dellocate
*
* If not set free will be used
*/
void (*free)(void* ptr);
/*! A user define callback to handle trace from the pnf
* \param level The trace level
* \param message The message string
*/
void (*trace)(nfapi_trace_level_t level, const char* message, ...);
/*! The PHY id*/
uint16_t phy_id;
// remote
/*! The VNF P7 UDP port */
int remote_p7_port;
/*! The VNF P7 UDP address */
char* remote_p7_addr;
// local
/*! The PNF P7 UDP port */
int local_p7_port;
/*! The PNF P7 UDP address */
char* local_p7_addr;
/*! Flag to indicate of the pnf should use the P7 checksum */
uint8_t checksum_enabled;
/*! The maxium size of a P7 segement. If a message is large that this it
* will be segemented */
uint16_t segment_size;
/*! The dummy subframe buffer structure that should be used in case there
* are no 'valid' subframe messages */
nfapi_pnf_p7_subframe_buffer_t dummy_subframe;
/*! Configuration options for the p7 pack unpack functions*/
nfapi_p7_codec_config_t codec_config;
/*! Optional userdata that will be passed back in the callbacks*/
void* user_data;
// tdb : if these should be public
uint16_t subframe_buffer_size;
uint8_t timing_info_mode_periodic; // 0:false 1:true
uint8_t timing_info_mode_aperiodic; // 0:false 1:true
uint8_t timing_info_period; // 1..225 in subframes
/*! A callback for the DL_CONFIG.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the dl config request message structure
* \return not currently used
*/
int (*dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
/*! A callback for the UL_CONFIG.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the ul config request message structure
* \return not currently used
*/
int (*ul_config_req)(nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
/*! A callback for the HI_DCI0.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the hi dci0 request message structure
* \return not currently used
*/
int (*hi_dci0_req)(nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
/*! A callback for the TX_REQ.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the tx request message structure
* \return not currently used
*
* The TX request contains pointers to the downlink PDUs to be sent. In the case that the FAPI interface
* will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0
* and then use the p7 codec config free function to release the pdu's when appropriate.
*/
int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req);
/*! A callback for the LBT_DL_CONFIG.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the lbt dl request message structure
* \return not currently used
*/
int (*lbt_dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req);
/*! A callback for vendor extension messages
* \param config A poiner to the PNF P7 config
* \param msg A pointer to a decode vendor extention message
* \return not currently used
*/
int (*vendor_ext)(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
/*! A callback to allocate vendor extension message
* \param message_id The vendor extention message id from the decode message header
* \param msg_size A pointer to size of the allocate vendor extention message. Set by the callee
* \return A pointer to an allocated vendor extention message structure. 0 if failed
*
*
*/
nfapi_p7_message_header_t* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
/*! A callback to deallocate vendor extension message
* \param header A pointer to a p7 vendor extention message
*/
void (*deallocate_p7_vendor_ext)(nfapi_p7_message_header_t* header);
} nfapi_pnf_p7_config_t;
/*! Create and initialise a nfapi_pnf_p7_config structure
* \return A pointer to a PNF P7 config structure
*/
nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create(void);
/*! Delete an nfapi_pnf_p7_config structure
* \param config
*/
int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config);
/*! Start the PNF P7 library.
* \param config A pointer to a PNF P7 config
* \return 0 means success, -1 means failure
*
* This function will not return until nfapi_pnf_p7_stop is called.
*/
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
/*! Stop the PNF P7 library.
* \param config A pointer to a PNF P7 config
* \return 0 means success, -1 means failure
*
* This function will cause the nfapi_pnf_p7_start to return
*/
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
/*! Subframe indication
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
* \param sfn_sf The SFN and SF in the format of FAPI
* \return 0 means success, -1 means failure
*
* The client should call the subframe indication every 1ms. The PNF will
* respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer
*
* If messages are not in the subframe buffer, they dummy subframe messages will be sent
*/
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf);
/*! Send the HARQ.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the harq indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t* ind);
/*! Send the CRC.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the crc indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind);
/*! Send the RX.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the rx indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind);
/*! Send the RACH.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the rach indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t* ind);
/*! Send the SRS.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the srs indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind);
/*! Send the SR.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the sr indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind);
/*! Send the CQI.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the cqi indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* ind);
/*! Send the LBT_DL.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind);
/*! Send the NB_HARQ.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind);
/*! Send the NRACH.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind);
/*! Send a vendor exntesion message
* \param config A pointer to a PNF P7 config
* \param msg A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
#if defined(__cplusplus)
}
#endif
#endif // _NFAPI_PNF_INTERFACE_H_
......@@ -1766,7 +1766,6 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
if (ue->mac_enabled == 1) {
// signal MAC that Msg3 was sent
// Substitute call to this function by call to fill_Tx_indication (UE_MAC_Tx_IND_Msg3_TYPE)
Msg3_transmitted(Mod_id,
CC_id,
frame_tx,
......@@ -1784,9 +1783,6 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
//if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
access_mode=SCHEDULED_ACCESS;
// Panos: Remove the call to ue_get_sdu here and use
// the corresponding Tx.request PDU, instead of ulsch_input_buffer, below.
ue_get_sdu(Mod_id,
CC_id,
frame_tx,
......
......@@ -52,6 +52,7 @@
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "openair2/PHY_INTERFACE/phy_stub_UE.h"
#ifdef PHY_EMUL
# include "SIMULATION/simulation_defs.h"
......@@ -71,6 +72,8 @@
extern uint8_t usim_test;
extern UL_IND_t *UL_INFO;
/*
#ifndef USER_MODE
#define msg debug_msg
......@@ -1586,7 +1589,9 @@ for (lcid=DCCH; (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE) ; lcid
// build PHR and update the timers
if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
//Panos: Substitute with a static value for the MAC layer abstraction
//phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
phr_p->PH = 40;
phr_p->R = 0;
LOG_D(MAC,"[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n",
module_idP,frameP, get_PHR(module_idP,CC_id,eNB_index), phr_p->PH,POWER_HEADROOM);
......@@ -1595,6 +1600,7 @@ for (lcid=DCCH; (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE) ; lcid
phr_p=NULL;
}
LOG_T(MAC,"[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n", module_idP,frameP,bsr_s, bsr_l, phr_p);
......@@ -1804,7 +1810,6 @@ for (lcid=DCCH; (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE) ; lcid
stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
#endif
// Panos: Tx_request should be filled from the ulsch_buffer here.
if (opt_enabled) {
trace_pdu(0, ulsch_buffer, buflen, module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0);
......@@ -1813,6 +1818,8 @@ for (lcid=DCCH; (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE) ; lcid
}
}
//------------------------------------------------------------------------------
// called at each subframe
// Performs :
......
......@@ -7,11 +7,15 @@
#include "openair2/LAYER2/MAC/vars.h"
//#include "common/ran_context.h"
#include "openair2/PHY_INTERFACE/phy_stub_UE.h"
//#include "nfapi_pnf_interface.h"
//#include "nfapi.h"
//#include "nfapi_pnf.h"
//extern uint8_t nfapi_pnf;
//extern uint8_t nfapi_pnf;
//UL_IND_t *UL_INFO;
void handle_nfapi_UE_Rx(uint8_t Mod_id, Sched_Rsp_t *Sched_INFO, int eNB_id){
......@@ -80,11 +84,11 @@ void handle_nfapi_UE_Rx(uint8_t Mod_id, Sched_Rsp_t *Sched_INFO, int eNB_id){
// C-RNTI parameter not actually used. Provided only to comply with existing function definition.
// Not sure about parameters to fill the preamble index.
const rnti_t c_rnti = UE_mac_inst[Mod_id].crnti;
rnti_t c_rnti = UE_mac_inst[Mod_id].crnti;
ue_process_rar(Mod_id, CC_id, frame,
dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //RA-RNTI
Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
c_rnti,
&c_rnti,
UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex,
Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data);
}
......@@ -102,15 +106,18 @@ void handle_nfapi_UE_Rx(uint8_t Mod_id, Sched_Rsp_t *Sched_INFO, int eNB_id){
}
void fill_rx_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen)
void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t* UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti)
{
nfapi_rx_indication_pdu_t *pdu;
int timing_advance_update;
//int sync_pos;
/*uint32_t harq_pid = subframe2harq_pid(&eNB->frame_parms,
frame,subframe);*/
//uint32_t harq_pid = subframe2harq_pid(&eNB->frame_parms,
// frame,subframe);
//UL_IND_t *UL_INFO = (UL_IND_t*)malloc16(sizeof(UL_IND_t));
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
......@@ -122,7 +129,7 @@ void fill_rx_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I
// pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle;
pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
pdu->rx_ue_information.rnti = UE_mac_inst[Mod_id].crnti;
pdu->rx_ue_information.rnti = rnti;
pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG;
//pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
pdu->rx_indication_rel8.length = buflen;
......@@ -134,7 +141,7 @@ void fill_rx_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I
pdu->rx_indication_rel8.timing_advance = timing_advance_update;
// if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
// if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
// if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}*/
/*switch (eNB->frame_parms.N_RB_DL) {
case 6:
pdu->rx_indication_rel8.timing_advance = timing_advance_update;
......@@ -182,7 +189,7 @@ void fill_rx_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I
}
void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO) {
void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti) {
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
nfapi_sr_indication_pdu_t *pdu = &UL_INFO->sr_ind.sr_pdu_list[UL_INFO->rx_ind.number_of_pdus];
......@@ -190,7 +197,7 @@ void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I
pdu->instance_length = 0; // don't know what to do with this
// pdu->rx_ue_information.handle = handle;
pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
pdu->rx_ue_information.rnti = UE_mac_inst[Mod_id].crnti;; //Panos: Is this the right RNTI?
pdu->rx_ue_information.rnti = rnti; //UE_mac_inst[Mod_id].crnti;; //Panos: Is this the right RNTI?
// Panos dependency from PHY not sure how to substitute this. Should we hardcode it?
......@@ -244,6 +251,7 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
//Panos: The two following should get extracted from the call to get_prach_resources().
UL_INFO->rach_ind.preamble_list[0].preamble_rel8.preamble = ra_PreambleIndex;
UL_INFO->rach_ind.preamble_list[0].preamble_rel8.rnti = ra_RNTI;
UL_INFO->rach_ind.number_of_preambles++;
UL_INFO->rach_ind.preamble_list[0].preamble_rel13.rach_resource_type = 0;
......@@ -253,10 +261,14 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
// If NFAPI PNF then we need to send the message to the VNF
//if (nfapi_pnf == 1)
//{
nfapi_rach_indication_t rach_ind;
rach_ind.header.message_id = NFAPI_RACH_INDICATION;
rach_ind.sfn_sf = frame<<4 | subframe;
rach_ind.rach_indication_body = UL_INFO->rach_ind;
//Panos: Not sure if we need the following. They refer to nfapi_rach_indication_t type
//so we cannot insert it to the UL_INFO which has an nfapi_rach_indication_body_t type.
//Probably it should be part of UL_indication() function before calling oai_nfapi_rach_ind(&rach_ind).
/*nfapi_rach_indication_t *rach_ind;
rach_ind->header.message_id = NFAPI_RACH_INDICATION;
rach_ind->sfn_sf = frame<<4 | subframe;
rach_ind->rach_indication_body = UL_INFO->rach_ind;*/
LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n");
LOG_E(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
......@@ -275,12 +287,12 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
}
void fill_ulsch_cqi_indication(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO) {
void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) {
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_pdu_list[UL_INFO->cqi_ind.number_of_cqis];
nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_raw_pdu_list[UL_INFO->cqi_ind.number_of_cqis];
pdu->rx_ue_information.rnti = UE_mac_inst[Mod_id].crnti;;
pdu->rx_ue_information.rnti = rnti;
//if (ulsch_harq->cqi_crc_status != 1)
//Panos: Since we assume that CRC flag is always 0 (ACK) I guess that data_offset should always be 0.
pdu->cqi_indication_rel9.data_offset = 0;
......@@ -315,6 +327,452 @@ void fill_ulsch_cqi_indication(int Mod_id, uint16_t frame,uint8_t subframe, UL_I
}
void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti)
{
//int UE_id = find_dlsch(rnti,eNB,SEARCH_EXIST);
//AssertFatal(UE_id>=0,"UE_id doesn't exist\n");
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_pdu_list[UL_INFO->harq_ind.number_of_harqs];
int i;
pdu->instance_length = 0; // don't know what to do with this
// pdu->rx_ue_information.handle = handle;
pdu->rx_ue_information.rnti = rnti;
//Panos: For now we consider only FDD
//if (eNB->frame_parms.frame_type == FDD) {
pdu->harq_indication_fdd_rel13.mode = 0;
pdu->harq_indication_fdd_rel13.number_of_ack_nack = harq_information->harq_information_rel10.harq_size;
//Panos: Could this be wrong? Is the number_of_ack_nack field equivalent to O_ACK?
//pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
for (i=0;i<harq_information->harq_information_rel10.harq_size;i++) {
//AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]);
pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 1; //Panos: Assuming always an ACK (No NACK or DTX)
// release DLSCH if needed
//if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
}
//}
/*else { // TDD
M=ul_ACK_subframe2_M(&eNB->frame_parms,
subframe);
pdu->harq_indication_fdd_rel13.mode = 1-bundling;
pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
for (i=0;i<ulsch_harq->O_ACK;i++) {
AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]);
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = 2-ulsch_harq->o_ACK[i];
// release DLSCH if needed
if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
else if (M>1 && ulsch_harq->o_ACK[i] == 1) {
// spatial bundling
release_harq(eNB,UE_id,0,frame,subframe,1<<i);
release_harq(eNB,UE_id,1,frame,subframe,1<<i);
}
}
}*/
UL_INFO->harq_ind.number_of_harqs++;
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
}
void fill_uci_harq_indication_UE_MAC(int Mod_id,
int frame,
int subframe,
UL_IND_t *UL_INFO,
nfapi_ul_config_harq_information *harq_information,
uint16_t rnti
/*uint8_t tdd_mapping_mode,
uint16_t tdd_multiplexing_mask*/) {
//int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
//AssertFatal(UE_id>=0,"UE_id doesn't exist\n");
pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_pdu_list[UL_INFO->harq_ind.number_of_harqs];
pdu->instance_length = 0; // don't know what to do with this
// pdu->rx_ue_information.handle = handle;
pdu->rx_ue_information.rnti = rnti;
// estimate UL_CQI for MAC (from antenna port 0 only)
// Panos: Set static SNR for now
//int SNRtimes10 = dB_fixed_times10(uci->stat) - 200;//(10*eNB->measurements.n0_power_dB[0]);
int SNRtimes10 = 640;
//if (SNRtimes10 < -100) LOG_I(PHY,"uci->stat %d \n",uci->stat);
if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255;
else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5;
pdu->ul_cqi_information.channel = 0;
//Panos: Considering only FDD for now
//if (eNB->frame_parms.frame_type == FDD) {
//Panos: Condition taken from fapi_l1::handle_uci_harq_information() function
if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
(harq_information->harq_information_rel9_fdd.harq_size == 1)) {
//if (uci->pucch_fmt == pucch_format1a) {
pdu->harq_indication_fdd_rel13.mode = 0;
pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1;
//AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; //Panos: Assuming always an ACK (No NACK or DTX)
}
else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
(harq_information->harq_information_rel9_fdd.harq_size == 2)) {
pdu->harq_indication_fdd_rel13.mode = 0;
pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2;
//AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]);
//AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]);
pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; //Panos: Assuming always an ACK (No NACK or DTX)
pdu->harq_indication_fdd_rel13.harq_tb_n[1] = 1; //Panos: Assuming always an ACK (No NACK or DTX)
// release DLSCH if needed
//if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
//if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
}
else AssertFatal(1==0,"only format 1a/b for now, received \n");
//}
/*else { // TDD
AssertFatal(tdd_mapping_mode==0 || tdd_mapping_mode==1 || tdd_mapping_mode==2,
"Illegal tdd_mapping_mode %d\n",tdd_mapping_mode);
pdu->harq_indication_tdd_rel13.mode = tdd_mapping_mode;
switch (tdd_mapping_mode) {
case 0: // bundling
if (uci->pucch_fmt == pucch_format1a) {
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
// release all bundled DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
}
else if (uci->pucch_fmt == pucch_format1b) {
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]);
AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]);
pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1];
// release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
}
break;
case 1: // multiplexing
AssertFatal(uci->pucch_fmt == pucch_format1b,"uci->pucch_format %d is not format1b\n",uci->pucch_fmt);
if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1a) {
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
// release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
}
else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) {
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]);
AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]);
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1];
// release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
}
else { // num_pucch_resources (M) > 1
pdu->harq_indication_tdd_rel13.number_of_ack_nack = uci->num_pucch_resources;
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1];
if (uci->num_pucch_resources == 3) pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2];
if (uci->num_pucch_resources == 4) pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3];
// spatial-bundling in this case so release both HARQ if necessary
release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask);
release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask);
}
break;
case 2: // special bundling (SR collision)
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
int tdd_config5_sf2scheds=0;
if (eNB->frame_parms.tdd_config==5) tdd_config5_sf2scheds = getM(eNB,frame,subframe);
switch (harq_ack[0]) {
case 0:
break;
case 1: // check if M=1,4,7
if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 ||
tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff);
release_harq(eNB,UE_id,1,frame,subframe,0xffff);
}
break;
case 2: // check if M=2,5,8
if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 ||
tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff);
release_harq(eNB,UE_id,1,frame,subframe,0xffff);
}
break;
case 3: // check if M=3,6,9
if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 ||
tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff);
release_harq(eNB,UE_id,1,frame,subframe,0xffff);
}
break;
}
break;
}
} //TDD*/
UL_INFO->harq_ind.number_of_harqs++;
LOG_E(PHY,"Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.number_of_harqs);
pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
}
void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
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, rnti %x for frame %d, subframe %d\n",
rel8->rnti,frame,subframe);
uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
uint16_t buflen = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size;
uint16_t rnti = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti;
uint8_t access_mode=SCHEDULED_ACCESS;
if(buflen>0){
ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
}
}
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);
uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
uint16_t buflen = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information;
uint16_t rnti = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
uint8_t access_mode=SCHEDULED_ACCESS;
if(buflen>0){
ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
}
if(ulsch_harq_information)
fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
}
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);
uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
uint16_t buflen = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
uint16_t rnti = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
uint8_t access_mode=SCHEDULED_ACCESS;
if(buflen>0){
ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
}
fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
}
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);
uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
uint16_t buflen = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information;
uint16_t rnti = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
uint8_t access_mode=SCHEDULED_ACCESS;
if(buflen>0){
ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti);
}
if(ulsch_harq_information)
fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
}
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);
uint16_t rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_harq_pdu.harq_information;
fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti);
}
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);
uint16_t rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
}
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);
uint16_t rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
// We fill the sr_indication only if ue_get_sr() would normally instruct PHY to send a SR.
if (ue_get_SR(Mod_id ,0,frame, 0, rnti, subframe))
fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,rnti);
nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information;
fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti);
}
/*else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_SRS_PDU_TYPE) {
handle_srs_pdu(eNB,ul_config_pdu,frame,subframe);
}*/
}
int ul_config_req_UE_MAC(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req)
{
LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
__FUNCTION__,
NFAPI_SFNSF2DEC(req->sfn_sf),
req->ul_config_request_body.number_of_pdus,
req->ul_config_request_body.rach_prach_frequency_resources,
req->ul_config_request_body.srs_present
);
/*if (RC.ru == 0)
{
return -1;
}
if (RC.eNB == 0)
{
return -2;
}
if (RC.eNB[0][0] == 0)
{
return -3;
}
if (sync_var != 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__);
return -4;
}*/
int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
int sf = NFAPI_SFNSF2SF(req->sfn_sf);
//struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
//eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];
module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change.
nfapi_ul_config_request_pdu_t* ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list;
//Panos: Not sure whether we should put the memory allocation here.
//*** Note we should find the right place to call free(UL_INFO).
UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
uint8_t is_rach = req->ul_config_request_body.rach_prach_frequency_resources;
if(is_rach) {
PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, sfn, 0, sf);
fill_rach_indication_UE_MAC(Mod_id, sfn ,sf, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
}
// subframe works off TX SFN/SF which is 4 ahead, need to put it back to RX SFN/SF
// probably could just use proc->frame_rx
// PanosQ: This an eNB MAC function. Are we allowed to call it from here?
// Also, it is only in the nfapi-RU-RAU-split
//subtract_subframe(&sfn, &sf, 4);
for (int i=0;i<req->ul_config_request_body.number_of_pdus;i++)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, ul_config_pdu_list[i].pdu_size);
if (
ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE ||
ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE ||
ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE ||
ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE ||
ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE ||
ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE ||
ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE
)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i);
handle_nfapi_ul_pdu_UE_MAC(Mod_id,&ul_config_pdu_list[i],sfn,sf,req->ul_config_request_body.srs_present);
}
else
{
//NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_config_pdu_list[i].pdu_type);
}
}
return 0;
}
......
......@@ -11,10 +11,15 @@
#include <stdint.h>
#include "openair2/PHY_INTERFACE/IF_Module.h"
#include "nfapi_interface.h"
#include "nfapi_pnf_interface.h"
//#include "openair1/PHY/LTE_TRANSPORT/defs.h"
//#include "openair1/PHY/defs.h"
//#include "openair1/PHY/LTE_TRANSPORT/defs.h"
UL_IND_t *UL_INFO;
// Panos: This function should return all the sched_response config messages which concern a specific UE. Inside this
// function we should somehow make the translation of config message's rnti to Mod_ID.
......@@ -24,6 +29,8 @@ Sched_Rsp_t get_nfapi_sched_response(uint8_t Mod_id);
// namely:ue_send_sdu(), or ue_decode_si(), or ue_decode_p(), or ue_process_rar() based on the rnti type.
void handle_nfapi_UE_Rx(uint8_t Mod_id, Sched_Rsp_t *Sched_INFO, int eNB_id);
int pnf_ul_config_req_UE_MAC(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req);
// This function will be processing UL and HI_DCI0 config requests to trigger all the MAC Tx related calls
// at the UE side, namely: ue_get_SR(), ue_get_rach(), ue_get_sdu() based on the pdu configuration type.
// The output of these calls will be put to an UL_IND_t structure which will then be the input to
......@@ -35,12 +42,15 @@ void send_nfapi_UL_indications(UL_IND_t UL_INFO);
// This function should be filling the nfapi ULSCH indications at the MAC level of the UE in a similar manner
// as fill_rx_indication() does. It should get called from ue_get_SDU()
void fill_rx_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen);
//void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe);
void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti);
// This function should be indicating directly to the eNB when there is a planned scheduling request at the MAC layer
// of the UE. It should get called from ue_get_SR()
void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO);
void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti);
// In our case the this function will be always indicating ACK to the MAC of the eNB (i.e. always assuming)
// successful decoding.
......@@ -50,7 +60,21 @@ void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_
void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI);
void fill_ulsch_cqi_indication(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO);
void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti);
void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti);
void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO,nfapi_ul_config_harq_information *harq_information, uint16_t rnti
/*uint8_t tdd_mapping_mode,
uint16_t tdd_multiplexing_mask*/);
int ul_config_req_UE_MAC(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req);
void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
nfapi_ul_config_request_pdu_t *ul_config_pdu,
uint16_t frame,uint8_t subframe,uint8_t srs_present);
#endif /* PHY_STUB_UE_H_ */
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