NR SA thread and sockets have been added.
This commit also removed MAX_NUM_NEIGH_CELLs and replaced it with MAX_GNB_CELLS. This was a minor change OAI added. The standalone sockets for the NR UE correctly connect to the proxy. We are currently receiving dl_tti messages from the proxy.
This commit is contained in:
@@ -124,6 +124,21 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
|
||||
init_N_TA_offset(ue);
|
||||
}
|
||||
|
||||
void init_nrUE_standalone_thread(int ue_idx)
|
||||
{
|
||||
const char *standalone_addr = "127.0.0.1";
|
||||
int standalone_tx_port = 3211 + (1+ue_idx)*2;
|
||||
int standalone_rx_port = 3212 + (1+ue_idx)*2;
|
||||
nrue_init_standalone_socket(standalone_addr, standalone_tx_port, standalone_rx_port);
|
||||
|
||||
pthread_t thread;
|
||||
if (pthread_create(&thread, NULL, nrue_standalone_pnf_task, NULL) != 0) {
|
||||
LOG_E(NR_MAC, "pthread_create failed for calling nrue_standalone_pnf_task");
|
||||
}
|
||||
pthread_setname_np(thread, "oai:nrue-stand");
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* It performs band scanning and synchonization.
|
||||
* \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
|
||||
|
||||
@@ -150,8 +150,6 @@ int usrp_tx_thread = 0;
|
||||
int oaisim_flag = 0;
|
||||
int emulate_rf = 0;
|
||||
|
||||
uint16_t ue_idx_standalone = 0xFFFF;
|
||||
|
||||
char uecap_xer[1024],uecap_xer_in=0;
|
||||
|
||||
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
|
||||
@@ -159,6 +157,9 @@ char uecap_xer[1024],uecap_xer_in=0;
|
||||
*/
|
||||
uint8_t abstraction_flag=0;
|
||||
|
||||
uint16_t ue_id_g;
|
||||
uint16_t ue_idx_standalone = 0xFFFF;
|
||||
|
||||
/*---------------------BMC: timespec helpers -----------------------------*/
|
||||
|
||||
struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
@@ -586,6 +587,19 @@ int main( int argc, char **argv ) {
|
||||
printf("UE threads created by %ld\n", gettid());
|
||||
|
||||
}
|
||||
if (NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
init_queue(&dl_itti_config_req_tx_data_req_queue);
|
||||
init_queue(&ul_dci_config_req_queue);
|
||||
|
||||
config_sync_var=0;
|
||||
if (sem_init(&sfn_slot_semaphore, 0, 0) != 0)
|
||||
{
|
||||
LOG_E(MAC, "sem_init() error\n");
|
||||
abort();
|
||||
}
|
||||
init_nrUE_standalone_thread(ue_id_g);
|
||||
//init_NR_UE_threads(NB_UE_INST);
|
||||
}
|
||||
|
||||
// wait for end of program
|
||||
printf("TYPE <CTRL-C> TO TERMINATE\n");
|
||||
|
||||
@@ -86,6 +86,5 @@ extern void print_opp_meas(void);
|
||||
void *UE_thread(void *arg);
|
||||
void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag);
|
||||
void init_nrUE_standalone_thread(int ue_idx);
|
||||
extern void init_nrUE_single_thread_stub(int nb_inst);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -115,6 +115,7 @@ extern "C"
|
||||
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
|
||||
#define NFAPI softmodem_params.nfapi
|
||||
#define NSA softmodem_params.nsa
|
||||
#define NODE_NUMBER softmodem_params.node_number
|
||||
|
||||
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
|
||||
|
||||
@@ -147,6 +148,7 @@ extern "C"
|
||||
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
|
||||
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
|
||||
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \
|
||||
{"node-number", NULL, 0, u16ptr:&NODE_NUMBER, defuintval:2, TYPE_UINT16, 0}, \
|
||||
}
|
||||
|
||||
#define CONFIG_HLP_NSA "Enable NSA mode \n"
|
||||
@@ -236,6 +238,7 @@ typedef struct {
|
||||
int use_256qam_table;
|
||||
uint8_t nfapi;
|
||||
int nsa;
|
||||
uint16_t node_number;
|
||||
} softmodem_params_t;
|
||||
|
||||
extern uint64_t get_softmodem_optmask(void);
|
||||
|
||||
@@ -43,8 +43,167 @@
|
||||
#define MAX_IF_MODULES 100
|
||||
|
||||
const char *dl_indication_type[] = {"MIB", "SIB", "DLSCH", "DCI", "RAR"};
|
||||
int current_sfn_slot;
|
||||
sem_t sfn_slot_semaphore;
|
||||
|
||||
queue_t dl_itti_config_req_tx_data_req_queue;
|
||||
queue_t ul_dci_config_req_queue;
|
||||
|
||||
UL_IND_t *UL_INFO = NULL;
|
||||
|
||||
|
||||
static nr_ue_if_module_t *nr_ue_if_module_inst[MAX_IF_MODULES];
|
||||
static int ue_tx_sock_descriptor = -1;
|
||||
static int ue_rx_sock_descriptor = -1;
|
||||
int current_sfn_slot;
|
||||
sem_t sfn_slot_semaphore;
|
||||
|
||||
void nrue_init_standalone_socket(const char *addr, int tx_port, int rx_port)
|
||||
{
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
int addr_len = sizeof(server_address);
|
||||
memset(&server_address, 0, addr_len);
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_port = htons(tx_port);
|
||||
|
||||
int sd = socket(server_address.sin_family, SOCK_DGRAM, 0);
|
||||
if (sd < 0)
|
||||
{
|
||||
LOG_E(MAC, "Socket creation error standalone PNF\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inet_pton(server_address.sin_family, addr, &server_address.sin_addr) <= 0)
|
||||
{
|
||||
LOG_E(MAC, "Invalid standalone PNF Address\n");
|
||||
close(sd);
|
||||
return;
|
||||
}
|
||||
|
||||
// Using connect to use send() instead of sendto()
|
||||
if (connect(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
||||
{
|
||||
LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||
close(sd);
|
||||
return;
|
||||
}
|
||||
assert(ue_tx_sock_descriptor == -1);
|
||||
ue_tx_sock_descriptor = sd;
|
||||
LOG_D(NR_RRC, "Sucessfully set up tx_socket in %s.\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
int addr_len = sizeof(server_address);
|
||||
memset(&server_address, 0, addr_len);
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_port = htons(rx_port);
|
||||
|
||||
int sd = socket(server_address.sin_family, SOCK_DGRAM, 0);
|
||||
if (sd < 0)
|
||||
{
|
||||
LOG_E(MAC, "Socket creation error standalone PNF\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inet_pton(server_address.sin_family, addr, &server_address.sin_addr) <= 0)
|
||||
{
|
||||
LOG_E(MAC, "Invalid standalone PNF Address\n");
|
||||
close(sd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bind(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
||||
{
|
||||
LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||
close(sd);
|
||||
return;
|
||||
}
|
||||
assert(ue_rx_sock_descriptor == -1);
|
||||
ue_rx_sock_descriptor = sd;
|
||||
LOG_D(NR_RRC, "Sucessfully set up rx_socket in %s.\n", __FUNCTION__);
|
||||
}
|
||||
LOG_I(NR_RRC, "NRUE standalone socket info: tx_port %d rx_port %d on %s.\n",
|
||||
tx_port, rx_port, addr);
|
||||
}
|
||||
|
||||
void *nrue_standalone_pnf_task(void *context)
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
socklen_t addr_len = sizeof(server_address);
|
||||
char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
|
||||
int sd = ue_rx_sock_descriptor;
|
||||
assert(sd > 0);
|
||||
LOG_I(NR_RRC, "Sucessfully started %s.\n", __FUNCTION__);
|
||||
|
||||
while (true)
|
||||
{
|
||||
ssize_t len = recvfrom(sd, buffer, sizeof(buffer), MSG_TRUNC, (struct sockaddr *)&server_address, &addr_len);
|
||||
if (len == -1)
|
||||
{
|
||||
LOG_E(MAC, "reading from standalone pnf sctp socket failed \n");
|
||||
continue;
|
||||
}
|
||||
if (len > sizeof(buffer))
|
||||
{
|
||||
LOG_E(MAC, "%s(%d). Message truncated. %zd\n", __FUNCTION__, __LINE__, len);
|
||||
continue;
|
||||
}
|
||||
if (len == sizeof(uint16_t))
|
||||
{
|
||||
uint16_t sfn_slot = 0;
|
||||
memcpy((void *)&sfn_slot, buffer, sizeof(sfn_slot));
|
||||
current_sfn_slot = sfn_slot;
|
||||
|
||||
if (sem_post(&sfn_slot_semaphore) != 0)
|
||||
{
|
||||
LOG_E(MAC, "sem_post() error\n");
|
||||
abort();
|
||||
}
|
||||
int sfn = NFAPI_SFNSLOT2SFN(sfn_slot);
|
||||
int slot = NFAPI_SFNSLOT2SLOT(sfn_slot);
|
||||
LOG_D(MAC, "Received from proxy sfn %d slot %d\n", sfn, slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
nfapi_p7_message_header_t header;
|
||||
if (nfapi_p7_message_header_unpack((void *)buffer, len, &header, sizeof(header), NULL) < 0)
|
||||
{
|
||||
LOG_E(MAC, "Header unpack failed for nrue_standalone pnf\n");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (header.message_id)
|
||||
{
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
||||
LOG_I(NR_PHY, "Melissa, we have received a NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message. \n");
|
||||
/* Melissa, not 100% sure what to do but I think we need to
|
||||
0. Add TX_DATA_REQUEST and pair them similarly
|
||||
1. Queue them
|
||||
2. De-queue and pair them
|
||||
3. Get SSB PDU when received. Inside this NFAPI_NR_DL_TTI_SSB_PDU_TYPE
|
||||
we need the cell_id, SSB block index, SSB subcarrier offset, and the BCH payload
|
||||
4. Send back the SSB PDU type (that comes in from Proxy) and send to LTE */
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
||||
LOG_I(NR_PHY, "Melissa, we have received a NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message. \n");
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
||||
LOG_I(NR_PHY, "Melissa, we have received a NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST message. \n");
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
||||
LOG_I(NR_PHY, "Melissa, we have received a NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST message. \n");
|
||||
break;
|
||||
default:
|
||||
LOG_E(MAC, "Case Statement has no corresponding nfapi message, this is the header ID %d\n", header.message_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //while(true)
|
||||
}
|
||||
|
||||
// L2 Abstraction Layer
|
||||
int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t *pduP, unsigned int additional_bits, uint32_t ssb_index, uint32_t ssb_length, uint16_t cell_id){
|
||||
|
||||
@@ -35,7 +35,10 @@
|
||||
|
||||
#include "platform_types.h"
|
||||
#include <openair1/PHY/thread_NR_UE.h>
|
||||
#include <semaphore.h>
|
||||
#include "fapi_nr_ue_interface.h"
|
||||
#include "openair2/PHY_INTERFACE/queue.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
|
||||
|
||||
@@ -200,6 +203,20 @@ typedef struct nr_ue_if_module_s {
|
||||
\param module_id module id*/
|
||||
nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id);
|
||||
|
||||
void nrue_init_standalone_socket(const char *addr, int tx_port, int rx_port);
|
||||
|
||||
void *nrue_standalone_pnf_task(void *context);
|
||||
extern int current_sfn_slot;
|
||||
extern sem_t sfn_slot_semaphore;
|
||||
|
||||
extern queue_t dl_itti_config_req_tx_data_req_queue;
|
||||
extern queue_t ul_dci_config_req_queue;
|
||||
|
||||
typedef struct nfapi_dl_tti_config_req_tx_data_req_t
|
||||
{
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_itti_config_req;
|
||||
nfapi_nr_tx_data_request_t *tx_data_req_pdu_list;
|
||||
} nfapi_dl_tti_config_req_tx_data_req_t;
|
||||
|
||||
/**\brief done free of memory allocation by module_id and release to pointer pool.
|
||||
\param module_id module id*/
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
//for D2D
|
||||
#define DEBUG_CTRL_SOCKET
|
||||
|
||||
#define CONTROL_SOCKET_PORT_NO 8888
|
||||
#define MAX_NUM_DEST 10
|
||||
//netlink
|
||||
@@ -812,11 +813,9 @@ typedef struct eNB_RRC_INST_s {
|
||||
uint32_t gnb_cells_id[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
|
||||
|
||||
// Nr scc freq band and SSB absolute frequency
|
||||
uint32_t nr_neigh_freq_band[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
|
||||
uint32_t nr_gnb_freq_band[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
|
||||
int nr_scg_ssb_freq;
|
||||
|
||||
|
||||
// other RAN parameters
|
||||
int srb1_timer_poll_retransmit;
|
||||
int srb1_poll_pdu;
|
||||
|
||||
@@ -1282,7 +1282,7 @@ rrc_eNB_generate_UECapabilityEnquiry(
|
||||
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
|
||||
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
|
||||
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
|
||||
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
|
||||
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
|
||||
size = do_UECapabilityEnquiry(
|
||||
ctxt_pP,
|
||||
buffer,
|
||||
@@ -1332,7 +1332,7 @@ rrc_eNB_generate_NR_UECapabilityEnquiry(
|
||||
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
|
||||
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
|
||||
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
|
||||
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
|
||||
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
|
||||
size = do_NR_UECapabilityEnquiry(
|
||||
ctxt_pP,
|
||||
buffer,
|
||||
@@ -8996,22 +8996,22 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
}
|
||||
|
||||
void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) {
|
||||
if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) {
|
||||
LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
|
||||
if (RC.rrc[mod_id]->num_gnb_cells >= MAX_NUM_GNB_CELLs) {
|
||||
LOG_E(RRC, "Error: number of gNB cells is exceeded\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m->num_cc > MAX_NUM_CCs) {
|
||||
LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n");
|
||||
LOG_E(RRC, "Error: number of gNB cells carriers is exceeded \n");
|
||||
return;
|
||||
}
|
||||
|
||||
RC.rrc[mod_id]->num_neigh_cells++;
|
||||
RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
|
||||
RC.rrc[mod_id]->num_gnb_cells++;
|
||||
RC.rrc[mod_id]->num_gnb_cells_cc[RC.rrc[mod_id]->num_gnb_cells-1] = m->num_cc;
|
||||
|
||||
for (int i=0; i<m->num_cc; i++) {
|
||||
RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i];
|
||||
RC.rrc[mod_id]->nr_neigh_freq_band[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->servedNrCell_band[i];
|
||||
RC.rrc[mod_id]->gnb_cells_id[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->Nid_cell[i];
|
||||
RC.rrc[mod_id]->nr_gnb_freq_band[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->servedNrCell_band[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -495,6 +495,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
|
||||
errno,
|
||||
strerror(errno));
|
||||
int msg_len=fread(buffer,1,1024,fd);
|
||||
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
|
||||
fclose(fd);
|
||||
if (rrc_config_path)
|
||||
sprintf(filename,"%s/rbconfig.raw",rrc_config_path);
|
||||
@@ -507,6 +508,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
|
||||
errno,
|
||||
strerror(errno));
|
||||
msg_len=fread(buffer,1,1024,fd);
|
||||
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
|
||||
fclose(fd);
|
||||
|
||||
}
|
||||
@@ -2961,10 +2963,9 @@ void init_connections_with_lte_ue(void)
|
||||
|
||||
static void process_measurement_objects_nr(LTE_MeasObjectToAddMod_t *buf)
|
||||
{
|
||||
LOG_I(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld and band: %ld.\n",
|
||||
LOG_I(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n",
|
||||
buf->measObject.choice.measObjectNR_r15.carrierFreq_r15,
|
||||
buf->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15,
|
||||
buf->measObject.choice.measObjectNR_r15.ext1->bandNR_r15);
|
||||
buf->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15);
|
||||
#if 0
|
||||
uint16_t node_num = get_softmodem_params()->node_number;
|
||||
/* Receiving the RRC_Reconfiguration with the measurement objects
|
||||
@@ -2974,7 +2975,6 @@ static void process_measurement_objects_nr(LTE_MeasObjectToAddMod_t *buf)
|
||||
ue_id_g = (node_num == 0)? 0 : node_num-2;
|
||||
init_nrUE_standalone_thread(ue_id_g);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3036,7 +3036,7 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len)
|
||||
to be opened. It will listen for PBCH from gNB (proxy technically). Then it will
|
||||
call the ususal MIB functions to handle the MIB. Intervene in 5G stack to decode the MIB.
|
||||
Also, after receiving PBCH it will start sending SSB index/cellID and some info from MIB to UE
|
||||
as measurement reporting message */
|
||||
as measurement reporting message*/
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user