Merge remote-tracking branch 'origin/refactor-nas-config' into integration_2024_w31

This commit is contained in:
Robert Schmidt
2024-08-05 10:20:23 +02:00
118 changed files with 592 additions and 16679 deletions
@@ -1,6 +0,0 @@
ETHERNET_TRANSPORT_OBJS = $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/netlink_init.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/multicast_link.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/socket.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/bypass_session_layer.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/emu_transport.o
ETHERNET_TRANSPORT_OBJS += $(TOP_DIR)/SIMULATION/ETH_TRANSPORT/pgm_link.o
@@ -1,25 +0,0 @@
For reliable UDP multicast, the libpgm-dev should be installed on the machines,
otherwise the old multicast method using simply UDP will be used, resulting in
packet loss and unexpected behaviour of oaisim.
To compile OAI with PGM:
For Ubuntu 12.04 and earliers:
sudo apt-get install libpgm-dev
is sufficient
For Ubuntu older than 12.04:
wget http://openpgm.googlecode.com/files/libpgm-5.1.118.tar.gz
tar xvf libpgm-5.1.118.tar.gz
cd libpgm-5.1.118/openpgm/pgm
./configure --prefix=/usr
make
sudo make install
We have to clean oaisim compilation and re-compile
When running OAI, the -D should be used to provide the NIC to bind.
Parameter can be either an interface name or an ip address (refer to this link
for more informations: http://code.google.com/p/openpgm/wiki/OpenPgmConceptsTransport)
-144
View File
@@ -1,144 +0,0 @@
/*
* 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 defs.h
* \brief specifies the data structure and variable for phy emulation
* \author Navid Nikaein, Raymomd Knopp and Hicham Anouar
* \date 2011
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#ifndef __BYPASS_SESSION_LAYER_DEFS_H__
# define __BYPASS_SESSION_LAYER_DEFS_H__
//-----------------------------------------------------------------------------
//#include "openair_defs.h"
#include "common/openairinterface5g_limits.h"
#include "PHY/defs_common.h"
#include "PHY/LTE_TRANSPORT/uci_common.h"
typedef enum emu_transport_info_e {
EMU_TRANSPORT_INFO_ERROR = 0x0,
EMU_TRANSPORT_INFO_WAIT_PM,
EMU_TRANSPORT_INFO_WAIT_SM,
EMU_TRANSPORT_INFO_SYNC,
EMU_TRANSPORT_INFO_ENB,
EMU_TRANSPORT_INFO_UE,
EMU_TRANSPORT_INFO_RELEASE
} emu_transport_info_t;
#define WAIT_PM_TRANSPORT 1
#define WAIT_SM_TRANSPORT 2
#define SYNC_TRANSPORT 3
#define ENB_TRANSPORT 4
#define UE_TRANSPORT 5
#define RELEASE_TRANSPORT 6
#define WAIT_SYNC_TRANSPORT 1
#define SYNCED_TRANSPORT 2
//#define WAIT_ENB_TRANSPORT 2
//#define WAIT_UE_TRANSPORT 3
#define BYPASS_RX_BUFFER_SIZE 64000
#define BYPASS_TX_BUFFER_SIZE 64000
typedef unsigned int (*tx_handler_t) (unsigned char, char*, unsigned int*, unsigned int*);
typedef unsigned int (*rx_handler_t) (unsigned char, char*, unsigned int);
/*************************************************************/
typedef struct eNB_cntl_s {
uint32_t pbch_flag:1;
uint32_t pmch_flag:1;
uint32_t pss:2;
uint32_t sss:8;
uint32_t cfi:2;
uint32_t phich:19; // max 200 bit
// uint32_t pbch_payload:24;
uint32_t pbch_payload;
} eNB_cntl;
typedef struct UE_cntl_s {
uint8_t pucch_flag:3; // 0,7 = none, 1 = type 1, 2=type 1a, 3=type 1b, 4=type 2, 5=type 2a, 6=type 2b
uint8_t pucch_Ncs1:3; // physical configuration of pucch, for abstraction purposes
uint32_t pucch_payload:21; // ack/nak/cqi information
uint8_t sr:1;
uint8_t pusch_flag:1; // 0=none,1=active
uint8_t pucch_sel:1;
//uint32_t pusch_uci; // uci information on pusch
uint8_t pusch_uci[MAX_CQI_BYTES];
uint8_t uci_format;
uint8_t length_uci;
uint8_t pusch_ri:2; // ri information on pusch
uint8_t pusch_ack:2; // ack/nak on pusch
uint8_t prach_flag:1; // 0=none,1=active
uint8_t prach_id:6; // this is the PHY preamble index for the prach
} UE_cntl;
#define MAX_TRANSPORT_BLOCKS_BUFFER_SIZE 16384
//#define MAX_PMCH_TRANSPORT_BLOCKS_BUFFER_SIZE 8192 // 16384
#define MAX_NUM_DCI 5+1 // +1: for PMCH/MCH
typedef struct eNB_transport_info_s {
eNB_cntl cntl;
uint8_t num_pmch;
uint8_t num_common_dci;
uint8_t num_ue_spec_dci;
DCI_ALLOC_t dci_alloc[MAX_NUM_DCI];
uint8_t dlsch_type[MAX_NUM_DCI];
uint8_t harq_pid[MAX_NUM_DCI];
uint8_t ue_id[MAX_NUM_DCI];
uint16_t tbs[MAX_NUM_DCI*2]; // times 2 for dual-stream MIMO formats
uint8_t transport_blocks[MAX_TRANSPORT_BLOCKS_BUFFER_SIZE];
//uint8_t pmch_transport_blocks[MAX_PMCH_TRANSPORT_BLOCKS_BUFFER_SIZE];
} __attribute__((__packed__)) eNB_transport_info_t ;
typedef struct UE_transport_info_s {
UE_cntl cntl;
uint8_t num_eNB;
uint16_t rnti[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t eNB_id[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t harq_pid[NUMBER_OF_CONNECTED_eNB_MAX];
uint16_t tbs[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t transport_blocks[MAX_TRANSPORT_BLOCKS_BUFFER_SIZE];//*NUMBER_OF_CONNECTED_eNB_MAX];
} __attribute__((__packed__)) UE_transport_info_t ;
/*! \brief */
typedef struct bypass_msg_header_s {
unsigned char Message_type; /*! \brief control or data*/
//unsigned char nb_master; /*! \brief */
unsigned char master_id; /*! \brief */
unsigned int nb_enb; /*! \brief */
unsigned int nb_ue; /*! \brief */
unsigned int nb_flow; /*! \brief */
unsigned int frame;
unsigned int subframe;
uint64_t seq_num;
unsigned int failing_master_id;
} __attribute__((__packed__)) bypass_msg_header_t;
typedef struct bypass_proto2multicast_header_s {
unsigned int size;
} bypass_proto2multicast_header_t;
#endif /* __BYPASS_SESSION_LAYER_DEFS_H__ */
@@ -1,517 +0,0 @@
/*
* 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 phy_emulation.c
* \brief implements the underlying protocol for emulated data exchange over Ethernet using IP multicast
* \author Navid Nikaein
* \date 2011 - 2014
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "common/ran_context.h"
#include "defs.h"
#include "extern.h"
#include "proto.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "openair1/SIMULATION/ETH_TRANSPORT/extern.h"
unsigned char Emulation_status;
unsigned char emu_tx_status;
unsigned char emu_rx_status;
#if !defined(ENABLE_NEW_MULTICAST)
pthread_mutex_t Tx_mutex;
pthread_cond_t Tx_cond;
char Tx_mutex_var;
#endif
/* Handlers for RX and TX */
rx_handler_t rx_handler;
tx_handler_t tx_handler;
eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
uint16_t eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
UE_transport_info_t UE_transport_info[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
UE_cntl ue_cntl_delay[NUMBER_OF_UE_MAX][MAX_NUM_CCs][2];
extern unsigned int Master_list_rx;
extern unsigned char NB_INST;
//#define DEBUG_CONTROL 1
//#define DEBUG_EMU 1
void emu_transport_sync(void)
{
LOG_D(EMU, "Entering EMU transport SYNC is primary master %d\n",
oai_emulation.info.is_primary_master);
if (oai_emulation.info.is_primary_master == 0) {
retry:
bypass_tx_data(WAIT_SM_TRANSPORT,0,0);
// just wait to recieve the master 0 msg
Master_list_rx = oai_emulation.info.master_list - 1;
if (bypass_rx_data(0,0,0,1) == -1) {
/* In case the master is not ready at time we send the first message */
sleep(1);
goto retry;
}
} else {
bypass_rx_data(0,0,0,0);
bypass_tx_data(WAIT_PM_TRANSPORT,0,0);
}
if (oai_emulation.info.master_list!=0) {
retry2:
bypass_tx_data(SYNC_TRANSPORT,0,0);
if (bypass_rx_data(0,0,0,0) == -1) {
goto retry2;
}
// i received the sync from all secondary masters
if (emu_rx_status == SYNCED_TRANSPORT) {
emu_tx_status = SYNCED_TRANSPORT;
}
LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n");
}
LOG_D(EMU, "Leaving EMU transport SYNC is primary master %d\n",
oai_emulation.info.is_primary_master);
}
void emu_transport(unsigned int frame, unsigned int last_slot,
unsigned int next_slot,lte_subframe_t direction,
unsigned char frame_type,
int ethernet_flag )
{
if (ethernet_flag == 0) {
return;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(
VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_IN);
if ((frame_type == 1) && (direction == SF_S)) {
if ((next_slot % 2) == 0) {
emu_transport_DL(frame, last_slot, next_slot);
} else {
emu_transport_UL(frame, last_slot , next_slot);
}
//DL
} else {
if ((next_slot % 2) == 0) {
if (((frame_type == 1) && (direction == SF_DL )) || (frame_type == 0) ) {
emu_transport_DL(frame, last_slot, next_slot);
}
}
// UL
if (((frame_type == 1) && (direction == SF_UL)) || (frame_type == 0) ) {
emu_transport_UL(frame, last_slot, next_slot);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(
VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_OUT);
}
void emu_transport_DL(unsigned int frame, unsigned int last_slot,
unsigned int next_slot)
{
LOG_D(EMU, "Entering EMU transport DL, is primary master %d\n",
oai_emulation.info.is_primary_master);
if (oai_emulation.info.is_primary_master == 0) {
if (oai_emulation.info.nb_enb_local > 0) { // send in DL if
bypass_tx_data(ENB_TRANSPORT, frame, next_slot);
bypass_rx_data(frame, last_slot, next_slot, 1);
} else {
bypass_tx_data(WAIT_SM_TRANSPORT,frame,next_slot);
bypass_rx_data(frame, last_slot, next_slot, 0);
}
} else { // PM
if (oai_emulation.info.nb_enb_local>0) { // send in DL if
bypass_rx_data(frame, last_slot, next_slot, 1);
bypass_tx_data(ENB_TRANSPORT, frame, next_slot);
} else {
bypass_rx_data(frame, last_slot, next_slot, 0);
bypass_tx_data(WAIT_SM_TRANSPORT,frame,next_slot);
}
}
LOG_D(EMU, "Leaving EMU transport DL, is primary master %d\n",
oai_emulation.info.is_primary_master);
}
void emu_transport_UL(unsigned int frame, unsigned int last_slot,
unsigned int next_slot)
{
LOG_D(EMU, "Entering EMU transport UL, is primary master %d\n",
oai_emulation.info.is_primary_master);
if (oai_emulation.info.is_primary_master == 0) {
if (oai_emulation.info.nb_ue_local > 0) {
bypass_tx_data(UE_TRANSPORT, frame, next_slot);
bypass_rx_data(frame, last_slot, next_slot, 1);
} else {
bypass_tx_data(WAIT_SM_TRANSPORT, frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot, 0);
}
} else {
if (oai_emulation.info.nb_ue_local > 0) {
bypass_rx_data(frame, last_slot, next_slot, 1);
bypass_tx_data(UE_TRANSPORT, frame, next_slot);
} else {
bypass_rx_data(frame,last_slot, next_slot, 0);
bypass_tx_data(WAIT_SM_TRANSPORT, frame, next_slot);
}
}
LOG_D(EMU, "Leaving EMU transport UL, is primary master %d\n",
oai_emulation.info.is_primary_master);
}
void emu_transport_release(void)
{
bypass_tx_data(RELEASE_TRANSPORT,0,0);
LOG_E(EMU," tx RELEASE_TRANSPORT \n");
}
unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,
unsigned int *Nbytes,unsigned int *Nb_flows)
{
return *Nbytes;
}
unsigned int emul_rx_data(void)
{
return(0);
}
unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer,
unsigned int Nbytes)
{
unsigned short Rx_size=0;
return (Rx_size+2);
}
void clear_eNB_transport_info(uint8_t nb_eNB)
{
uint8_t eNB_id;
uint8_t CC_id;
for (eNB_id=0; eNB_id<nb_eNB; eNB_id++) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB_transport_info_TB_index[eNB_id][CC_id]=0;
memset((void *)&eNB_transport_info[eNB_id][CC_id].cntl,0,sizeof(eNB_cntl));
eNB_transport_info[eNB_id][CC_id].num_common_dci=0;
eNB_transport_info[eNB_id][CC_id].num_ue_spec_dci=0;
}
}
#ifdef DEBUG_EMU
LOG_D(EMU, "EMUL clear_eNB_transport_info\n");
#endif
}
void clear_UE_transport_info(uint8_t nb_UE)
{
uint8_t UE_id,CC_id;
for (UE_id=0; UE_id<nb_UE; UE_id++)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
memset((void *)&UE_transport_info[UE_id][CC_id].cntl,0,sizeof(UE_cntl));
}
#ifdef DEBUG_EMU
LOG_D(EMU, "EMUL clear_UE_transport_info\n");
#endif
}
void fill_phy_enb_vars(unsigned int enb_id, uint8_t CC_id,unsigned int next_slot)
{
int n_dci = 0, n_dci_dl;
int payload_offset = 0;
unsigned int harq_pid;
LTE_eNB_DLSCH_t *dlsch_eNB;
unsigned short ue_id;
uint8_t nb_total_dci;
// eNB
// PBCH : copy payload
*(uint32_t *)RC.eNB[enb_id][CC_id]->pbch_pdu =
eNB_transport_info[enb_id][CC_id].cntl.pbch_payload;
/* LOG_I(EMU," RX slot %d ENB TRANSPORT pbch payload %d pdu[0] %d pdu[0] %d \n",
next_slot ,
eNB_transport_info[enb_id][CC_id].cntl.pbch_payload,
((uint8_t*)RC.eNB[enb_id]->pbch_pdu)[0],
((uint8_t*)RC.eNB[enb_id]->pbch_pdu)[1]);
*/
// }
//CFI
// not needed yet
//PHICH
// to be added later
//DCI
nb_total_dci= eNB_transport_info[enb_id][CC_id].num_pmch +
eNB_transport_info[enb_id][CC_id].num_ue_spec_dci +
eNB_transport_info[enb_id][CC_id].num_common_dci;
RC.eNB[enb_id][CC_id]->num_ue_spec_dci[(next_slot>>1)&1] =
eNB_transport_info[enb_id][CC_id].num_ue_spec_dci;
RC.eNB[enb_id][CC_id]->num_common_dci[(next_slot>>1)&1] =
eNB_transport_info[enb_id][CC_id].num_common_dci;
#ifdef DEBUG_EMU
LOG_D(EMU, "Fill phy vars eNB %d for slot %d, DCI found %d \n",
enb_id, next_slot, nb_total_dci);
#endif
if (nb_total_dci >0) {
memcpy(RC.eNB[enb_id][CC_id]->dci_alloc[(next_slot>>1)&1],
eNB_transport_info[enb_id][CC_id].dci_alloc,
(nb_total_dci) * sizeof(DCI_ALLOC_t));
n_dci_dl=0;
// fill dlsch_eNB structure from DCI
for (n_dci = 0; n_dci < nb_total_dci; n_dci++) {
//exclude ul dci
if ((eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].format > 0) || (eNB_transport_info[enb_id][CC_id].num_pmch > 0 )) {
#ifdef DEBUG_EMU
LOG_D(EMU, "dci spec %d common %d pmch %d tbs is %d payload offset %d\n",
eNB_transport_info[enb_id][CC_id].num_ue_spec_dci,
eNB_transport_info[enb_id][CC_id].num_common_dci,
eNB_transport_info[enb_id][CC_id].num_pmch,
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl],
payload_offset);
#endif
switch (eNB_transport_info[enb_id][CC_id].dlsch_type[n_dci_dl]) {
case 0: //SI:
memcpy(RC.eNB[enb_id][CC_id]->dlsch_SI->harq_processes[0]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#ifdef DEBUG_EMU
LOG_D(EMU, "SI eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]%d \n",
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#endif
break;
case 1: //RA:
memcpy(RC.eNB[enb_id][CC_id]->dlsch_ra->harq_processes[0]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#ifdef DEBUG_EMU
LOG_D(EMU, "RA eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]%d \n",
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#endif
break;
case 2://TB0:
harq_pid = eNB_transport_info[enb_id][CC_id].harq_pid[n_dci_dl];
ue_id = eNB_transport_info[enb_id][CC_id].ue_id[n_dci_dl];
RC.eNB[enb_id][CC_id]->dlsch[ue_id][0]->rnti=
eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].rnti;
dlsch_eNB = RC.eNB[enb_id][CC_id]->dlsch[ue_id][0];
#ifdef DEBUG_EMU
LOG_D(EMU,
" enb_id %d ue id is %d rnti is %x dci index %d, harq_pid %d tbs %d \n",
enb_id, ue_id, eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].rnti,
n_dci_dl, harq_pid, eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
for (i=0; i<eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]; i++) {
LOG_T(EMU, "%x.",
(unsigned char) eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset+i]);
}
#endif
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
break;
case 3://TB1:
harq_pid = eNB_transport_info[enb_id][CC_id].harq_pid[n_dci_dl];
ue_id = eNB_transport_info[enb_id][CC_id].ue_id[n_dci_dl];
RC.eNB[enb_id][CC_id]->dlsch[ue_id][1]->rnti=
eNB_transport_info[enb_id][CC_id].dci_alloc[n_dci_dl].rnti;
dlsch_eNB = RC.eNB[enb_id][CC_id]->dlsch[ue_id][1];
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
break;
case 5:
memcpy(RC.eNB[enb_id][CC_id]->dlsch_MCH->harq_processes[0]->b,
&eNB_transport_info[enb_id][CC_id].transport_blocks[payload_offset],
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#ifdef DEBUG_EMU
LOG_D(EMU, "PMCH eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl] %d \n",
eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl]);
#endif
break;
default:
LOG_W(EMU,"not supported dlsch type %d \n", eNB_transport_info[enb_id][CC_id].dlsch_type[n_dci_dl]);
break;
}
payload_offset += eNB_transport_info[enb_id][CC_id].tbs[n_dci_dl];
}
n_dci_dl++;
}
#ifdef DEBUG_EMU
LOG_D(EMU, "Fill phy eNB vars done next slot %d !\n", next_slot);
#endif
}
}
void fill_phy_ue_vars(unsigned int ue_id, uint8_t CC_id,unsigned int last_slot)
{
int n_enb;//index
int enb_id;
// int harq_id;
// int payload_offset = 0;
unsigned short rnti;
unsigned int harq_pid;
LTE_UE_ULSCH_t *ulsch;
PUCCH_FMT_t pucch_format;
// uint8_t ue_transport_info_index[NUMBER_OF_eNB_MAX];
uint8_t subframe = (last_slot+1)>>1;
memcpy(&ue_cntl_delay[ue_id][CC_id][(last_slot+1)%2], &UE_transport_info[ue_id][CC_id].cntl,
sizeof(UE_cntl));
#ifdef DEBUG_EMU
LOG_D(EMU,
"Last slot %d subframe %d CC_id %d: Fill phy vars UE %d : PRACH is (%d,%d) preamble (%d,%d) SR (%d,%d), pucch_sel (%d, %d)\n",
last_slot,subframe,CC_id, ue_id,
UE_transport_info[ue_id][CC_id].cntl.prach_flag,
ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_flag,
UE_transport_info[ue_id][CC_id].cntl.prach_id,
ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_id,
UE_transport_info[ue_id][CC_id].cntl.sr,
ue_cntl_delay[ue_id][CC_id][last_slot%2].sr,
UE_transport_info[ue_id][CC_id].cntl.pucch_sel,
ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_sel);
#endif
//ue_cntl_delay[subframe%2].prach_flag ;
PHY_vars_UE_g[ue_id][CC_id]->generate_prach = ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_flag;//UE_transport_info[ue_id][CC_id].cntl.prach_flag;
if (PHY_vars_UE_g[ue_id][CC_id]->generate_prach == 1) {
// if (PHY_vars_UE_g[ue_id][CC_id]->prach_resources[enb_id] == NULL)
// PHY_vars_UE_g[ue_id][CC_id]->prach_resources[enb_id] = malloc(sizeof(PRACH_RESOURCES_t));
//ue_cntl_delay[subframe%2].prach_id;
PHY_vars_UE_g[ue_id][CC_id]->prach_PreambleIndex =
ue_cntl_delay[ue_id][CC_id][last_slot%2].prach_id;
}
pucch_format= ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_flag;// UE_transport_info[ue_id][CC_id].cntl.pucch_flag;
if ((last_slot + 1) % 2 == 0) {
if (pucch_format == pucch_format1) { // UE_transport_info[ue_id][CC_id].cntl.sr;
PHY_vars_UE_g[ue_id][CC_id]->sr[subframe] = ue_cntl_delay[ue_id][CC_id][last_slot%2].sr;
} else if ((pucch_format == pucch_format1a) ||
(pucch_format == pucch_format1b)) {
PHY_vars_UE_g[ue_id][CC_id]->pucch_payload[0] = ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_payload;
//UE_transport_info[ue_id][CC_id].cntl.pucch_payload;
}
PHY_vars_UE_g[ue_id][CC_id]->pucch_sel[subframe] =
ue_cntl_delay[ue_id][CC_id][last_slot%2].pucch_sel;
}
#ifdef DEBUG_EMU
LOG_D(EMU,"subframe %d trying to copy the payload from num eNB %d to UE %d \n",
subframe, UE_transport_info[ue_id][CC_id].num_eNB, ue_id);
#endif
for (n_enb = 0; n_enb < UE_transport_info[ue_id][CC_id].num_eNB; n_enb++) {
rnti = UE_transport_info[ue_id][CC_id].rnti[n_enb];
enb_id = UE_transport_info[ue_id][CC_id].eNB_id[n_enb];
PHY_vars_UE_g[ue_id][CC_id]->pdcch_vars[0][enb_id]->crnti=rnti;
PHY_vars_UE_g[ue_id][CC_id]->pdcch_vars[1][enb_id]->crnti=rnti;
harq_pid = UE_transport_info[ue_id][CC_id].harq_pid[n_enb];
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_RI[0] =
ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ri & 0x1;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_RI[1] =
(ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ri>>1) & 0x1;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_ACK[0]=
ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ack & 0x1;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o_ACK[1]=
(ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_ack>>1) & 0x1;
//*(uint32_t *)ulsch->o = ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_uci;
if ((last_slot % 2) == 1) {
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->O =
ue_cntl_delay[ue_id][CC_id][last_slot%2].length_uci;
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->uci_format =
ue_cntl_delay[ue_id][CC_id][last_slot%2].uci_format;
memcpy(PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->o,
ue_cntl_delay[ue_id][CC_id][last_slot%2].pusch_uci,
MAX_CQI_BYTES);
ulsch = PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id];
// if (((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1)
LOG_D(EMU,
"[UE %d] subframe %d last slot %d copy the payload from eNB %d to UE %d with harq id %d cqi (val %d, length %d) \n",
ue_id, subframe, last_slot, enb_id, ue_id, harq_pid,
((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1,
PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->O);
}
memcpy(PHY_vars_UE_g[ue_id][CC_id]->ulsch[enb_id]->harq_processes[harq_pid]->b,
UE_transport_info[ue_id][CC_id].transport_blocks,
UE_transport_info[ue_id][CC_id].tbs[enb_id]);
//ue_transport_info_index[enb_id]+=UE_transport_info[ue_id][CC_id].tbs[enb_id];
//UE_transport_info[ue_id][CC_id].transport_blocks+=ue_transport_info_index[enb_id];
//LOG_T(EMU,"ulsch tbs is %d\n", UE_transport_info[ue_id][CC_id].tbs[enb_id]);
}
}
@@ -1,60 +0,0 @@
/*
* 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 extern.h
* \brief specifies the extern variables for phy emulation
* \author Navid Nikaein and Raymomd Knopp and Hicham Anouar
* \date 2011
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#ifndef __BYPASS_SESSION_LAYER_EXTERN_H__
# define __BYPASS_SESSION_LAYER_EXTERN_H__
#include <pthread.h>
extern unsigned char Emulation_status;
extern unsigned char emu_tx_status;
extern unsigned char emu_rx_status;
//extern unsigned int Master_list;
//extern unsigned short Master_id;
//extern unsigned int Is_primary_master;
#if !defined(ENABLE_NEW_MULTICAST)
extern pthread_mutex_t Tx_mutex;
extern pthread_cond_t Tx_cond;
extern char Tx_mutex_var;
#endif
extern rx_handler_t rx_handler;
extern tx_handler_t tx_handler;
extern eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
extern uint16_t eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
extern UE_transport_info_t UE_transport_info[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
extern UE_cntl ue_cntl_delay[NUMBER_OF_UE_MAX][MAX_NUM_CCs][2];
#endif
@@ -1,329 +0,0 @@
/*
* 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 multicast_link.c
* \brief
* \author Lionel Gauthier and Navid Nikaein
* \date 2011
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>
#include <assert.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#define MULTICAST_LINK_C
#include "socket.h"
#include "multicast_link.h"
#include "common/utils/LOG/log.h"
extern unsigned short Master_id;
const char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS] = {
"239.0.0.161",
"239.0.0.162",
"239.0.0.163",
"239.0.0.164"
};
static multicast_group_t group_list[MULTICAST_LINK_NUM_GROUPS];
/* Socket file descriptors we want to wake up for, using select() */
static fd_set socks;
/* Highest #'d file descriptor, needed for select() */
static int highsock;
#if ! defined(ENABLE_NEW_MULTICAST)
static pthread_t main_loop_thread;
#endif
static void (*rx_handler) (unsigned int, char *);
static unsigned char multicast_group;
static char *multicast_if;
//------------------------------------------------------------------------------
void
multicast_link_init(void)
{
//------------------------------------------------------------------------------
int group;
int multicast_loop;
int reuse_addr = 1;
static struct ip_mreq command;
struct sockaddr_in sin;
// struct ifreq ifr;
for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) {
//strcpy (group_list[group].host_addr, multicast_group_list[group]);
strncpy (group_list[group].host_addr, multicast_group_list[group], sizeof(group_list[group].host_addr));
group_list[group].host_addr[sizeof(group_list[group].host_addr) - 1] = 0; // terminate string
group_list[group].port = 46014 + group;
group_list[group].socket = make_socket_inet(
SOCK_DGRAM,
&group_list[group].port, &sin);
LOG_D(PHY, "multicast_link_init(): Created socket %d for group %d, port %d\n",
group_list[group].socket,group,group_list[group].port);
/* Used so we can re-bind to our port while a previous connection is still
* in TIME_WAIT state.
*/
if (setsockopt(group_list[group].socket, SOL_SOCKET, SO_REUSEADDR,
&reuse_addr, sizeof (reuse_addr)) < 0) {
LOG_E(PHY, "[MULTICAST] ERROR : setsockopt:SO_REUSEADDR, exiting ...");
exit (EXIT_FAILURE);
}
if (multicast_if != NULL) {
if (setsockopt(group_list[group].socket, SOL_SOCKET,SO_BINDTODEVICE,
multicast_if, strlen(multicast_if)) < 0) {
LOG_E(PHY,
"[MULTICAST] ERROR : setsockopt:SO_BINDTODEVICE on interface %s, exiting ...\n",
multicast_if);
LOG_E(PHY,
"[MULTICAST] make sure that you have a root privilage or run with sudo -E \n");
exit (EXIT_FAILURE);
}
}
#if !defined(ENABLE_NEW_MULTICAST)
/* Make the socket blocking */
socket_setnonblocking(group_list[group].socket);
#endif
multicast_loop = 0;
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_MULTICAST_LOOP,
&multicast_loop, sizeof (multicast_loop)) < 0) {
LOG_E(PHY,
"[MULTICAST] ERROR: %s line %d multicast_link_main_loop() IP_MULTICAST_LOOP %m",
__FILE__, __LINE__);
exit (EXIT_FAILURE);
}
// Join the broadcast group:
command.imr_multiaddr.s_addr = inet_addr (group_list[group].host_addr);
command.imr_interface.s_addr = htonl (INADDR_ANY);
if (command.imr_multiaddr.s_addr == -1) {
LOG_E(PHY, "[MULTICAST] ERROR: %s line %d NO MULTICAST", __FILE__, __LINE__);
exit (EXIT_FAILURE);
}
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&command, sizeof (command)) < 0) {
LOG_E(PHY, "[MULTICAST] ERROR: %s line %d IP_ADD_MEMBERSHIP %m", __FILE__,
__LINE__);
exit (EXIT_FAILURE);
}
memset (&group_list[group].sock_remote_addr, 0, sizeof (struct sockaddr_in));
group_list[group].sock_remote_addr.sin_family = AF_INET;
group_list[group].sock_remote_addr.sin_addr.s_addr = inet_addr (multicast_group_list[group]);
group_list[group].sock_remote_addr.sin_port = htons (group_list[group].port);
}
}
//------------------------------------------------------------------------------
void
multicast_link_build_select_list (void)
{
//------------------------------------------------------------------------------
int group;
/* First put together fd_set for select(), which will
consist of the sock veriable in case a new connection
is coming in, plus all the sockets we have already
accepted. */
/* FD_ZERO() clears out the fd_set called socks, so that
it doesn't contain any file descriptors. */
FD_ZERO (&socks);
/* Loops through all the possible connections and adds
those sockets to the fd_set */
for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) {
if (group_list[group].socket != 0) {
FD_SET (group_list[group].socket, &socks);
if (group_list[group].socket > highsock) {
highsock = group_list[group].socket;
}
}
}
}
void
multicast_link_read_data (int groupP)
{
int num_bytes;
if ((groupP < MULTICAST_LINK_NUM_GROUPS) && (groupP >= 0)) {
if ((num_bytes = recvfrom (group_list[groupP].socket,
group_list[groupP].rx_buffer, 40000, 0, 0, 0)) < 0) {
LOG_E(PHY, "[MULTICAST] recvfrom has failed (%d:%s)\n (%s:%d)\n",
errno, strerror(errno), __FILE__, __LINE__);
} else {
rx_handler(num_bytes,group_list[groupP].rx_buffer);
}
} else {
LOG_E(PHY, "[MULTICAST] ERROR: groupP out of bounds %d\n", groupP);
}
}
//------------------------------------------------------------------------------
void
multicast_link_read (void)
{
//------------------------------------------------------------------------------
int group; /* Current item in connectlist for for loops */
/* Now check connectlist for available data */
/* Run through our sockets and check to see if anything
happened with them, if so 'service' them. */
for (group = multicast_group; group < MULTICAST_LINK_NUM_GROUPS ; group++) {
if (FD_ISSET (group_list[group].socket, &socks)) {
multicast_link_read_data (group);
break;
}
} /* for (all entries in queue) */
}
//------------------------------------------------------------------------------
int
multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP)
{
//------------------------------------------------------------------------------
int num;
if ((num = sendto (group_list[groupP].socket, dataP, sizeP, 0,
(struct sockaddr *) &group_list[groupP].sock_remote_addr,
sizeof (group_list[groupP].sock_remote_addr))) < 0) {
LOG_E(PHY, "[MULTICAST] sendto has failed (%d:%s)\n (%s:%d)\n",
errno, strerror(errno),
__FILE__, __LINE__);
}
return num;
}
int multicast_link_read_data_from_sock(uint8_t is_master)
{
struct timeval timeout, *timeout_p;
int readsocks; /* Number of sockets ready for reading */
timeout.tv_sec = 0;
timeout.tv_usec = 15000;
if (is_master == 0) {
/* UE will block indefinetely if no data is sent from eNB
* NOTE: a NULL timeout for select will block indefinetely
*/
timeout_p = NULL;
} else {
/* In case of eNB set the timeout to 500 usecs after which we consider
* the packets as dropped.
*/
timeout_p = &timeout;
}
highsock = -1;
multicast_link_build_select_list ();
LOG_D(PHY, "Stuck on select with timeout %s\n",
timeout_p == NULL ? "infinite" : "15000 usecs");
readsocks = select(highsock + 1, &socks, (fd_set *) 0, (fd_set *) 0, timeout_p);
if (readsocks < 0) {
LOG_E(PHY, "Multicast select failed (%d:%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
} else if (readsocks > 0) {
multicast_link_read();
} else {
/* Timeout */
LOG_I(PHY, "Multicast select time-out\n");
return 1;
}
return 0;
}
void* multicast_link_main_loop (void *param)
{
while (1) {
multicast_link_read_data_from_sock(0);
}
return NULL;
}
void multicast_link_start(void (*rx_handlerP) (unsigned int, char *),
unsigned char _multicast_group, char *multicast_ifname)
{
rx_handler = rx_handlerP;
multicast_group = _multicast_group;
multicast_if = multicast_ifname;
LOG_I(PHY, "[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n",
(multicast_if == NULL) ? "not specified" : multicast_if, multicast_group,
rx_handler);
multicast_link_init ();
#if ! defined(ENABLE_NEW_MULTICAST)
LOG_D(PHY, "[MULTICAST] multicast link start thread\n");
if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop,
NULL) != 0) {
LOG_E(PHY, "[MULTICAST LINK] Error in pthread_create (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
} else {
pthread_detach(main_loop_thread); // disassociate from parent
LOG_I(PHY, "[MULTICAST LINK] Thread detached\n");
}
#endif
}
@@ -1,66 +0,0 @@
/*
* 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 multicast_link.h
* \brief
* \author Lionel Gauthier and Navid Nikaein
* \date 2011
* \version 1.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#ifndef __MULTICAST_LINK_H__
# define __MULTICAST_LINK_H__
# ifdef MULTICAST_LINK_C
# define private_multicast_link(x) x
# define public_multicast_link(x) x
# else
# define private_multicast_link(x)
# define public_multicast_link(x) extern x
# endif
# include "stdint.h"
private_multicast_link (typedef struct multicast_group_t {
int socket;
struct sockaddr_in sock_remote_addr;
char host_addr[16];
uint16_t port;
char rx_buffer[40000];
} multicast_group_t;)
#define MULTICAST_LINK_NUM_GROUPS 4
extern const char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS];
private_multicast_link(void multicast_link_init (void));
private_multicast_link(void multicast_link_read_data (int groupP));
private_multicast_link(void multicast_link_read (void));
private_multicast_link(void *multicast_link_main_loop (void *param));
public_multicast_link(int multicast_link_write_sock (int groupP, char *dataP, uint32_t sizeP));
public_multicast_link(void multicast_link_start ( void (*rx_handlerP) (unsigned int, char*), unsigned char multicast_group, char * multicast_ifname));
# ifdef BYPASS_PHY
public_multicast_link(pthread_mutex_t Bypass_phy_wr_mutex);
public_multicast_link(pthread_cond_t Bypass_phy_wr_cond);
public_multicast_link(char Bypass_phy_wr);
# endif //BYPASS_PHY
#endif
@@ -1,227 +0,0 @@
/*
* 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 netlink_init.c
* \brief initiate the netlink socket for communication with nas dirver
* \author Navid Nikaein and Raymomd Knopp
* \date 2011
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include <sys/socket.h>
#include <linux/netlink.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include "common/platform_constants.h"
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include "common/openairinterface5g_limits.h"
#include "pdcp.h"
char nl_rx_buf[NL_MAX_PAYLOAD];
struct sockaddr_nl nas_src_addr, nas_dest_addr;
struct nlmsghdr *nas_nlh_tx = NULL;
struct nlmsghdr *nas_nlh_rx = NULL;
struct iovec nas_iov_tx;
struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)};
int nas_sock_fd[MAX_MOBILES_PER_ENB*2]; //Allocated for both LTE UE and NR UE.
int nas_sock_mbms_fd;
struct msghdr nas_msg_tx;
struct msghdr nas_msg_rx;
#define GRAAL_NETLINK_ID 31
static int tun_alloc(char *dev) {
struct ifreq ifr;
int fd, err;
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
LOG_E(PDCP, "[TUN] failed to open /dev/net/tun\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
if( *dev )
strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
close(fd);
return err;
}
strcpy(dev, ifr.ifr_name);
return fd;
}
int netlink_init_mbms_tun(char *ifprefix, int id) {//for UE, id = 1, 2, ...,
int ret;
char ifname[64];
if (id > 0) {
sprintf(ifname, "oaitun_%.3s%d", ifprefix, id-1);
}
else {
sprintf(ifname, "oaitun_%.3s1", ifprefix); // added "1": for historical reasons
}
nas_sock_mbms_fd = tun_alloc(ifname);
if (nas_sock_mbms_fd == -1) {
printf("[NETLINK] Error opening mbms socket %s (%d:%s)\n",ifname,errno, strerror(errno));
exit(1);
}
printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_mbms_fd);
ret = fcntl(nas_sock_mbms_fd,F_SETFL,O_NONBLOCK);
if (ret == -1) {
printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno));
if (LINK_ENB_PDCP_TO_IP_DRIVER) {
exit(1);
}
}
memset(&nas_src_addr, 0, sizeof(nas_src_addr));
nas_src_addr.nl_family = AF_NETLINK;
nas_src_addr.nl_pid = 1;//getpid(); /* self pid */
nas_src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(nas_sock_mbms_fd, (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr));
return 1;
}
int netlink_init_tun(char *ifprefix, int num_if, int id) {//for UE, id = 1, 2, ...,
int ret;
char ifname[64];
int begx = (id == 0) ? 0 : id - 1;
int endx = (id == 0) ? num_if : id;
for (int i = begx; i < endx; i++) {
sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1);
nas_sock_fd[i] = tun_alloc(ifname);
if (nas_sock_fd[i] == -1) {
LOG_E(PDCP, "TUN: Error opening socket %s (%d:%s)\n",ifname,errno, strerror(errno));
return 0;
}
LOG_I(PDCP, "TUN: Opened socket %s with fd nas_sock_fd[%d]=%d\n",
ifname, i, nas_sock_fd[i]);
ret = fcntl(nas_sock_fd[i],F_SETFL,O_NONBLOCK);
if (ret == -1) {
LOG_E(PDCP, "TUN: Error fcntl (%d:%s)\n",errno, strerror(errno));
if (LINK_ENB_PDCP_TO_IP_DRIVER) {
exit(1);
}
}
} /* for */
return 1;
}
int netlink_init(void) {
int ret;
nas_sock_fd[0] = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID);
if (nas_sock_fd[0] == -1) {
printf("[NETLINK] Error opening GRAAL_NETLINK_ID socket %d (%d:%s)\n",nas_sock_fd[0],errno, strerror(errno));
if (LINK_ENB_PDCP_TO_IP_DRIVER) {
exit(1);
}
}
printf("[NETLINK] Opened socket with fd %d\n",nas_sock_fd[0]);
ret = fcntl(nas_sock_fd[0],F_SETFL,O_NONBLOCK);
if (ret == -1) {
printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno));
if (LINK_ENB_PDCP_TO_IP_DRIVER) {
exit(1);
}
}
memset(&nas_src_addr, 0, sizeof(nas_src_addr));
nas_src_addr.nl_family = AF_NETLINK;
nas_src_addr.nl_pid = 1;//getpid(); /* self pid */
nas_src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(nas_sock_fd[0], (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr));
memset(&nas_dest_addr, 0, sizeof(nas_dest_addr));
nas_dest_addr.nl_family = AF_NETLINK;
nas_dest_addr.nl_pid = 0; /* For Linux Kernel */
nas_dest_addr.nl_groups = 0; /* unicast */
// TX PART
free(nas_nlh_tx);
nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD));
memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD));
/* Fill the netlink message header */
nas_nlh_tx->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD);
nas_nlh_tx->nlmsg_pid = 1;//getpid(); /* self pid */
nas_nlh_tx->nlmsg_flags = 0;
nas_iov_tx.iov_base = (void *)nas_nlh_tx;
nas_iov_tx.iov_len = nas_nlh_tx->nlmsg_len;
memset(&nas_msg_tx,0,sizeof(nas_msg_tx));
nas_msg_tx.msg_name = (void *)&nas_dest_addr;
nas_msg_tx.msg_namelen = sizeof(nas_dest_addr);
nas_msg_tx.msg_iov = &nas_iov_tx;
nas_msg_tx.msg_iovlen = 1;
// RX PART
memset(&nas_msg_rx,0,sizeof(nas_msg_rx));
nas_msg_rx.msg_name = (void *)&nas_src_addr;
nas_msg_rx.msg_namelen = sizeof(nas_src_addr);
nas_msg_rx.msg_iov = &nas_iov_rx;
nas_msg_rx.msg_iovlen = 1;
return(nas_sock_fd[0]);
}
void netlink_cleanup(void)
{
free(nas_nlh_tx);
nas_nlh_tx = NULL;
}
-69
View File
@@ -1,69 +0,0 @@
/*
* 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 proto.h
* \brief
* \author Navid Nikaein
* \date 2011
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include "SIMULATION/ETH_TRANSPORT/defs.h"
#ifndef EMU_PROTO_H_
#define EMU_PROTO_H_
void init_bypass (void);
void bypass_init ( unsigned int (*tx_handlerP) (unsigned char,char *, unsigned int *, unsigned int *),unsigned int (*rx_handlerP) (unsigned char,char *,unsigned int));
int bypass_rx_data(unsigned int frame, unsigned int last_slot,
unsigned int next_slot, uint8_t is_master);
void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot,
unsigned int next_slot, uint8_t is_master);
void bypass_tx_data (emu_transport_info_t Type, unsigned int frame, unsigned int next_slot);
void emulation_tx_rx(void);
unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,unsigned int *Nbytes,unsigned int *Nb_flows);
unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer, unsigned int Nbytes);
unsigned int emul_rx_data(void);
void emu_transport_info(unsigned int last_slot, unsigned int next_slot);
void fill_phy_enb_vars(unsigned int enb_id, uint8_t CC_id,unsigned int next_slot);
void fill_phy_ue_vars(unsigned int ue_id, uint8_t CC_id,unsigned int last_slot);
void emu_transport_sync(void);
void emu_transport(unsigned int frame, unsigned int last_slot,unsigned int next_slot, lte_subframe_t direction, unsigned char frame_type, int ethernet_flag );
void emu_transport_DL(unsigned int frame, unsigned int last_slot,unsigned int next_slot);
void emu_transport_UL(unsigned int frame, unsigned int last_slot,unsigned int next_slot);
void emu_transport_release(void);
int multicast_link_read_data_from_sock(uint8_t eNB_flag);
void clear_eNB_transport_info(uint8_t);
void clear_UE_transport_info(uint8_t);
int netlink_init(void);
int netlink_init_tun(char *ifsuffix, int num_if, int id);
int netlink_init_mbms_tun(char *ifsuffix, int id);
void netlink_cleanup(void);
#endif /* EMU_PROTO_H_ */
-109
View File
@@ -1,109 +0,0 @@
/*
* 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 socket.c
* \brief
* \author Lionel Gauthier
* \date 2011
* \version 1.0
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
//#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <assert.h>
#define SOCKET_C
//#include "openair_defs.h"
#include "socket.h"
#define msg printf
//------------------------------------------------------------------------------
void
socket_setnonblocking (int sockP)
{
//------------------------------------------------------------------------------
int opts;
opts = fcntl (sockP, F_GETFL);
if (opts < 0) {
perror ("fcntl(F_GETFL)");
exit (EXIT_FAILURE);
}
opts = (opts | O_NONBLOCK);
if (fcntl (sockP, F_SETFL, opts) < 0) {
perror ("fcntl(F_SETFL)");
exit (EXIT_FAILURE);
}
return;
}
//------------------------------------------------------------------------------
int
make_socket_inet (int typeP, uint16_t * portP, struct sockaddr_in *ptr_addressP)
{
//------------------------------------------------------------------------------
int sock;
unsigned int length = sizeof (struct sockaddr_in);
struct sockaddr_in name;
assert ((typeP == SOCK_STREAM) || (typeP == SOCK_DGRAM));
/* Create the socket. */
sock = socket (PF_INET, typeP, 0);
if (sock < 0) {
fprintf (stderr, "ERROR: %s line %d socket %m", __FILE__, __LINE__);
exit (EXIT_FAILURE);
}
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (*portP);
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
close (sock);
fprintf (stderr, "ERROR: %s line %d bind port %d %m", __FILE__, __LINE__, *portP);
exit (EXIT_FAILURE);
}
if (ptr_addressP != NULL) {
getsockname (sock, (struct sockaddr *) ptr_addressP, &length);
}
msg("[SOCKET] bound socket port %d\n", *portP);
return sock;
}
@@ -1,46 +0,0 @@
/*
* 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 socket.h
* \brief
* \author Lionel Gauthier
* \date 2011
* \version 1.0
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#ifndef __SIMULATION_ETH_TRANSPORT_SOCKET__H__
#define __SIMULATION_ETH_TRANSPORT_SOCKET__H__
# ifdef SOCKET_C
# define private_socket(x) x
# define public_socket(x) x
# else
# define private_socket(x)
# define public_socket(x) extern x
# endif
# include "stdint.h"
public_socket (void socket_setnonblocking (int sockP);
)
public_socket (int make_socket_inet (int typeP, uint16_t * portP, struct sockaddr_in *ptr_addressP);
)
#endif
@@ -47,8 +47,6 @@ SLDCH_t *ue_get_sldch(module_id_t module_idP, int CC_id,frame_t frameP, sub_fram
SLSCH_t *ue_get_slsch(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe) {return(NULL);}
void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {}
uint16_t
ue_process_rar(const module_id_t module_idP,
const int CC_id,