- Update multicast:
* Remove recv thread * Update logs to LOG api * Retransmit Initial message if master not ready * Assert if packets lost -> break the execution if there is a drift in slots git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4006 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -1,16 +1,18 @@
|
||||
/*! \file bypass_session_layer.h
|
||||
* \brief implementation of emultor tx and rx
|
||||
* \author Navid Nikaein and Raymond Knopp
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
* \brief implementation of emultor tx and rx
|
||||
* \author Navid Nikaein and Raymond Knopp
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
|
||||
#include "PHY/defs.h"
|
||||
#include "defs.h"
|
||||
#include "proto.h"
|
||||
#include "extern.h"
|
||||
//#include "mac_extern.h"
|
||||
|
||||
#include "UTIL/assertions.h"
|
||||
#include "UTIL/OCG/OCG.h"
|
||||
#include "UTIL/OCG/OCG_extern.h"
|
||||
#include "UTIL/LOG/log.h"
|
||||
@@ -19,455 +21,523 @@
|
||||
#include "multicast_link.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
char rx_bufferP[BYPASS_RX_BUFFER_SIZE];
|
||||
static unsigned int num_bytesP=0;
|
||||
int N_P=0,N_R=0;
|
||||
char bypass_tx_buffer[BYPASS_TX_BUFFER_SIZE];
|
||||
unsigned int Master_list_rx, Seq_nb;
|
||||
/***************************************************************************/
|
||||
static unsigned int num_bytesP = 0;
|
||||
int N_P = 0, N_R = 0;
|
||||
char bypass_tx_buffer[BYPASS_TX_BUFFER_SIZE];
|
||||
static unsigned int byte_tx_count;
|
||||
unsigned int Master_list_rx;
|
||||
static uint64_t seq_num_tx = 0;
|
||||
|
||||
mapping transport_names[] = {
|
||||
{"WAIT PM TRANSPORT INFO", WAIT_PM_TRANSPORT_INFO},
|
||||
{"WAIT SM TRANSPORT INFO", WAIT_SM_TRANSPORT_INFO},
|
||||
{"SYNC TRANSPORT INFO", SYNC_TRANSPORT_INFO},
|
||||
{"ENB_TRANSPORT INFO", ENB_TRANSPORT_INFO},
|
||||
{"UE TRANSPORT INFO", UE_TRANSPORT_INFO},
|
||||
{"RELEASE TRANSPORT INFO", RELEASE_TRANSPORT_INFO},
|
||||
{"WAIT PM TRANSPORT INFO", EMU_TRANSPORT_INFO_WAIT_PM},
|
||||
{"WAIT SM TRANSPORT INFO", EMU_TRANSPORT_INFO_WAIT_SM},
|
||||
{"SYNC TRANSPORT INFO", EMU_TRANSPORT_INFO_SYNC},
|
||||
{"ENB_TRANSPORT INFO", EMU_TRANSPORT_INFO_ENB},
|
||||
{"UE TRANSPORT INFO", EMU_TRANSPORT_INFO_UE},
|
||||
{"RELEASE TRANSPORT INFO", EMU_TRANSPORT_INFO_RELEASE},
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
void init_bypass (void){
|
||||
|
||||
msg ("[PHYSIM] INIT BYPASS\n");
|
||||
pthread_mutex_init (&Tx_mutex, NULL);
|
||||
pthread_cond_init (&Tx_cond, NULL);
|
||||
Tx_mutex_var = 1;
|
||||
pthread_mutex_init (&emul_low_mutex, NULL);
|
||||
pthread_cond_init (&emul_low_cond, NULL);
|
||||
emul_low_mutex_var = 1;
|
||||
bypass_init (emul_tx_handler, emul_rx_handler);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
void bypass_init ( unsigned int (*tx_handlerP) (unsigned char,char*, unsigned int*, unsigned int*),unsigned int (*rx_handlerP) (unsigned char,char*,unsigned int)){
|
||||
/***************************************************************************/
|
||||
#ifdef USER_MODE
|
||||
multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group, oai_emulation.info.multicast_ifname);
|
||||
#endif //USER_MODE
|
||||
tx_handler = tx_handlerP;
|
||||
rx_handler = rx_handlerP;
|
||||
Master_list_rx=0;
|
||||
emu_tx_status = WAIT_SYNC_TRANSPORT;
|
||||
emu_rx_status = WAIT_SYNC_TRANSPORT;
|
||||
}
|
||||
/***************************************************************************/
|
||||
int bypass_rx_data (unsigned int frame, unsigned int last_slot, unsigned int next_slot){
|
||||
/***************************************************************************/
|
||||
bypass_msg_header_t *messg;
|
||||
bypass_proto2multicast_header_t *bypass_read_header;
|
||||
eNB_transport_info_t *eNB_info;
|
||||
UE_transport_info_t *UE_info;
|
||||
int ue_info_ix, enb_info_ix;
|
||||
// int tmp_byte_count;
|
||||
int bytes_read = 0;
|
||||
int bytes_data_to_read;
|
||||
// int num_flows;
|
||||
// int current_flow;
|
||||
int m_id, n_enb, n_ue, n_dci, total_tbs=0, total_header=0;
|
||||
|
||||
// printf("in bypass_rx_data ...\n");
|
||||
|
||||
|
||||
pthread_mutex_lock(&emul_low_mutex);
|
||||
if(emul_low_mutex_var){
|
||||
//LOG_T(EMU, " WAIT BYPASS_PHY...\n");
|
||||
pthread_cond_wait(&emul_low_cond, &emul_low_mutex);
|
||||
}
|
||||
|
||||
if(num_bytesP==0){
|
||||
//msg("[BYPASS] IDLE_WAIT\n");
|
||||
//exit(0);
|
||||
pthread_mutex_unlock(&emul_low_mutex);
|
||||
}
|
||||
|
||||
else{
|
||||
//LOG_T(EMU,"BYPASS_RX_DATA: IN, Num_bytesp=%d...\n",num_bytesP);
|
||||
bypass_read_header = (bypass_proto2multicast_header_t *) (&rx_bufferP[bytes_read]);
|
||||
bytes_read += sizeof (bypass_proto2multicast_header_t);
|
||||
bytes_data_to_read = bypass_read_header->size;
|
||||
if(num_bytesP!=bytes_read+bytes_data_to_read) {
|
||||
LOG_W(EMU, "WARNINIG BYTES2READ # DELIVERED BYTES!!!\n");
|
||||
}
|
||||
else{
|
||||
messg = (bypass_msg_header_t *) (&rx_bufferP[bytes_read]);
|
||||
bytes_read += sizeof (bypass_msg_header_t);
|
||||
if ( (messg->frame != frame) || (messg->subframe != next_slot>>1) )
|
||||
LOG_W(EMU, "Received %s from master %d for (frame %d,subframe %d) currently (frame %d,subframe %d)\n",
|
||||
map_int_to_str(transport_names,messg->Message_type), messg->master_id,
|
||||
messg->frame, messg->subframe,
|
||||
frame, next_slot>>1);
|
||||
//chek if MASTER in my List
|
||||
// switch(Emulation_status){
|
||||
switch(messg->Message_type){
|
||||
//case WAIT_SYNC_TRANSPORT:
|
||||
|
||||
case WAIT_PM_TRANSPORT_INFO:
|
||||
if (messg->master_id==0 )
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
break;
|
||||
|
||||
case WAIT_SM_TRANSPORT_INFO:
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
break;
|
||||
case SYNC_TRANSPORT_INFO:
|
||||
|
||||
// determite the total number of remote enb & ue
|
||||
oai_emulation.info.nb_enb_remote += messg->nb_enb;
|
||||
oai_emulation.info.nb_ue_remote += messg->nb_ue;
|
||||
// determine the index of local enb and ue wrt the remote ones
|
||||
if ( messg->master_id < oai_emulation.info.master_id ){
|
||||
oai_emulation.info.first_enb_local +=messg->nb_enb;
|
||||
oai_emulation.info.first_ue_local +=messg->nb_ue;
|
||||
}
|
||||
|
||||
// store param for enb per master
|
||||
if ((oai_emulation.info.master[messg->master_id].nb_enb = messg->nb_enb) > 0 ){
|
||||
for (m_id=0;m_id < messg->master_id; m_id++ ){
|
||||
oai_emulation.info.master[messg->master_id].first_enb+=oai_emulation.info.master[m_id].nb_enb;
|
||||
}
|
||||
LOG_I(EMU, "[ENB] WAIT_SYNC_TRANSPORT state: for master %d (first enb %d, totan enb %d)\n",
|
||||
messg->master_id,
|
||||
oai_emulation.info.master[messg->master_id].first_enb,
|
||||
oai_emulation.info.master[messg->master_id].nb_enb);
|
||||
}
|
||||
// store param for ue per master
|
||||
if ((oai_emulation.info.master[messg->master_id].nb_ue = messg->nb_ue) > 0){
|
||||
for (m_id=0;m_id < messg->master_id; m_id++ ){
|
||||
oai_emulation.info.master[messg->master_id].first_ue+=oai_emulation.info.master[m_id].nb_ue;
|
||||
}
|
||||
LOG_I(EMU, "[UE]WAIT_SYNC_TRANSPORT state: for master %d (first ue %d, total ue%d)\n",
|
||||
messg->master_id,
|
||||
oai_emulation.info.master[messg->master_id].first_ue,
|
||||
oai_emulation.info.master[messg->master_id].nb_ue );
|
||||
}
|
||||
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
if (Master_list_rx == oai_emulation.info.master_list) {
|
||||
emu_rx_status = SYNCED_TRANSPORT;
|
||||
}
|
||||
LOG_I(EMU,"WAIT_SYNC_TRANSPORT state: m_id %d total enb remote %d total ue remote %d \n",
|
||||
messg->master_id,oai_emulation.info.nb_enb_remote, oai_emulation.info.nb_ue_remote );
|
||||
|
||||
break;
|
||||
|
||||
//case WAIT_ENB_TRANSPORT:
|
||||
case ENB_TRANSPORT_INFO:
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU," RX ENB_TRANSPORT INFO from master %d \n",messg->master_id);
|
||||
void init_bypass (void)
|
||||
{
|
||||
LOG_I(EMU, "[PHYSIM] INIT BYPASS\n");
|
||||
#if !defined(ENABLE_NEW_MULTICAST)
|
||||
pthread_mutex_init (&Tx_mutex, NULL);
|
||||
pthread_cond_init (&Tx_cond, NULL);
|
||||
Tx_mutex_var = 1;
|
||||
pthread_mutex_init (&emul_low_mutex, NULL);
|
||||
pthread_cond_init (&emul_low_cond, NULL);
|
||||
emul_low_mutex_var = 1;
|
||||
#endif
|
||||
clear_eNB_transport_info(oai_emulation.info.nb_enb_local+oai_emulation.info.nb_enb_remote);
|
||||
|
||||
if (oai_emulation.info.master[messg->master_id].nb_enb > 0 ){
|
||||
enb_info_ix =0;
|
||||
total_header=0;
|
||||
total_header += sizeof(eNB_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
|
||||
eNB_info = (eNB_transport_info_t *) (&rx_bufferP[bytes_read]);
|
||||
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
|
||||
n_enb < oai_emulation.info.master[messg->master_id].first_enb+oai_emulation.info.master[messg->master_id].nb_enb ;
|
||||
n_enb ++) {
|
||||
total_tbs=0;
|
||||
for (n_dci = 0 ;
|
||||
n_dci < (eNB_info[enb_info_ix].num_ue_spec_dci+eNB_info[enb_info_ix].num_common_dci);
|
||||
n_dci ++) {
|
||||
total_tbs+=eNB_info[enb_info_ix].tbs[n_dci];
|
||||
}
|
||||
enb_info_ix++;
|
||||
if ( (total_tbs + total_header) > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ){
|
||||
LOG_W(EMU,"RX eNB Transport buffer total size %d (header%d,tbs %d) \n",
|
||||
total_header+total_tbs, total_header,total_tbs);
|
||||
}
|
||||
memcpy (&eNB_transport_info[n_enb],eNB_info, total_header+total_tbs);
|
||||
eNB_info = (eNB_transport_info_t *)((unsigned int)eNB_info + total_header+total_tbs);
|
||||
bytes_read+=total_header+total_tbs;
|
||||
}
|
||||
|
||||
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
|
||||
n_enb < oai_emulation.info.master[messg->master_id].first_enb+oai_emulation.info.master[messg->master_id].nb_enb ;
|
||||
n_enb ++)
|
||||
fill_phy_enb_vars(n_enb,next_slot);
|
||||
}
|
||||
else{
|
||||
LOG_T(EMU,"WAIT_ENB_TRANSPORT state: no enb transport info from master %d \n", messg->master_id);
|
||||
}
|
||||
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
if (Master_list_rx == oai_emulation.info.master_list) {
|
||||
emu_rx_status = SYNCED_TRANSPORT;
|
||||
}
|
||||
break;
|
||||
|
||||
case UE_TRANSPORT_INFO:
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU," RX UE TRANSPORT INFO from master %d\n",messg->master_id);
|
||||
#endif
|
||||
clear_UE_transport_info(oai_emulation.info.nb_ue_local+oai_emulation.info.nb_ue_remote);
|
||||
|
||||
|
||||
if (oai_emulation.info.master[messg->master_id].nb_ue > 0 ){ //&& oai_emulation.info.nb_enb_local >0 ){
|
||||
// get the header first
|
||||
ue_info_ix =0;
|
||||
total_header=0;
|
||||
total_header += sizeof(UE_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
UE_info = (UE_transport_info_t *) (&rx_bufferP[bytes_read]);
|
||||
// get the total size of the transport blocks
|
||||
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
|
||||
n_ue < oai_emulation.info.master[messg->master_id].first_ue+oai_emulation.info.master[messg->master_id].nb_ue ;
|
||||
n_ue ++) {
|
||||
total_tbs=0;
|
||||
for (n_enb = 0;n_enb < UE_info[ue_info_ix].num_eNB; n_enb ++) {
|
||||
total_tbs+=UE_info[ue_info_ix].tbs[n_enb];
|
||||
}
|
||||
ue_info_ix++;
|
||||
if (total_tbs + total_header > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ){
|
||||
LOG_W(EMU,"RX [UE %d] Total size of buffer is %d (header%d,tbs %d) \n",
|
||||
n_ue, total_header+total_tbs,total_header,total_tbs);
|
||||
}
|
||||
memcpy (&UE_transport_info[n_ue], UE_info, total_header+total_tbs);
|
||||
UE_info = (UE_transport_info_t *)((unsigned int)UE_info + total_header+total_tbs);
|
||||
bytes_read+=total_header+total_tbs;
|
||||
}
|
||||
#ifdef DEBUG_EMU
|
||||
for (n_enb=0; n_enb < UE_info[0].num_eNB; n_enb ++ )
|
||||
LOG_T(EMU,"dump ue transport info rnti %x enb_id %d, harq_id %d tbs %d\n",
|
||||
UE_transport_info[0].rnti[n_enb],
|
||||
UE_transport_info[0].eNB_id[n_enb],
|
||||
UE_transport_info[0].harq_pid[n_enb],
|
||||
UE_transport_info[0].tbs[n_enb]);
|
||||
#endif
|
||||
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
|
||||
n_ue < oai_emulation.info.master[messg->master_id].first_ue + oai_emulation.info.master[messg->master_id].nb_ue ;
|
||||
n_ue ++) {
|
||||
fill_phy_ue_vars(n_ue,last_slot);
|
||||
}
|
||||
}
|
||||
else{
|
||||
LOG_T(EMU,"WAIT_UE_TRANSPORT state: no UE transport info from master %d\n", messg->master_id );
|
||||
}
|
||||
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
if (Master_list_rx == oai_emulation.info.master_list) {
|
||||
emu_rx_status = SYNCED_TRANSPORT;
|
||||
}
|
||||
break;
|
||||
case RELEASE_TRANSPORT_INFO :
|
||||
Master_list_rx = oai_emulation.info.master_list;
|
||||
LOG_E(EMU, "RX RELEASE_TRANSPORT_INFO\n");
|
||||
break;
|
||||
default:
|
||||
msg("[MAC][BYPASS] ERROR RX UNKNOWN MESSAGE\n");
|
||||
//mac_xface->macphy_exit("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
num_bytesP=0;
|
||||
emul_low_mutex_var=1;
|
||||
//msg("[BYPASS] CALLING_SIGNAL_HIGH_MAC\n");
|
||||
pthread_cond_signal(&emul_low_cond);
|
||||
pthread_mutex_unlock(&emul_low_mutex);
|
||||
bypass_signal_mac_phy(frame,last_slot, next_slot);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//printf("leaving ...\n");
|
||||
return bytes_read;
|
||||
bypass_init (emul_tx_handler, emul_rx_handler);
|
||||
}
|
||||
|
||||
/******************************************************************************************************/
|
||||
#ifndef USER_MODE
|
||||
int bypass_rx_handler(unsigned int fifo, int rw){
|
||||
/******************************************************************************************************/
|
||||
// if(rw=='w'){
|
||||
int bytes_read;
|
||||
int bytes_processed=0;
|
||||
int header_bytes; //, elapsed_time;
|
||||
/***************************************************************************/
|
||||
void bypass_init (tx_handler_t tx_handlerP, rx_handler_t rx_handlerP)
|
||||
{
|
||||
/***************************************************************************/
|
||||
#if defined(USER_MODE)
|
||||
multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group,
|
||||
oai_emulation.info.multicast_ifname);
|
||||
#endif //USER_MODE
|
||||
tx_handler = tx_handlerP;
|
||||
rx_handler = rx_handlerP;
|
||||
Master_list_rx=0;
|
||||
emu_tx_status = WAIT_SYNC_TRANSPORT;
|
||||
emu_rx_status = WAIT_SYNC_TRANSPORT;
|
||||
}
|
||||
|
||||
|
||||
int bypass_rx_data(unsigned int frame, unsigned int last_slot,
|
||||
unsigned int next_slot, uint8_t is_master)
|
||||
{
|
||||
bypass_msg_header_t *messg;
|
||||
bypass_proto2multicast_header_t *bypass_read_header;
|
||||
eNB_transport_info_t *eNB_info;
|
||||
UE_transport_info_t *UE_info;
|
||||
int ue_info_ix, enb_info_ix;
|
||||
int bytes_read = 0;
|
||||
int bytes_data_to_read;
|
||||
int m_id, n_enb, n_ue, n_dci, total_tbs = 0, total_header = 0;
|
||||
|
||||
LOG_D(EMU, "Entering bypass_rx for frame %d next_slot %d is_master %u\n",
|
||||
frame, next_slot, is_master);
|
||||
|
||||
#if defined(ENABLE_NEW_MULTICAST)
|
||||
if (multicast_link_read_data_from_sock(is_master) == 1) {
|
||||
/* We got a timeout */
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
pthread_mutex_lock(&emul_low_mutex);
|
||||
if(emul_low_mutex_var) {
|
||||
pthread_cond_wait(&emul_low_cond, &emul_low_mutex);
|
||||
}
|
||||
|
||||
if(num_bytesP==0) {
|
||||
pthread_mutex_unlock(&emul_low_mutex);
|
||||
} else {
|
||||
#endif
|
||||
bypass_read_header = (bypass_proto2multicast_header_t *) (
|
||||
&rx_bufferP[bytes_read]);
|
||||
bytes_read += sizeof (bypass_proto2multicast_header_t);
|
||||
bytes_data_to_read = bypass_read_header->size;
|
||||
if(num_bytesP!=bytes_read+bytes_data_to_read) {
|
||||
LOG_W(EMU, "WARNINIG BYTES2READ # DELIVERED BYTES!!!\n");
|
||||
} else {
|
||||
messg = (bypass_msg_header_t *) (&rx_bufferP[bytes_read]);
|
||||
bytes_read += sizeof (bypass_msg_header_t);
|
||||
#if defined(ENABLE_NEW_MULTICAST)
|
||||
LOG_D(EMU, "Received %d bytes [%s] from master_id %d with seq %"PRIuMAX"\n",
|
||||
num_bytesP, map_int_to_str(transport_names, messg->Message_type),
|
||||
messg->master_id,
|
||||
messg->seq_num);
|
||||
DevCheck4((messg->frame == frame) && (messg->subframe == (next_slot>>1)),
|
||||
messg->frame, frame, messg->subframe, next_slot>>1);
|
||||
#else
|
||||
if ((messg->frame != frame) || (messg->subframe != next_slot>>1))
|
||||
LOG_W(EMU,
|
||||
"Received %s from master %d for (frame %d,subframe %d) "
|
||||
"currently (frame %d,subframe %d)\n",
|
||||
map_int_to_str(transport_names,messg->Message_type),
|
||||
messg->master_id,
|
||||
messg->frame, messg->subframe,
|
||||
frame, next_slot>>1);
|
||||
#endif
|
||||
//chek if MASTER in my List
|
||||
// switch(Emulation_status){
|
||||
switch(messg->Message_type) {
|
||||
//case WAIT_SYNC_TRANSPORT:
|
||||
|
||||
case EMU_TRANSPORT_INFO_WAIT_PM:
|
||||
if (messg->master_id==0 ) {
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
}
|
||||
break;
|
||||
case EMU_TRANSPORT_INFO_WAIT_SM:
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
break;
|
||||
case EMU_TRANSPORT_INFO_SYNC:
|
||||
|
||||
// determite the total number of remote enb & ue
|
||||
oai_emulation.info.nb_enb_remote += messg->nb_enb;
|
||||
oai_emulation.info.nb_ue_remote += messg->nb_ue;
|
||||
// determine the index of local enb and ue wrt the remote ones
|
||||
if ( messg->master_id < oai_emulation.info.master_id ) {
|
||||
oai_emulation.info.first_enb_local +=messg->nb_enb;
|
||||
oai_emulation.info.first_ue_local +=messg->nb_ue;
|
||||
}
|
||||
|
||||
// store param for enb per master
|
||||
if ((oai_emulation.info.master[messg->master_id].nb_enb = messg->nb_enb) > 0 ) {
|
||||
for (m_id=0; m_id < messg->master_id; m_id++ ) {
|
||||
oai_emulation.info.master[messg->master_id].first_enb+=oai_emulation.info.master[m_id].nb_enb;
|
||||
}
|
||||
LOG_I(EMU,
|
||||
"[ENB] WAIT_SYNC_TRANSPORT state: for master %d (first enb %d, totan enb %d)\n",
|
||||
messg->master_id,
|
||||
oai_emulation.info.master[messg->master_id].first_enb,
|
||||
oai_emulation.info.master[messg->master_id].nb_enb);
|
||||
}
|
||||
// store param for ue per master
|
||||
if ((oai_emulation.info.master[messg->master_id].nb_ue = messg->nb_ue) > 0) {
|
||||
for (m_id=0; m_id < messg->master_id; m_id++ ) {
|
||||
oai_emulation.info.master[messg->master_id].first_ue+=oai_emulation.info.master[m_id].nb_ue;
|
||||
}
|
||||
LOG_I(EMU,
|
||||
"[UE]WAIT_SYNC_TRANSPORT state: for master %d (first ue %d, total ue%d)\n",
|
||||
messg->master_id,
|
||||
oai_emulation.info.master[messg->master_id].first_ue,
|
||||
oai_emulation.info.master[messg->master_id].nb_ue );
|
||||
}
|
||||
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
if (Master_list_rx == oai_emulation.info.master_list) {
|
||||
emu_rx_status = SYNCED_TRANSPORT;
|
||||
}
|
||||
LOG_I(EMU,
|
||||
"WAIT_SYNC_TRANSPORT state: m_id %d total enb remote %d total ue remote %d \n",
|
||||
messg->master_id,oai_emulation.info.nb_enb_remote,
|
||||
oai_emulation.info.nb_ue_remote );
|
||||
break;
|
||||
|
||||
//case WAIT_ENB_TRANSPORT:
|
||||
case EMU_TRANSPORT_INFO_ENB:
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU," RX ENB_TRANSPORT INFO from master %d \n",messg->master_id);
|
||||
#endif
|
||||
clear_eNB_transport_info(oai_emulation.info.nb_enb_local+
|
||||
oai_emulation.info.nb_enb_remote);
|
||||
|
||||
if (oai_emulation.info.master[messg->master_id].nb_enb > 0 ) {
|
||||
enb_info_ix =0;
|
||||
total_header=0;
|
||||
total_header += sizeof(eNB_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
|
||||
eNB_info = (eNB_transport_info_t *) (&rx_bufferP[bytes_read]);
|
||||
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
|
||||
n_enb < oai_emulation.info.master[messg->master_id].first_enb+
|
||||
oai_emulation.info.master[messg->master_id].nb_enb ;
|
||||
n_enb ++) {
|
||||
total_tbs=0;
|
||||
for (n_dci = 0 ;
|
||||
n_dci < (eNB_info[enb_info_ix].num_ue_spec_dci+
|
||||
eNB_info[enb_info_ix].num_common_dci);
|
||||
n_dci ++) {
|
||||
total_tbs+=eNB_info[enb_info_ix].tbs[n_dci];
|
||||
}
|
||||
enb_info_ix++;
|
||||
if ( (total_tbs + total_header) > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ) {
|
||||
LOG_W(EMU,"RX eNB Transport buffer total size %d (header%d,tbs %d) \n",
|
||||
total_header+total_tbs, total_header,total_tbs);
|
||||
}
|
||||
memcpy (&eNB_transport_info[n_enb],eNB_info, total_header+total_tbs);
|
||||
eNB_info = (eNB_transport_info_t *)((unsigned int)eNB_info + total_header+
|
||||
total_tbs);
|
||||
bytes_read+=total_header+total_tbs;
|
||||
}
|
||||
|
||||
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
|
||||
n_enb < oai_emulation.info.master[messg->master_id].first_enb+
|
||||
oai_emulation.info.master[messg->master_id].nb_enb ;
|
||||
n_enb ++) {
|
||||
fill_phy_enb_vars(n_enb, next_slot);
|
||||
}
|
||||
} else {
|
||||
LOG_T(EMU,"WAIT_ENB_TRANSPORT state: no enb transport info from master %d \n",
|
||||
messg->master_id);
|
||||
}
|
||||
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
if (Master_list_rx == oai_emulation.info.master_list) {
|
||||
emu_rx_status = SYNCED_TRANSPORT;
|
||||
}
|
||||
break;
|
||||
case EMU_TRANSPORT_INFO_UE:
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU," RX UE TRANSPORT INFO from master %d\n",messg->master_id);
|
||||
#endif
|
||||
clear_UE_transport_info(oai_emulation.info.nb_ue_local+
|
||||
oai_emulation.info.nb_ue_remote);
|
||||
|
||||
|
||||
if (oai_emulation.info.master[messg->master_id].nb_ue >
|
||||
0 ) { //&& oai_emulation.info.nb_enb_local >0 ){
|
||||
// get the header first
|
||||
ue_info_ix =0;
|
||||
total_header=0;
|
||||
total_header += sizeof(UE_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
UE_info = (UE_transport_info_t *) (&rx_bufferP[bytes_read]);
|
||||
// get the total size of the transport blocks
|
||||
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
|
||||
n_ue < oai_emulation.info.master[messg->master_id].first_ue+
|
||||
oai_emulation.info.master[messg->master_id].nb_ue ;
|
||||
n_ue ++) {
|
||||
total_tbs=0;
|
||||
for (n_enb = 0; n_enb < UE_info[ue_info_ix].num_eNB; n_enb ++) {
|
||||
total_tbs+=UE_info[ue_info_ix].tbs[n_enb];
|
||||
}
|
||||
ue_info_ix++;
|
||||
if (total_tbs + total_header > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ) {
|
||||
LOG_W(EMU,"RX [UE %d] Total size of buffer is %d (header%d,tbs %d) \n",
|
||||
n_ue, total_header+total_tbs,total_header,total_tbs);
|
||||
}
|
||||
memcpy (&UE_transport_info[n_ue], UE_info, total_header+total_tbs);
|
||||
UE_info = (UE_transport_info_t *)((unsigned int)UE_info + total_header+
|
||||
total_tbs);
|
||||
bytes_read+=total_header+total_tbs;
|
||||
}
|
||||
#ifdef DEBUG_EMU
|
||||
for (n_enb=0; n_enb < UE_info[0].num_eNB; n_enb ++ )
|
||||
LOG_T(EMU,"dump ue transport info rnti %x enb_id %d, harq_id %d tbs %d\n",
|
||||
UE_transport_info[0].rnti[n_enb],
|
||||
UE_transport_info[0].eNB_id[n_enb],
|
||||
UE_transport_info[0].harq_pid[n_enb],
|
||||
UE_transport_info[0].tbs[n_enb]);
|
||||
#endif
|
||||
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
|
||||
n_ue < oai_emulation.info.master[messg->master_id].first_ue +
|
||||
oai_emulation.info.master[messg->master_id].nb_ue ;
|
||||
n_ue ++) {
|
||||
fill_phy_ue_vars(n_ue,last_slot);
|
||||
}
|
||||
} else {
|
||||
LOG_T(EMU,"WAIT_UE_TRANSPORT state: no UE transport info from master %d\n",
|
||||
messg->master_id);
|
||||
}
|
||||
|
||||
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
|
||||
if (Master_list_rx == oai_emulation.info.master_list) {
|
||||
emu_rx_status = SYNCED_TRANSPORT;
|
||||
}
|
||||
break;
|
||||
case EMU_TRANSPORT_INFO_RELEASE :
|
||||
Master_list_rx = oai_emulation.info.master_list;
|
||||
LOG_E(EMU, "RX EMU_TRANSPORT_INFO_RELEASE\n");
|
||||
break;
|
||||
default:
|
||||
LOG_E(EMU, "[MAC][BYPASS] ERROR RX UNKNOWN MESSAGE\n");
|
||||
//mac_xface->macphy_exit("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
num_bytesP=0;
|
||||
|
||||
#if !defined(ENABLE_NEW_MULTICAST)
|
||||
emul_low_mutex_var=1;
|
||||
|
||||
pthread_cond_signal(&emul_low_cond);
|
||||
pthread_mutex_unlock(&emul_low_mutex);
|
||||
#endif
|
||||
bypass_signal_mac_phy(frame,last_slot, next_slot, is_master);
|
||||
#if !defined(ENABLE_NEW_MULTICAST)
|
||||
}
|
||||
#endif
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
/******************************************************************************************************/
|
||||
#ifndef USER_MODE
|
||||
int bypass_rx_handler(unsigned int fifo, int rw)
|
||||
{
|
||||
/******************************************************************************************************/
|
||||
int bytes_read;
|
||||
int bytes_processed=0;
|
||||
int header_bytes; //, elapsed_time;
|
||||
//printk("[BYPASS] BYPASS_RX_HANDLER IN...\n");
|
||||
header_bytes= rtf_get(fifo_bypass_phy_user2kern, rx_bufferP,sizeof(bypass_proto2multicast_header_t) );
|
||||
header_bytes= rtf_get(fifo_bypass_phy_user2kern, rx_bufferP,
|
||||
sizeof(bypass_proto2multicast_header_t) );
|
||||
if (header_bytes> 0) {
|
||||
bytes_read = rtf_get(fifo_bypass_phy_user2kern, &rx_bufferP[header_bytes],((bypass_proto2multicast_header_t *) (&rx_bufferP[0]))->size);
|
||||
// printk("BYTES_READ=%d\n",bytes_read);
|
||||
if (bytes_read > 0) {
|
||||
num_bytesP=header_bytes+bytes_read;
|
||||
emul_low_mutex_var=0;
|
||||
//printk("BYPASS_PHY SIGNAL MAC_LOW...\n");
|
||||
pthread_cond_signal(&emul_low_cond);
|
||||
}
|
||||
bytes_read = rtf_get(fifo_bypass_phy_user2kern, &rx_bufferP[header_bytes],
|
||||
((bypass_proto2multicast_header_t *) (&rx_bufferP[0]))->size);
|
||||
// printk("BYTES_READ=%d\n",bytes_read);
|
||||
if (bytes_read > 0) {
|
||||
num_bytesP=header_bytes+bytes_read;
|
||||
emul_low_mutex_var=0;
|
||||
//printk("BYPASS_PHY SIGNAL MAC_LOW...\n");
|
||||
pthread_cond_signal(&emul_low_cond);
|
||||
}
|
||||
}
|
||||
// }
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
#else //USER_MODE
|
||||
/******************************************************************************************************/
|
||||
void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer){
|
||||
/******************************************************************************************************/
|
||||
// msg("[BYPASS] BYPASS RX_HANDLER IN ...\n");
|
||||
if(Num_bytes >0){
|
||||
pthread_mutex_lock(&emul_low_mutex);
|
||||
while(!emul_low_mutex_var){
|
||||
// msg("[BYPASS] BYPASS: WAIT MAC_LOW...\n");
|
||||
pthread_cond_wait(&emul_low_cond, &emul_low_mutex);
|
||||
/******************************************************************************************************/
|
||||
void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer)
|
||||
{
|
||||
/******************************************************************************************************/
|
||||
if(Num_bytes >0) {
|
||||
#if !defined(ENABLE_NEW_MULTICAST)
|
||||
pthread_mutex_lock(&emul_low_mutex);
|
||||
while(!emul_low_mutex_var) {
|
||||
pthread_cond_wait(&emul_low_cond, &emul_low_mutex);
|
||||
}
|
||||
#endif
|
||||
num_bytesP=Num_bytes;
|
||||
memcpy(rx_bufferP, Rx_buffer, Num_bytes);
|
||||
#if !defined(ENABLE_NEW_MULTICAST)
|
||||
emul_low_mutex_var=0;
|
||||
|
||||
/* on ne peut que signaler depuis un context linux
|
||||
* (rtf_handler); pas de wait, jamais!!!!!!
|
||||
*/
|
||||
pthread_cond_signal(&emul_low_cond);
|
||||
pthread_mutex_unlock(&emul_low_mutex);
|
||||
#endif
|
||||
}
|
||||
num_bytesP=Num_bytes;
|
||||
memcpy(rx_bufferP,Rx_buffer,Num_bytes);
|
||||
emul_low_mutex_var=0;
|
||||
//msg("[BYPASS] RX_HANDLER SIGNAL MAC_LOW\n");
|
||||
pthread_cond_signal(&emul_low_cond); //on ne peut que signaler depuis un context linux (rtf_handler); pas de wait, jamais!!!!!!
|
||||
pthread_mutex_unlock(&emul_low_mutex);
|
||||
}
|
||||
}
|
||||
#endif //USER_MODE
|
||||
|
||||
/******************************************************************************************************/
|
||||
void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot, unsigned int next_slot){
|
||||
/******************************************************************************************************/
|
||||
// char tt=1;
|
||||
|
||||
if(Master_list_rx != oai_emulation.info.master_list){
|
||||
/******************************************************************************************************/
|
||||
void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot,
|
||||
unsigned int next_slot, uint8_t is_master)
|
||||
{
|
||||
/******************************************************************************************************/
|
||||
if(Master_list_rx != oai_emulation.info.master_list) {
|
||||
#ifndef USER_MODE
|
||||
rtf_put(fifo_mac_bypass,&tt,1); // the Rx window is still opened (Re)signal bypass_phy (emulate MAC signal)
|
||||
#endif //USER_MODE
|
||||
bypass_rx_data(frame,last_slot, next_slot);
|
||||
}
|
||||
else Master_list_rx=0;
|
||||
rtf_put(fifo_mac_bypass, &tt, 1);
|
||||
/* the Rx window is still opened (Re)signal bypass_phy (emulate MAC signal) */
|
||||
#endif
|
||||
bypass_rx_data(frame, last_slot, next_slot, is_master);
|
||||
} else {
|
||||
Master_list_rx=0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USER_MODE
|
||||
/***************************************************************************/
|
||||
int multicast_link_write_sock (int groupP, char *dataP, unsigned int sizeP){
|
||||
int multicast_link_write_sock (int groupP, char *dataP, unsigned int sizeP)
|
||||
{
|
||||
/***************************************************************************/
|
||||
int tx_bytes=0;
|
||||
|
||||
pthread_mutex_lock(&Tx_mutex);
|
||||
while(!Tx_mutex_var){
|
||||
//msg("[BYPASS]RG WAIT USER_SPACE FIFO SIGNAL..\n");
|
||||
pthread_cond_wait(&Tx_cond,&Tx_mutex);
|
||||
}
|
||||
Tx_mutex_var=0;
|
||||
N_P=(int)((sizeP-sizeof (bypass_proto2multicast_header_t))/1000)+2;
|
||||
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],sizeof (bypass_proto2multicast_header_t));
|
||||
while(tx_bytes<sizeP){
|
||||
if(sizeP-tx_bytes<=1000)
|
||||
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],sizeP-tx_bytes);
|
||||
else
|
||||
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],1000);
|
||||
}
|
||||
//RG_tx_mutex_var=0;
|
||||
pthread_mutex_unlock(&Tx_mutex);
|
||||
|
||||
return tx_bytes;
|
||||
int tx_bytes=0;
|
||||
|
||||
pthread_mutex_lock(&Tx_mutex);
|
||||
while(!Tx_mutex_var) {
|
||||
pthread_cond_wait(&Tx_cond,&Tx_mutex);
|
||||
}
|
||||
Tx_mutex_var=0;
|
||||
N_P=(int)((sizeP-sizeof (bypass_proto2multicast_header_t))/1000)+2;
|
||||
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],
|
||||
sizeof (bypass_proto2multicast_header_t));
|
||||
while(tx_bytes<sizeP) {
|
||||
if(sizeP-tx_bytes<=1000) {
|
||||
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],
|
||||
sizeP-tx_bytes);
|
||||
} else {
|
||||
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],1000);
|
||||
}
|
||||
}
|
||||
//RG_tx_mutex_var=0;
|
||||
pthread_mutex_unlock(&Tx_mutex);
|
||||
|
||||
return tx_bytes;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
void bypass_tx_data(char Type, unsigned int frame, unsigned int next_slot){
|
||||
/***************************************************************************/
|
||||
unsigned int num_flows;
|
||||
bypass_msg_header_t *messg;
|
||||
unsigned int byte_tx_count;
|
||||
// eNB_transport_info_t *eNB_info;
|
||||
int n_enb,n_ue, n_dci,total_tbs=0,total_size=0;
|
||||
messg = (bypass_msg_header_t *) (&bypass_tx_buffer[sizeof (bypass_proto2multicast_header_t)]);
|
||||
num_flows = 0;
|
||||
messg->master_id = oai_emulation.info.master_id; //Master_id;
|
||||
// messg->nb_master = oai_emulation.info.nb_master;
|
||||
messg->nb_enb = oai_emulation.info.nb_enb_local; //Master_id;
|
||||
messg->nb_ue = oai_emulation.info.nb_ue_local; //Master_id;
|
||||
messg->nb_flow = num_flows;
|
||||
messg->frame = frame;
|
||||
messg->subframe = next_slot>>1;
|
||||
void bypass_tx_data(emu_transport_info_t Type, unsigned int frame, unsigned int next_slot)
|
||||
{
|
||||
/***************************************************************************/
|
||||
unsigned int num_flows;
|
||||
bypass_msg_header_t *messg;
|
||||
|
||||
byte_tx_count = sizeof (bypass_msg_header_t) + sizeof (bypass_proto2multicast_header_t);
|
||||
|
||||
if(Type==WAIT_PM_TRANSPORT){
|
||||
messg->Message_type = WAIT_PM_TRANSPORT_INFO;
|
||||
LOG_T(EMU,"[TX_DATA] WAIT SYNC PM TRANSPORT\n");
|
||||
}
|
||||
else if(Type==WAIT_SM_TRANSPORT){
|
||||
messg->Message_type = WAIT_SM_TRANSPORT_INFO;
|
||||
LOG_T(EMU,"[TX_DATA] WAIT SYNC SM TRANSPORT\n");
|
||||
}
|
||||
else if(Type==SYNC_TRANSPORT){
|
||||
messg->Message_type = SYNC_TRANSPORT_INFO;
|
||||
// make sure that sync messages from the masters are received in increasing order of master id
|
||||
sleep(oai_emulation.info.master_id+1);
|
||||
LOG_T(EMU,"[TX_DATA] SYNC TRANSPORT\n");
|
||||
}
|
||||
else if(Type==ENB_TRANSPORT){
|
||||
LOG_D(EMU,"[TX_DATA] ENB TRANSPORT\n");
|
||||
messg->Message_type = ENB_TRANSPORT_INFO;
|
||||
total_size=0;
|
||||
total_tbs=0;
|
||||
for (n_enb=oai_emulation.info.first_enb_local;n_enb<(oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local);n_enb++) {
|
||||
total_tbs=0;
|
||||
for (n_dci =0 ;
|
||||
n_dci < (eNB_transport_info[n_enb].num_ue_spec_dci+ eNB_transport_info[n_enb].num_common_dci);
|
||||
n_dci++) {
|
||||
total_tbs +=eNB_transport_info[n_enb].tbs[n_dci];
|
||||
}
|
||||
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE)
|
||||
total_size = sizeof(eNB_transport_info_t)+total_tbs-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
else
|
||||
LOG_E(EMU,"[eNB]running out of memory for the eNB emulation transport buffer of size %d\n", MAX_TRANSPORT_BLOCKS_BUFFER_SIZE);
|
||||
memcpy(&bypass_tx_buffer[byte_tx_count], (char*)&eNB_transport_info[n_enb], total_size);
|
||||
byte_tx_count +=total_size;
|
||||
}
|
||||
}
|
||||
else if (Type == UE_TRANSPORT){
|
||||
LOG_D(EMU,"[TX_DATA] UE TRANSPORT\n");
|
||||
messg->Message_type = UE_TRANSPORT_INFO;
|
||||
total_size=0;
|
||||
total_tbs=0; // compute the actual size of transport_blocks
|
||||
for (n_ue = oai_emulation.info.first_ue_local; n_ue < (oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local);n_ue++){
|
||||
for (n_enb=0;n_enb<UE_transport_info[n_ue].num_eNB;n_enb++) {
|
||||
total_tbs+=UE_transport_info[n_ue].tbs[n_enb];
|
||||
}
|
||||
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE)
|
||||
total_size = sizeof(UE_transport_info_t)+total_tbs-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
else
|
||||
LOG_E(EMU,"[UE]running out of memory for the UE emulation transport buffer of size %d\n", MAX_TRANSPORT_BLOCKS_BUFFER_SIZE);
|
||||
memcpy(&bypass_tx_buffer[byte_tx_count], (char*)&UE_transport_info[n_ue], total_size);
|
||||
byte_tx_count +=total_size;
|
||||
LOG_D(EMU, "Entering bypass_tx [%s] for frame %d next_slot %d\n",
|
||||
map_int_to_str(transport_names, Type), frame, next_slot);
|
||||
|
||||
int n_enb,n_ue, n_dci,total_tbs=0,total_size=0;
|
||||
messg = (bypass_msg_header_t *) (
|
||||
&bypass_tx_buffer[sizeof (bypass_proto2multicast_header_t)]);
|
||||
num_flows = 0;
|
||||
messg->master_id = oai_emulation.info.master_id; //Master_id;
|
||||
|
||||
messg->nb_enb = oai_emulation.info.nb_enb_local; //Master_id;
|
||||
messg->nb_ue = oai_emulation.info.nb_ue_local; //Master_id;
|
||||
messg->nb_flow = num_flows;
|
||||
messg->frame = frame;
|
||||
messg->subframe = next_slot>>1;
|
||||
messg->seq_num = seq_num_tx;
|
||||
|
||||
seq_num_tx++;
|
||||
|
||||
byte_tx_count = sizeof (bypass_msg_header_t) + sizeof (
|
||||
bypass_proto2multicast_header_t);
|
||||
|
||||
if (Type == WAIT_PM_TRANSPORT) {
|
||||
messg->Message_type = EMU_TRANSPORT_INFO_WAIT_PM;
|
||||
LOG_T(EMU,"[TX_DATA] WAIT SYNC PM TRANSPORT\n");
|
||||
} else if (Type == WAIT_SM_TRANSPORT) {
|
||||
messg->Message_type = EMU_TRANSPORT_INFO_WAIT_SM;
|
||||
LOG_T(EMU,"[TX_DATA] WAIT SYNC SM TRANSPORT\n");
|
||||
} else if (Type == SYNC_TRANSPORT) {
|
||||
messg->Message_type = EMU_TRANSPORT_INFO_SYNC;
|
||||
/* make sure that sync messages from the masters are received in
|
||||
* increasing order of master id
|
||||
*/
|
||||
sleep(oai_emulation.info.master_id+1);
|
||||
LOG_T(EMU,"[TX_DATA] SYNC TRANSPORT\n");
|
||||
} else if(Type==ENB_TRANSPORT) {
|
||||
LOG_D(EMU,"[TX_DATA] ENB TRANSPORT\n");
|
||||
messg->Message_type = EMU_TRANSPORT_INFO_ENB;
|
||||
total_size=0;
|
||||
total_tbs=0;
|
||||
for (n_enb=oai_emulation.info.first_enb_local;
|
||||
n_enb<(oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local);
|
||||
n_enb++) {
|
||||
total_tbs=0;
|
||||
for (n_dci =0 ;
|
||||
n_dci < (eNB_transport_info[n_enb].num_ue_spec_dci+
|
||||
eNB_transport_info[n_enb].num_common_dci);
|
||||
n_dci++) {
|
||||
total_tbs +=eNB_transport_info[n_enb].tbs[n_dci];
|
||||
}
|
||||
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) {
|
||||
total_size = sizeof(eNB_transport_info_t)+total_tbs-
|
||||
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
} else {
|
||||
LOG_E(EMU,
|
||||
"[eNB]running out of memory for the eNB emulation transport buffer of size %d\n",
|
||||
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE);
|
||||
}
|
||||
memcpy(&bypass_tx_buffer[byte_tx_count], (char *)&eNB_transport_info[n_enb],
|
||||
total_size);
|
||||
byte_tx_count +=total_size;
|
||||
}
|
||||
} else if (Type == UE_TRANSPORT) {
|
||||
LOG_D(EMU,"[TX_DATA] UE TRANSPORT\n");
|
||||
messg->Message_type = EMU_TRANSPORT_INFO_UE;
|
||||
total_size=0;
|
||||
total_tbs=0; // compute the actual size of transport_blocks
|
||||
for (n_ue = oai_emulation.info.first_ue_local;
|
||||
n_ue < (oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local);
|
||||
n_ue++) {
|
||||
for (n_enb=0; n_enb<UE_transport_info[n_ue].num_eNB; n_enb++) {
|
||||
total_tbs+=UE_transport_info[n_ue].tbs[n_enb];
|
||||
}
|
||||
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) {
|
||||
total_size = sizeof(UE_transport_info_t)+total_tbs-
|
||||
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
|
||||
} else {
|
||||
LOG_E(EMU,
|
||||
"[UE]running out of memory for the UE emulation transport buffer of size %d\n",
|
||||
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE);
|
||||
}
|
||||
memcpy(&bypass_tx_buffer[byte_tx_count], (char *)&UE_transport_info[n_ue],
|
||||
total_size);
|
||||
byte_tx_count +=total_size;
|
||||
}
|
||||
} else if (Type == RELEASE_TRANSPORT) {
|
||||
messg->Message_type = EMU_TRANSPORT_INFO_RELEASE;
|
||||
} else {
|
||||
LOG_E(EMU,"[TX_DATA] UNKNOWN MSG \n");
|
||||
}
|
||||
}
|
||||
else if (Type == RELEASE_TRANSPORT){
|
||||
messg->Message_type = RELEASE_TRANSPORT_INFO;
|
||||
}else {
|
||||
LOG_T(EMU,"[TX_DATA] UNKNOWN MSG \n");
|
||||
}
|
||||
|
||||
((bypass_proto2multicast_header_t *) bypass_tx_buffer)->size = byte_tx_count - sizeof (bypass_proto2multicast_header_t);
|
||||
//if(mac_xface->frame%1000==0)
|
||||
multicast_link_write_sock (oai_emulation.info.multicast_group, bypass_tx_buffer, byte_tx_count);
|
||||
((bypass_proto2multicast_header_t *) bypass_tx_buffer)->size = byte_tx_count -
|
||||
sizeof (bypass_proto2multicast_header_t);
|
||||
|
||||
multicast_link_write_sock (oai_emulation.info.multicast_group,
|
||||
bypass_tx_buffer, byte_tx_count);
|
||||
|
||||
LOG_D(EMU, "Sent %d bytes [%s] with master_id %d and seq %"PRIuMAX"\n",
|
||||
byte_tx_count, map_int_to_str(transport_names, Type),
|
||||
messg->master_id, messg->seq_num);
|
||||
}
|
||||
|
||||
#ifndef USER_MODE
|
||||
#ifndef USER_MODE
|
||||
/*********************************************************************************************************************/
|
||||
int bypass_tx_handler(unsigned int fifo, int rw){
|
||||
/***************************************************************************/
|
||||
// if(rw=='r'){
|
||||
if(++N_R==N_P){
|
||||
//msg("[OPENAIR][RG_BYPASS] TX_handler..\n");
|
||||
// pthread_mutex_lock(&RG_tx_mutex);
|
||||
rtf_reset(fifo_bypass_phy_kern2user);
|
||||
// pthread_mutex_lock(&RG_tx_mutex);
|
||||
Tx_mutex_var=1;
|
||||
N_R=0;
|
||||
// pthread_mutex_unlock(&RG_tx_mutex);
|
||||
pthread_cond_signal(&Tx_cond);
|
||||
int bypass_tx_handler(unsigned int fifo, int rw)
|
||||
{
|
||||
/***************************************************************************/
|
||||
if(++N_R==N_P) {
|
||||
rtf_reset(fifo_bypass_phy_kern2user);
|
||||
|
||||
Tx_mutex_var=1;
|
||||
N_R=0;
|
||||
|
||||
pthread_cond_signal(&Tx_cond);
|
||||
}
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
/*! \file phy_emulation.h
|
||||
* \brief specifies the data structure and variable for phy emulation
|
||||
* \author Navid Nikaein, Raymomd Knopp and Hicham Anouar
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
|
||||
|
||||
//#include "SCHED/defs.h"
|
||||
#include "proto.h"
|
||||
//#include "UTIL/OCG/OCG.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"
|
||||
|
||||
#define WAIT_PM_TRANSPORT_INFO 0x1
|
||||
#define WAIT_SM_TRANSPORT_INFO 0x2
|
||||
#define SYNC_TRANSPORT_INFO 0x3
|
||||
#define ENB_TRANSPORT_INFO 0X4
|
||||
#define UE_TRANSPORT_INFO 0X5
|
||||
#define RELEASE_TRANSPORT_INFO 0x6
|
||||
typedef enum {
|
||||
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
|
||||
@@ -41,10 +38,11 @@
|
||||
#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 {
|
||||
u32 pbch_flag:1;
|
||||
u32 pss:2;
|
||||
@@ -71,8 +69,10 @@ typedef struct {
|
||||
u8 prach_flag:1; // 0=none,1=active
|
||||
u8 prach_id:6; // this is the PHY preamble index for the prach
|
||||
} UE_cntl;
|
||||
|
||||
#define MAX_TRANSPORT_BLOCKS_BUFFER_SIZE 16384
|
||||
#define MAX_NUM_DCI 5
|
||||
|
||||
typedef struct {
|
||||
eNB_cntl cntl;
|
||||
u8 num_common_dci;
|
||||
@@ -85,15 +85,6 @@ typedef struct {
|
||||
u8 transport_blocks[MAX_TRANSPORT_BLOCKS_BUFFER_SIZE];
|
||||
} __attribute__ ((__packed__)) eNB_transport_info_t ;
|
||||
|
||||
/*typedef struct {
|
||||
eNB_cntl cntl;
|
||||
u8 num_common_dci;
|
||||
u8 num_ue_spec_dci;
|
||||
DCI_ALLOC_t dci_alloc;
|
||||
u8 dlsch_info[6*MAX_NUM_DCI + MAX_TRANSPORT_BLOCKS_BUFFER_SIZE];
|
||||
} eNB_transport_info_rx_t ;
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
UE_cntl cntl;
|
||||
u8 num_eNB;
|
||||
@@ -113,54 +104,12 @@ typedef struct bypass_msg_header {
|
||||
unsigned int nb_ue; /*! \brief */
|
||||
unsigned int nb_flow; /*! \brief */
|
||||
unsigned int frame;
|
||||
unsigned int subframe;
|
||||
unsigned int subframe;
|
||||
uint64_t seq_num;
|
||||
}__attribute__ ((__packed__)) bypass_msg_header_t;
|
||||
|
||||
typedef struct bypass_proto2multicast_header_t {
|
||||
unsigned int size;
|
||||
} bypass_proto2multicast_header_t;
|
||||
|
||||
|
||||
/* // replaced to OCG.h
|
||||
#define NUMBER_OF_MASTER_MAX 20
|
||||
//#define NUMBER_OF_UE_MAX 32
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char nb_ue;
|
||||
unsigned char first_ue;
|
||||
unsigned char nb_enb;
|
||||
unsigned char first_enb;
|
||||
}master_info_t;
|
||||
|
||||
typedef struct {
|
||||
master_info_t master[NUMBER_OF_MASTER_MAX];
|
||||
unsigned char nb_ue_local;
|
||||
unsigned char nb_ue_remote;
|
||||
unsigned char nb_enb_local;
|
||||
unsigned char nb_enb_remote;
|
||||
unsigned char first_enb_local;
|
||||
unsigned char first_ue_local;
|
||||
unsigned short master_id;
|
||||
unsigned char nb_master;
|
||||
unsigned int master_list;
|
||||
unsigned int is_primary_master;
|
||||
unsigned int ethernet_flag;
|
||||
char local_server[128]; // for the oaisim -c option : 0 = EURECOM web portal; -1 = local; 1 - N or filename = running a specific XML configuration file
|
||||
unsigned int offset_ue_inst;
|
||||
unsigned char multicast_group;
|
||||
unsigned char ocg_enabled;
|
||||
unsigned char opt_enabled;
|
||||
unsigned char otg_enabled;
|
||||
unsigned char omg_model_enb;
|
||||
unsigned char omg_model_ue;
|
||||
unsigned int seed;
|
||||
double time;
|
||||
|
||||
}emu_info_t;
|
||||
*/
|
||||
|
||||
|
||||
#endif //
|
||||
|
||||
|
||||
#endif /* __BYPASS_SESSION_LAYER_DEFS_H__ */
|
||||
|
||||
@@ -1,397 +1,441 @@
|
||||
/*! \file phy_emulation.c
|
||||
* \brief implements the underlying protocol for emulated data exchange over Ethernet using IP multicast
|
||||
* \author Navid Nikaein
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
* \brief implements the underlying protocol for emulated data exchange over Ethernet using IP multicast
|
||||
* \author Navid Nikaein
|
||||
* \date 2011
|
||||
* \version 1.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
|
||||
|
||||
#include "PHY/defs.h"
|
||||
#include "PHY/extern.h"
|
||||
#include "defs.h"
|
||||
#include "extern.h"
|
||||
#include "proto.h"
|
||||
#include "UTIL/OCG/OCG.h"
|
||||
#include "UTIL/OCG/OCG_extern.h"
|
||||
#include "UTIL/LOG/log.h"
|
||||
#include "UTIL/LOG/vcd_signal_dumper.h"
|
||||
|
||||
extern unsigned int Master_list_rx;
|
||||
//extern unsigned short NODE_ID[1];
|
||||
extern unsigned char NB_INST;
|
||||
extern unsigned int Master_list_rx;
|
||||
|
||||
extern unsigned char NB_INST;
|
||||
//#define DEBUG_CONTROL 1
|
||||
//#define DEBUG_EMU 1
|
||||
/*
|
||||
char is_node_local_neighbor(unsigned short Node_id){
|
||||
int i;
|
||||
for(i=0;i<NB_INST;i++)
|
||||
if(NODE_ID[i]==Node_id) return 1;
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
void emu_transport_sync(void){
|
||||
|
||||
if (oai_emulation.info.is_primary_master==0){
|
||||
void emu_transport_sync(void)
|
||||
{
|
||||
LOG_D(EMU, "Entering EMU transport SYNC is primary master %d\n",
|
||||
oai_emulation.info.is_primary_master);
|
||||
|
||||
bypass_tx_data(WAIT_SM_TRANSPORT,0,0);
|
||||
Master_list_rx=oai_emulation.info.master_list-1; // just wait to recieve the master 0 msg
|
||||
bypass_rx_data(0,0,0);
|
||||
}
|
||||
else {
|
||||
bypass_rx_data(0,0,0);
|
||||
bypass_tx_data(WAIT_PM_TRANSPORT,0,0);
|
||||
}
|
||||
|
||||
if (oai_emulation.info.master_list!=0){
|
||||
|
||||
bypass_tx_data(SYNC_TRANSPORT,0,0);
|
||||
bypass_rx_data(0,0,0);
|
||||
|
||||
if (emu_rx_status == SYNCED_TRANSPORT){ // i received the sync from all secondary masters
|
||||
emu_tx_status = SYNCED_TRANSPORT;
|
||||
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);
|
||||
}
|
||||
// else emu_transport_sync(last_slot);
|
||||
LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 (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;
|
||||
}
|
||||
|
||||
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);
|
||||
// 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");
|
||||
}
|
||||
// UL
|
||||
if ( ((frame_type == 1) && (direction == SF_UL)) || (frame_type == 0) ){
|
||||
emu_transport_UL(frame, last_slot , next_slot);
|
||||
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_OUT);
|
||||
|
||||
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) {
|
||||
|
||||
if (oai_emulation.info.is_primary_master==0){
|
||||
// bypass_rx_data(last_slot);
|
||||
if (oai_emulation.info.nb_enb_local>0) // send in DL if
|
||||
bypass_tx_data(ENB_TRANSPORT,frame, next_slot);
|
||||
else
|
||||
bypass_tx_data(WAIT_SM_TRANSPORT,frame,next_slot);
|
||||
|
||||
bypass_rx_data(frame, last_slot, next_slot);
|
||||
}
|
||||
else { // I am the master
|
||||
// bypass_tx_data(WAIT_TRANSPORT,last_slot);
|
||||
|
||||
if (oai_emulation.info.nb_enb_local>0) // send in DL if
|
||||
bypass_tx_data(ENB_TRANSPORT,frame, next_slot);
|
||||
else
|
||||
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
|
||||
|
||||
bypass_rx_data(frame,last_slot, next_slot);
|
||||
}
|
||||
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) {
|
||||
// bypass_rx_data(last_slot);
|
||||
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 { // I am the master
|
||||
// bypass_tx_data(WAIT_TRANSPORT,last_slot);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
||||
|
||||
if (oai_emulation.info.is_primary_master==0){
|
||||
// bypass_rx_data(last_slot, next_slot);
|
||||
if (oai_emulation.info.nb_ue_local>0)
|
||||
bypass_tx_data(UE_TRANSPORT,frame, next_slot);
|
||||
else
|
||||
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
|
||||
|
||||
bypass_rx_data(frame,last_slot, next_slot);
|
||||
}
|
||||
else {
|
||||
// bypass_tx_data(WAIT_TRANSPORT,last_slot);
|
||||
if (oai_emulation.info.nb_ue_local>0)
|
||||
bypass_tx_data(UE_TRANSPORT,frame, next_slot);
|
||||
else
|
||||
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
|
||||
|
||||
bypass_rx_data(frame,last_slot, next_slot);
|
||||
}
|
||||
|
||||
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) {
|
||||
// bypass_rx_data(last_slot, next_slot);
|
||||
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 {
|
||||
// bypass_tx_data(WAIT_TRANSPORT,last_slot);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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){
|
||||
unsigned short k,Mod_id;
|
||||
|
||||
for(k=0;k<NB_INST;k++){//Nb_out_src[Mode];k++){
|
||||
Mod_id=k;//Out_list[Mode][k];
|
||||
}
|
||||
return *Nbytes;
|
||||
void emu_transport_release(void)
|
||||
{
|
||||
bypass_tx_data(RELEASE_TRANSPORT,0,0);
|
||||
LOG_E(EMU," tx RELEASE_TRANSPORT \n");
|
||||
}
|
||||
|
||||
unsigned int emul_rx_data(void){
|
||||
return(0);
|
||||
unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,
|
||||
unsigned int *Nbytes,unsigned int *Nb_flows)
|
||||
{
|
||||
|
||||
return *Nbytes;
|
||||
}
|
||||
|
||||
unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer, unsigned int Nbytes){
|
||||
unsigned short Rx_size=0;
|
||||
return (Rx_size+2);
|
||||
unsigned int emul_rx_data(void)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
void clear_eNB_transport_info(u8 nb_eNB) {
|
||||
u8 eNB_id;
|
||||
|
||||
for (eNB_id=0;eNB_id<nb_eNB;eNB_id++) {
|
||||
eNB_transport_info_TB_index[eNB_id]=0;
|
||||
memset((void *)&eNB_transport_info[eNB_id].cntl,0,sizeof(eNB_cntl));
|
||||
eNB_transport_info[eNB_id].num_common_dci=0;
|
||||
eNB_transport_info[eNB_id].num_ue_spec_dci=0;
|
||||
}
|
||||
// LOG_T(EMU, "EMUL clear_eNB_transport_info\n");
|
||||
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_UE_transport_info(u8 nb_UE) {
|
||||
u8 UE_id;
|
||||
|
||||
for (UE_id=0;UE_id<nb_UE;UE_id++) {
|
||||
UE_transport_info_TB_index[UE_id]=0;
|
||||
memset((void *)&UE_transport_info[UE_id].cntl,0,sizeof(UE_cntl));
|
||||
}
|
||||
// LOG_T(EMU, "EMUL clear_UE_transport_info\n");
|
||||
void clear_eNB_transport_info(u8 nb_eNB)
|
||||
{
|
||||
u8 eNB_id;
|
||||
|
||||
for (eNB_id=0; eNB_id<nb_eNB; eNB_id++) {
|
||||
eNB_transport_info_TB_index[eNB_id]=0;
|
||||
memset((void *)&eNB_transport_info[eNB_id].cntl,0,sizeof(eNB_cntl));
|
||||
eNB_transport_info[eNB_id].num_common_dci=0;
|
||||
eNB_transport_info[eNB_id].num_ue_spec_dci=0;
|
||||
}
|
||||
// LOG_T(EMU, "EMUL clear_eNB_transport_info\n");
|
||||
}
|
||||
|
||||
void clear_UE_transport_info(u8 nb_UE)
|
||||
{
|
||||
u8 UE_id;
|
||||
|
||||
void fill_phy_enb_vars(unsigned int enb_id, unsigned int next_slot) {
|
||||
for (UE_id=0; UE_id<nb_UE; UE_id++) {
|
||||
UE_transport_info_TB_index[UE_id]=0;
|
||||
memset((void *)&UE_transport_info[UE_id].cntl,0,sizeof(UE_cntl));
|
||||
}
|
||||
// LOG_T(EMU, "EMUL clear_UE_transport_info\n");
|
||||
}
|
||||
|
||||
void fill_phy_enb_vars(unsigned int enb_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;
|
||||
u8 nb_total_dci;
|
||||
|
||||
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;
|
||||
u8 nb_total_dci;
|
||||
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU," pbch fill phy eNB %d vars for slot %d \n",enb_id, next_slot);
|
||||
#endif
|
||||
// eNB
|
||||
// PBCH : copy payload
|
||||
|
||||
//if (next_slot == 2){
|
||||
*(u32*)PHY_vars_eNB_g[enb_id]->pbch_pdu = eNB_transport_info[enb_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].cntl.pbch_payload,
|
||||
((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[0],
|
||||
((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[1]);
|
||||
LOG_D(EMU, " pbch fill phy eNB %d vars for slot %d fault %d\n",
|
||||
enb_id, next_slot, network_fault);
|
||||
#endif
|
||||
// eNB
|
||||
// PBCH : copy payload
|
||||
|
||||
*(u32 *)PHY_vars_eNB_g[enb_id]->pbch_pdu =
|
||||
eNB_transport_info[enb_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].cntl.pbch_payload,
|
||||
((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[0],
|
||||
((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[1]);
|
||||
*/
|
||||
// }
|
||||
//CFI
|
||||
// not needed yet
|
||||
|
||||
//PHICH
|
||||
// to be added later
|
||||
//CFI
|
||||
// not needed yet
|
||||
|
||||
//DCI
|
||||
nb_total_dci= eNB_transport_info[enb_id].num_ue_spec_dci+ eNB_transport_info[enb_id].num_common_dci;
|
||||
PHY_vars_eNB_g[enb_id]->num_ue_spec_dci[(next_slot>>1)&1] = eNB_transport_info[enb_id].num_ue_spec_dci;
|
||||
PHY_vars_eNB_g[enb_id]->num_common_dci[(next_slot>>1)&1] = eNB_transport_info[enb_id].num_common_dci;
|
||||
//PHICH
|
||||
// to be added later
|
||||
|
||||
if (nb_total_dci >0) {
|
||||
|
||||
memcpy(PHY_vars_eNB_g[enb_id]->dci_alloc[(next_slot>>1)&1],
|
||||
&eNB_transport_info[enb_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++) {
|
||||
|
||||
if (eNB_transport_info[enb_id].dci_alloc[n_dci_dl].format > 0){ //exclude ul dci
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU, "dci spec %d common %d tbs is %d payload offset %d\n",
|
||||
eNB_transport_info[enb_id].num_ue_spec_dci,
|
||||
eNB_transport_info[enb_id].num_common_dci,
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl],
|
||||
payload_offset);
|
||||
#endif
|
||||
switch (eNB_transport_info[enb_id].dlsch_type[n_dci_dl]) {
|
||||
|
||||
case 0: //SI:
|
||||
|
||||
memcpy(PHY_vars_eNB_g[enb_id]->dlsch_eNB_SI->harq_processes[0]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
//DCI
|
||||
nb_total_dci= eNB_transport_info[enb_id].num_ue_spec_dci+
|
||||
eNB_transport_info[enb_id].num_common_dci;
|
||||
PHY_vars_eNB_g[enb_id]->num_ue_spec_dci[(next_slot>>1)&1] =
|
||||
eNB_transport_info[enb_id].num_ue_spec_dci;
|
||||
PHY_vars_eNB_g[enb_id]->num_common_dci[(next_slot>>1)&1] =
|
||||
eNB_transport_info[enb_id].num_common_dci;
|
||||
|
||||
if (nb_total_dci >0) {
|
||||
|
||||
memcpy(PHY_vars_eNB_g[enb_id]->dci_alloc[(next_slot>>1)&1],
|
||||
&eNB_transport_info[enb_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].dci_alloc[n_dci_dl].format > 0) {
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU, "SI eNB_transport_info[enb_id].tbs[n_dci_dl]%d \n", eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
LOG_D(EMU, "dci spec %d common %d tbs is %d payload offset %d\n",
|
||||
eNB_transport_info[enb_id].num_ue_spec_dci,
|
||||
eNB_transport_info[enb_id].num_common_dci,
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl],
|
||||
payload_offset);
|
||||
#endif
|
||||
break;
|
||||
case 1: //RA:
|
||||
|
||||
memcpy(PHY_vars_eNB_g[enb_id]->dlsch_eNB_ra->harq_processes[0]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
switch (eNB_transport_info[enb_id].dlsch_type[n_dci_dl]) {
|
||||
case 0: //SI:
|
||||
memcpy(PHY_vars_eNB_g[enb_id]->dlsch_eNB_SI->harq_processes[0]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU, "RA eNB_transport_info[enb_id].tbs[n_dci_dl]%d \n", eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
LOG_D(EMU, "SI eNB_transport_info[enb_id].tbs[n_dci_dl]%d \n",
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 2://TB0:
|
||||
harq_pid = eNB_transport_info[enb_id].harq_pid[n_dci_dl];
|
||||
ue_id = eNB_transport_info[enb_id].ue_id[n_dci_dl];
|
||||
PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][0]->rnti= eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti;
|
||||
dlsch_eNB = PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][0];
|
||||
break;
|
||||
case 1: //RA:
|
||||
|
||||
memcpy(PHY_vars_eNB_g[enb_id]->dlsch_eNB_ra->harq_processes[0]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
#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].dci_alloc[n_dci_dl].rnti,
|
||||
n_dci_dl, harq_pid, eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
int i;
|
||||
for (i=0;i<eNB_transport_info[enb_id].tbs[n_dci_dl];i++)
|
||||
msg("%x.",(unsigned char) eNB_transport_info[enb_id].transport_blocks[payload_offset+i]);
|
||||
#endif
|
||||
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
break;
|
||||
|
||||
case 3://TB1:
|
||||
harq_pid = eNB_transport_info[enb_id].harq_pid[n_dci_dl];
|
||||
ue_id = eNB_transport_info[enb_id].ue_id[n_dci_dl];
|
||||
PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][1]->rnti= eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti;
|
||||
dlsch_eNB = PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][1];
|
||||
|
||||
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
break;
|
||||
|
||||
}
|
||||
payload_offset += eNB_transport_info[enb_id].tbs[n_dci_dl];
|
||||
}
|
||||
n_dci_dl++;
|
||||
LOG_D(EMU, "RA eNB_transport_info[enb_id].tbs[n_dci_dl]%d \n",
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
#endif
|
||||
break;
|
||||
case 2://TB0:
|
||||
harq_pid = eNB_transport_info[enb_id].harq_pid[n_dci_dl];
|
||||
ue_id = eNB_transport_info[enb_id].ue_id[n_dci_dl];
|
||||
PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][0]->rnti=
|
||||
eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti;
|
||||
dlsch_eNB = PHY_vars_eNB_g[enb_id]->dlsch_eNB[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].dci_alloc[n_dci_dl].rnti,
|
||||
n_dci_dl, harq_pid, eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
int i;
|
||||
for (i=0; i<eNB_transport_info[enb_id].tbs[n_dci_dl]; i++) {
|
||||
LOG_T(EMU, "%x.",
|
||||
(unsigned char) eNB_transport_info[enb_id].transport_blocks[payload_offset+i]);
|
||||
}
|
||||
#endif
|
||||
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
break;
|
||||
case 3://TB1:
|
||||
harq_pid = eNB_transport_info[enb_id].harq_pid[n_dci_dl];
|
||||
ue_id = eNB_transport_info[enb_id].ue_id[n_dci_dl];
|
||||
PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][1]->rnti=
|
||||
eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti;
|
||||
dlsch_eNB = PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][1];
|
||||
|
||||
memcpy(dlsch_eNB->harq_processes[harq_pid]->b,
|
||||
&eNB_transport_info[enb_id].transport_blocks[payload_offset],
|
||||
eNB_transport_info[enb_id].tbs[n_dci_dl]);
|
||||
break;
|
||||
|
||||
}
|
||||
payload_offset += eNB_transport_info[enb_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, 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;
|
||||
// u8 ue_transport_info_index[NUMBER_OF_eNB_MAX];
|
||||
u8 subframe = (last_slot+1)>>1;
|
||||
|
||||
memcpy (&ue_cntl_delay[ue_id][(last_slot+1)%2],
|
||||
&UE_transport_info[ue_id].cntl,
|
||||
sizeof(UE_cntl));
|
||||
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU,
|
||||
"Last slot %d subframe %d Fill phy UE %d vars PRACH is (%d,%d) preamble (%d,%d) SR (%d,%d), pucch_sel (%d, %d)\n",
|
||||
|
||||
last_slot,subframe,ue_id,
|
||||
UE_transport_info[ue_id].cntl.prach_flag,
|
||||
ue_cntl_delay[ue_id][last_slot%2].prach_flag,
|
||||
UE_transport_info[ue_id].cntl.prach_id,
|
||||
ue_cntl_delay[ue_id][last_slot%2].prach_id,
|
||||
UE_transport_info[ue_id].cntl.sr,
|
||||
ue_cntl_delay[ue_id][last_slot%2].sr,
|
||||
UE_transport_info[ue_id].cntl.pucch_sel,
|
||||
ue_cntl_delay[ue_id][last_slot%2].pucch_sel );
|
||||
#endif
|
||||
//ue_cntl_delay[subframe%2].prach_flag ;
|
||||
PHY_vars_UE_g[ue_id]->generate_prach =
|
||||
ue_cntl_delay[ue_id][last_slot%2].prach_flag;//UE_transport_info[ue_id].cntl.prach_flag;
|
||||
if (PHY_vars_UE_g[ue_id]->generate_prach == 1) {
|
||||
// if (PHY_vars_UE_g[ue_id]->prach_resources[enb_id] == NULL)
|
||||
// PHY_vars_UE_g[ue_id]->prach_resources[enb_id] = malloc(sizeof(PRACH_RESOURCES_t));
|
||||
//ue_cntl_delay[subframe%2].prach_id;
|
||||
PHY_vars_UE_g[ue_id]->prach_PreambleIndex =
|
||||
ue_cntl_delay[ue_id][last_slot%2].prach_id;
|
||||
}
|
||||
|
||||
pucch_format=
|
||||
ue_cntl_delay[ue_id][last_slot%2].pucch_flag;// UE_transport_info[ue_id].cntl.pucch_flag;
|
||||
if ((last_slot+1) % 2 == 0 ) {
|
||||
if (pucch_format == pucch_format1) { // UE_transport_info[ue_id].cntl.sr;
|
||||
PHY_vars_UE_g[ue_id]->sr[subframe] = ue_cntl_delay[ue_id][last_slot%2].sr;
|
||||
} else if ((pucch_format == pucch_format1a)
|
||||
|| (pucch_format == pucch_format1b )) {
|
||||
PHY_vars_UE_g[ue_id]->pucch_payload[0] =
|
||||
ue_cntl_delay[ue_id][last_slot%2].pucch_payload;//UE_transport_info[ue_id].cntl.pucch_payload;
|
||||
}
|
||||
PHY_vars_UE_g[ue_id]->pucch_sel[subframe] =
|
||||
ue_cntl_delay[ue_id][last_slot%2].pucch_sel;
|
||||
}
|
||||
#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, 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;
|
||||
// u8 ue_transport_info_index[NUMBER_OF_eNB_MAX];
|
||||
u8 subframe = (last_slot+1)>>1;
|
||||
|
||||
memcpy (&ue_cntl_delay[ue_id][(last_slot+1)%2],
|
||||
&UE_transport_info[ue_id].cntl,
|
||||
sizeof(UE_cntl));
|
||||
|
||||
LOG_D(EMU,"subframe %d trying to copy the payload from num eNB %d to UE %d \n",
|
||||
subframe, UE_transport_info[ue_id].num_eNB, ue_id);
|
||||
#endif
|
||||
for (n_enb=0; n_enb < UE_transport_info[ue_id].num_eNB; n_enb++) {
|
||||
#ifdef DEBUG_EMU
|
||||
LOG_D(EMU, "Last slot %d subframe %d Fill phy UE %d vars PRACH is (%d,%d) preamble (%d,%d) SR (%d,%d), pucch_sel (%d, %d)\n",
|
||||
last_slot,subframe,ue_id,
|
||||
UE_transport_info[ue_id].cntl.prach_flag,
|
||||
ue_cntl_delay[ue_id][last_slot%2].prach_flag,
|
||||
UE_transport_info[ue_id].cntl.prach_id,
|
||||
ue_cntl_delay[ue_id][last_slot%2].prach_id,
|
||||
UE_transport_info[ue_id].cntl.sr,
|
||||
ue_cntl_delay[ue_id][last_slot%2].sr,
|
||||
UE_transport_info[ue_id].cntl.pucch_sel,
|
||||
ue_cntl_delay[ue_id][last_slot%2].pucch_sel );
|
||||
#endif
|
||||
//ue_cntl_delay[subframe%2].prach_flag ;
|
||||
PHY_vars_UE_g[ue_id]->generate_prach = ue_cntl_delay[ue_id][last_slot%2].prach_flag;//UE_transport_info[ue_id].cntl.prach_flag;
|
||||
if (PHY_vars_UE_g[ue_id]->generate_prach == 1) {
|
||||
// if (PHY_vars_UE_g[ue_id]->prach_resources[enb_id] == NULL)
|
||||
// PHY_vars_UE_g[ue_id]->prach_resources[enb_id] = malloc(sizeof(PRACH_RESOURCES_t));
|
||||
//ue_cntl_delay[subframe%2].prach_id;
|
||||
PHY_vars_UE_g[ue_id]->prach_PreambleIndex = ue_cntl_delay[ue_id][last_slot%2].prach_id;
|
||||
}
|
||||
|
||||
pucch_format= ue_cntl_delay[ue_id][last_slot%2].pucch_flag;// UE_transport_info[ue_id].cntl.pucch_flag;
|
||||
if ((last_slot+1) % 2 == 0 ) {
|
||||
if (pucch_format == pucch_format1) // UE_transport_info[ue_id].cntl.sr;
|
||||
PHY_vars_UE_g[ue_id]->sr[subframe] = ue_cntl_delay[ue_id][last_slot%2].sr;
|
||||
else if ((pucch_format == pucch_format1a) || (pucch_format == pucch_format1b )){
|
||||
PHY_vars_UE_g[ue_id]->pucch_payload[0] = ue_cntl_delay[ue_id][last_slot%2].pucch_payload;//UE_transport_info[ue_id].cntl.pucch_payload;
|
||||
}
|
||||
PHY_vars_UE_g[ue_id]->pucch_sel[subframe] = ue_cntl_delay[ue_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].num_eNB, ue_id);
|
||||
/* LOG_D(EMU,"Setting ulsch vars for ue %d rnti %x harq pid is %d \n",
|
||||
ue_id, UE_transport_info[ue_id].rnti[n_enb],
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]);
|
||||
*/
|
||||
#endif
|
||||
for (n_enb=0; n_enb < UE_transport_info[ue_id].num_eNB; n_enb++){
|
||||
#ifdef DEBUG_EMU
|
||||
/* LOG_D(EMU,"Setting ulsch vars for ue %d rnti %x harq pid is %d \n",
|
||||
ue_id, UE_transport_info[ue_id].rnti[n_enb],
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]);
|
||||
*/
|
||||
#endif
|
||||
rnti = UE_transport_info[ue_id].rnti[n_enb];
|
||||
enb_id = UE_transport_info[ue_id].eNB_id[n_enb];
|
||||
|
||||
PHY_vars_UE_g[ue_id]->lte_ue_pdcch_vars[enb_id]->crnti=rnti;
|
||||
|
||||
harq_pid = UE_transport_info[ue_id].harq_pid[n_enb];
|
||||
|
||||
//ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id];
|
||||
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[0] = ue_cntl_delay[ue_id][last_slot%2].pusch_ri & 0x1;
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[1] = (ue_cntl_delay[ue_id][last_slot%2].pusch_ri>>1) & 0x1;
|
||||
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[0]= ue_cntl_delay[ue_id][last_slot%2].pusch_ack & 0x1;
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[1]= (ue_cntl_delay[ue_id][last_slot%2].pusch_ack>>1) & 0x1;
|
||||
//*(u32 *)ulsch->o = ue_cntl_delay[ue_id][last_slot%2].pusch_uci;
|
||||
rnti = UE_transport_info[ue_id].rnti[n_enb];
|
||||
enb_id = UE_transport_info[ue_id].eNB_id[n_enb];
|
||||
|
||||
if (last_slot%2 == 1 ) {
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O = ue_cntl_delay[ue_id][last_slot%2].length_uci;
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->uci_format = ue_cntl_delay[ue_id][last_slot%2].uci_format;
|
||||
|
||||
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o,
|
||||
ue_cntl_delay[ue_id][last_slot%2].pusch_uci,
|
||||
MAX_CQI_BYTES);
|
||||
|
||||
ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[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]->ulsch_ue[enb_id]->O);
|
||||
}
|
||||
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->harq_processes[harq_pid]->b,
|
||||
UE_transport_info[ue_id].transport_blocks,
|
||||
UE_transport_info[ue_id].tbs[enb_id]);
|
||||
|
||||
//ue_transport_info_index[enb_id]+=UE_transport_info[ue_id].tbs[enb_id];
|
||||
|
||||
//UE_transport_info[ue_id].transport_blocks+=ue_transport_info_index[enb_id];
|
||||
//LOG_T(EMU,"ulsch tbs is %d\n", UE_transport_info[ue_id].tbs[enb_id]);
|
||||
}
|
||||
PHY_vars_UE_g[ue_id]->lte_ue_pdcch_vars[enb_id]->crnti=rnti;
|
||||
|
||||
harq_pid = UE_transport_info[ue_id].harq_pid[n_enb];
|
||||
|
||||
//ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id];
|
||||
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[0] =
|
||||
ue_cntl_delay[ue_id][last_slot%2].pusch_ri & 0x1;
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[1] =
|
||||
(ue_cntl_delay[ue_id][last_slot%2].pusch_ri>>1) & 0x1;
|
||||
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[0]=
|
||||
ue_cntl_delay[ue_id][last_slot%2].pusch_ack & 0x1;
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[1]=
|
||||
(ue_cntl_delay[ue_id][last_slot%2].pusch_ack>>1) & 0x1;
|
||||
//*(u32 *)ulsch->o = ue_cntl_delay[ue_id][last_slot%2].pusch_uci;
|
||||
|
||||
if (last_slot%2 == 1 ) {
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O =
|
||||
ue_cntl_delay[ue_id][last_slot%2].length_uci;
|
||||
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->uci_format =
|
||||
ue_cntl_delay[ue_id][last_slot%2].uci_format;
|
||||
|
||||
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o,
|
||||
ue_cntl_delay[ue_id][last_slot%2].pusch_uci,
|
||||
MAX_CQI_BYTES);
|
||||
|
||||
ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[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]->ulsch_ue[enb_id]->O);
|
||||
}
|
||||
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->harq_processes[harq_pid]->b,
|
||||
UE_transport_info[ue_id].transport_blocks,
|
||||
UE_transport_info[ue_id].tbs[enb_id]);
|
||||
|
||||
//ue_transport_info_index[enb_id]+=UE_transport_info[ue_id].tbs[enb_id];
|
||||
|
||||
//UE_transport_info[ue_id].transport_blocks+=ue_transport_info_index[enb_id];
|
||||
//LOG_T(EMU,"ulsch tbs is %d\n", UE_transport_info[ue_id].tbs[enb_id]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*! \file extern.h
|
||||
* \brief specifies the extern variables for phy emulation
|
||||
* \author Navid Nikaein and Raymomd Knopp and Hicham Anouar
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
* \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__
|
||||
@@ -23,16 +23,17 @@ extern unsigned char emu_rx_status;
|
||||
//extern unsigned short Master_id;
|
||||
//extern unsigned int Is_primary_master;
|
||||
|
||||
#if !defined(ENABLE_NEW_MULTICAST)
|
||||
extern pthread_mutex_t emul_low_mutex;
|
||||
extern pthread_cond_t emul_low_cond;
|
||||
extern char emul_low_mutex_var;
|
||||
extern pthread_mutex_t Tx_mutex;
|
||||
extern pthread_cond_t Tx_cond;
|
||||
extern char Tx_mutex_var;
|
||||
#endif
|
||||
|
||||
|
||||
extern int (*rx_handler) (unsigned char,char*,int);
|
||||
extern int (*tx_handler) (unsigned char,char*, unsigned int*, unsigned int*);
|
||||
extern rx_handler_t rx_handler;
|
||||
extern tx_handler_t tx_handler;
|
||||
|
||||
extern eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX];
|
||||
extern u16 eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX];
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*! \file multicast.h
|
||||
* \brief
|
||||
* \author Lionel Gauthier and Navid Nikaein
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
* \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>
|
||||
@@ -26,110 +26,117 @@
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
//#include "openair_defs.h"
|
||||
//#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
//#include "openair_defs.h"
|
||||
|
||||
#define MULTICAST_LINK_C
|
||||
|
||||
#include "socket.h"
|
||||
#include "multicast_link.h"
|
||||
#ifndef USER_MODE
|
||||
#ifdef NODE_RG
|
||||
//#include "mac_rg_bypass.h"
|
||||
#endif
|
||||
#ifdef NODE_MT
|
||||
//#include "mac_ue_bypass.h"
|
||||
#endif
|
||||
#endif //USER_MODE
|
||||
|
||||
#ifdef USER_MODE
|
||||
//#include <rtai.h>
|
||||
# define msg printf
|
||||
# include "UTIL/LOG/log.h"
|
||||
#endif //USER_MODE
|
||||
//#include "extern.h"
|
||||
|
||||
extern unsigned short Master_id;
|
||||
|
||||
#define MULTICAST_LINK_NUM_GROUPS 4
|
||||
|
||||
char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS] = {
|
||||
"239.0.0.161\0",
|
||||
"239.0.0.162\0",
|
||||
"239.0.0.163\0",
|
||||
"239.0.0.164\0"
|
||||
"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];
|
||||
|
||||
static fd_set socks; /* Socket file descriptors we want to wake up for, using select() */
|
||||
static int highsock; /* Highest #'d file descriptor, needed for select() */
|
||||
/* 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;
|
||||
static void (*rx_handler) (unsigned int, char*);
|
||||
static unsigned char multicast_group;
|
||||
static char *multicast_if;
|
||||
#endif
|
||||
static void (*rx_handler) (unsigned int, char *);
|
||||
static unsigned char multicast_group;
|
||||
static char *multicast_if;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
multicast_link_init ()
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
int group;
|
||||
int multicast_loop;
|
||||
int reuse_addr = 1; /* Used so we can re-bind to our port
|
||||
while a previous connection is still
|
||||
in TIME_WAIT state. */
|
||||
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]);
|
||||
group_list[group].port = 46014 + group;
|
||||
group_list[group].socket = make_socket_inet (SOCK_DGRAM, &group_list[group].port, &sin);
|
||||
msg("multicast_link_init(): Created socket %d for group %d, port %d\n",
|
||||
group_list[group].socket,group,group_list[group].port);
|
||||
if (setsockopt (group_list[group].socket, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof (reuse_addr)) < 0) {
|
||||
msg ("[MULTICAST] ERROR : setsockopt:SO_REUSEADDR, exiting ...");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (multicast_if != NULL) {
|
||||
/* memset(&ifr, 0, sizeof(struct ifreq));
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), multicast_if);
|
||||
ioctl(group_list[group].socket, SIOCGIFINDEX, &ifr);
|
||||
if (setsockopt (group_list[group].socket, SOL_SOCKET,SO_BINDTODEVICE,(void*)&ifr, sizeof(struct ifreq)) < 0) { */
|
||||
if (setsockopt (group_list[group].socket, SOL_SOCKET,SO_BINDTODEVICE,multicast_if, 4) < 0) {
|
||||
msg ("[MULTICAST] ERROR : setsockopt:SO_BINDTODEVICE on interface %s, exiting ...\n", multicast_if);
|
||||
msg ("[MULTICAST] make sure that you have a root privilage or run with sudo -E \n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
socket_setnonblocking (group_list[group].socket);
|
||||
int group;
|
||||
int multicast_loop;
|
||||
int reuse_addr = 1;
|
||||
static struct ip_mreq command;
|
||||
struct sockaddr_in sin;
|
||||
// struct ifreq ifr;
|
||||
|
||||
//
|
||||
multicast_loop = 0;
|
||||
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_MULTICAST_LOOP, &multicast_loop, sizeof (multicast_loop)) < 0) {
|
||||
msg ("[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) {
|
||||
msg ("[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) {
|
||||
msg ("[MULTICAST] ERROR: %s line %d IP_ADD_MEMBERSHIP %m", __FILE__, __LINE__);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) {
|
||||
strcpy (group_list[group].host_addr, multicast_group_list[group]);
|
||||
group_list[group].port = 46014 + group;
|
||||
group_list[group].socket = make_socket_inet(
|
||||
SOCK_DGRAM,
|
||||
&group_list[group].port, &sin);
|
||||
|
||||
LOG_D(EMU, "multicast_link_init(): Created socket %d for group %d, port %d\n",
|
||||
group_list[group].socket,group,group_list[group].port);
|
||||
|
||||
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);
|
||||
}
|
||||
/* 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(EMU, "[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, 4) < 0) {
|
||||
LOG_E(EMU,
|
||||
"[MULTICAST] ERROR : setsockopt:SO_BINDTODEVICE on interface %s, exiting ...\n",
|
||||
multicast_if);
|
||||
LOG_E(EMU,
|
||||
"[MULTICAST] make sure that you have a root privilage or run with sudo -E \n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(ENABLE_TCP_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(EMU,
|
||||
"[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(EMU, "[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(EMU, "[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);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -137,86 +144,69 @@ void
|
||||
multicast_link_build_select_list ()
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
int group;
|
||||
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. */
|
||||
/* 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() clears out the fd_set called socks, so that
|
||||
it doesn't contain any file descriptors. */
|
||||
|
||||
FD_ZERO (&socks);
|
||||
FD_ZERO (&socks);
|
||||
|
||||
|
||||
/* Loops through all the possible connections and adds
|
||||
those sockets to the fd_set */
|
||||
/* 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;
|
||||
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;
|
||||
|
||||
#ifdef BYPASS_PHY
|
||||
//pthread_mutex_lock(&Bypass_phy_wr_mutex);
|
||||
// while(Bypass_phy_wr){
|
||||
// msg("[Multicast read] BYPASS_PHY_NOT_YET READY, Waiting for signal\n");
|
||||
// pthread_cond_wait(&Bypass_phy_wr_cond,&Bypass_phy_wr_mutex);
|
||||
// }
|
||||
//msg("[Multicast read] BYPASS_PHY TX Signal\n");
|
||||
//pthread_mutex_unlock(&Bypass_phy_wr_mutex);
|
||||
//pthread_mutex_lock(&Bypass_phy_wr_mutex);
|
||||
// Bypass_phy_wr=1;
|
||||
// pthread_mutex_unlock(&Bypass_phy_wr_mutex);
|
||||
#endif //BYPASS_PHY
|
||||
|
||||
int num_bytes;
|
||||
//msg("multicast link read INNNNNNNNNNNNNNNNNN\n");
|
||||
// msg("multicast_link_read_data: groupP=%d,rx_buffer = %p\n",groupP,group_list[groupP].rx_buffer );
|
||||
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) {
|
||||
fprintf (stderr, "ERROR: %s line %d multicast_link_read_data()/recvfrom() %m", __FILE__, __LINE__);
|
||||
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(EMU, "[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 {
|
||||
// msg("multicast_link_read_data: groupP=%d,rx_buffer = %p,NUm_bytes=%d\n",groupP,group_list[groupP].rx_buffer,num_bytes );
|
||||
//msg("MULTICAST calling rx_handler\n");
|
||||
rx_handler(num_bytes,group_list[groupP].rx_buffer);
|
||||
LOG_E(EMU, "[MULTICAST] ERROR: groupP out of bounds %d\n", groupP);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"ERROR: groupP out of bounds %d\n",groupP);
|
||||
}
|
||||
//msg("ENNNNND multicast_link_read_data: groupP=%d,rx_buffer = %p, num_bytes=%d\n",groupP,group_list[groupP].rx_buffer,num_bytes );
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
multicast_link_read ()
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
int group; /* Current item in connectlist for for loops */
|
||||
int group; /* Current item in connectlist for for loops */
|
||||
|
||||
/* Now check connectlist for available data */
|
||||
/* 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) */
|
||||
/* 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) */
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -224,73 +214,89 @@ 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) {
|
||||
fprintf (stderr, "ERROR: %s line %d multicast_link_write_sock()/sendto() %m", __FILE__, __LINE__);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void *
|
||||
multicast_link_main_loop (void *param)
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
struct timeval timeout; /* Timeout for select */
|
||||
int readsocks; /* Number of sockets ready for reading */
|
||||
#ifdef USER_MODE
|
||||
|
||||
#endif //USER_MODE
|
||||
highsock = -1;
|
||||
while (1) {
|
||||
multicast_link_build_select_list ();
|
||||
/* [24/06/13] SR: Set the timeout to one second ->
|
||||
* avoid infinite loop if no data to read.
|
||||
*/
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
readsocks = select (highsock + 1, &socks, (fd_set *) 0, (fd_set *) 0, &timeout);
|
||||
if (readsocks < 0) {
|
||||
LOG_E(EMU, "Multicast select failed (%d:%s)\n", errno, strerror(errno));
|
||||
// exit();
|
||||
} else if (readsocks > 0) {
|
||||
//msg("calling multicast link read\n");
|
||||
multicast_link_read ();
|
||||
// usleep(1);
|
||||
} else {
|
||||
/* Timeout */
|
||||
LOG_I(EMU, "Multicast select time-out\n");
|
||||
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(EMU, "[MULTICAST] sendto has failed (%d:%s)\n (%s:%d)\n",
|
||||
errno, strerror(errno),
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
#ifdef USER_MODE
|
||||
|
||||
#endif //USER_MODE
|
||||
return num;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
multicast_link_start ( void (*rx_handlerP) (unsigned int, char*), unsigned char multicast_group, char * multicast_ifname)
|
||||
int multicast_link_read_data_from_sock(uint8_t is_master)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
rx_handler = rx_handlerP;
|
||||
multicast_group = multicast_group;
|
||||
multicast_if = multicast_ifname;
|
||||
msg("[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n",
|
||||
(multicast_if == NULL) ? "not specified" : multicast_if, multicast_group, rx_handler);
|
||||
#ifdef BYPASS_PHY
|
||||
// pthread_mutex_init(&Bypass_phy_wr_mutex,NULL);
|
||||
//pthread_cond_init(&Bypass_phy_wr_cond,NULL);
|
||||
//Bypass_phy_wr=0;
|
||||
#endif //BYPASS_PHY
|
||||
multicast_link_init ();
|
||||
msg("[MULTICAST] multicast link start thread\n");
|
||||
if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop, NULL) != 0) {
|
||||
msg ("[MULTICAST LINK] Thread started\n");
|
||||
exit (-2);
|
||||
} else {
|
||||
pthread_detach (main_loop_thread); // disassociate from parent
|
||||
msg ("[MULTICAST LINK] Thread detached\n");
|
||||
|
||||
}
|
||||
struct timeval timeout, *timeout_p;
|
||||
int readsocks; /* Number of sockets ready for reading */
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 3000;
|
||||
|
||||
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(EMU, "Stuck on select with timeout %s\n",
|
||||
timeout_p == NULL ? "infinite" : "1000 usecs");
|
||||
|
||||
readsocks = select(highsock + 1, &socks, (fd_set *) 0, (fd_set *) 0, timeout_p);
|
||||
if (readsocks < 0) {
|
||||
LOG_E(EMU, "Multicast select failed (%d:%s)\n", errno, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
} else if (readsocks > 0) {
|
||||
LOG_D(EMU, "Multicast Normal read\n");
|
||||
multicast_link_read();
|
||||
} else {
|
||||
/* Timeout */
|
||||
LOG_I(EMU, "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(EMU, "[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(EMU, "[MULTICAST] multicast link start thread\n");
|
||||
if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop,
|
||||
NULL) != 0) {
|
||||
LOG_E(EMU, "[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(EMU, "[MULTICAST LINK] Thread detached\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*! \file multicast.h
|
||||
* \brief
|
||||
* \author Lionel Gauthier and Navid Nikaein
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
* \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__
|
||||
@@ -18,27 +18,24 @@
|
||||
# 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;
|
||||
struct sockaddr_in sock_remote_addr;
|
||||
uint16_t port;
|
||||
char rx_buffer[40000];
|
||||
} multicast_group_t;)
|
||||
|
||||
|
||||
private_multicast_link(void multicast_link_init ());
|
||||
private_multicast_link(void multicast_link_read_data (int groupP));
|
||||
private_multicast_link(void multicast_link_read ());
|
||||
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
|
||||
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,11 +1,11 @@
|
||||
/*! \file netlink_init.c
|
||||
* \brief initiate the netlink socket for communication with nas dirver
|
||||
* \brief initiate the netlink socket for communication with nas dirver
|
||||
* \author Navid Nikaein and Raymomd Knopp
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
@@ -25,62 +25,50 @@ struct msghdr nas_msg;
|
||||
|
||||
#define GRAAL_NETLINK_ID 31
|
||||
|
||||
int netlink_init(void) {
|
||||
int netlink_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
nas_sock_fd = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID);
|
||||
if (nas_sock_fd == -1) {
|
||||
printf("[NETLINK] Error opening socket %d\n",nas_sock_fd);
|
||||
return(-1);
|
||||
}
|
||||
printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd);
|
||||
|
||||
int ret;
|
||||
ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK);
|
||||
printf("[NETLINK] fcntl returns %d\n",ret);
|
||||
|
||||
|
||||
nas_sock_fd = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID);
|
||||
if (nas_sock_fd==-1) {
|
||||
printf("[NETLINK] Error opening socket %d\n",nas_sock_fd);
|
||||
return(-1);
|
||||
}
|
||||
printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd);
|
||||
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, (struct sockaddr *)&nas_src_addr,
|
||||
sizeof(nas_src_addr));
|
||||
|
||||
ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK);
|
||||
printf("[NETLINK] fcntl returns %d\n",ret);
|
||||
printf("[NETLINK] bind returns %d\n",ret);
|
||||
|
||||
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, (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 */
|
||||
|
||||
printf("[NETLINK] bind returns %d\n",ret);
|
||||
nas_nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
|
||||
/* Fill the netlink message header */
|
||||
nas_nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
|
||||
nas_nlh->nlmsg_pid = 1;//getpid(); /* self pid */
|
||||
nas_nlh->nlmsg_flags = 0;
|
||||
|
||||
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 */
|
||||
|
||||
nas_nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
|
||||
/* Fill the netlink message header */
|
||||
nas_nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
|
||||
nas_nlh->nlmsg_pid = 1;//getpid(); /* self pid */
|
||||
nas_nlh->nlmsg_flags = 0;
|
||||
|
||||
nas_iov.iov_base = (void *)nas_nlh;
|
||||
nas_iov.iov_len = nas_nlh->nlmsg_len;
|
||||
memset(&nas_msg,0,sizeof(nas_msg));
|
||||
nas_msg.msg_name = (void *)&nas_dest_addr;
|
||||
nas_msg.msg_namelen = sizeof(nas_dest_addr);
|
||||
nas_msg.msg_iov = &nas_iov;
|
||||
nas_msg.msg_iovlen = 1;
|
||||
|
||||
|
||||
/* Read message from kernel */
|
||||
memset(nas_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
|
||||
|
||||
nas_iov.iov_base = (void *)nas_nlh;
|
||||
nas_iov.iov_len = nas_nlh->nlmsg_len;
|
||||
memset(&nas_msg,0,sizeof(nas_msg));
|
||||
nas_msg.msg_name = (void *)&nas_dest_addr;
|
||||
nas_msg.msg_namelen = sizeof(nas_dest_addr);
|
||||
nas_msg.msg_iov = &nas_iov;
|
||||
nas_msg.msg_iovlen = 1;
|
||||
|
||||
return(nas_sock_fd);
|
||||
/* Read message from kernel */
|
||||
memset(nas_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
|
||||
|
||||
return(nas_sock_fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,12 +5,18 @@
|
||||
* \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);
|
||||
void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot, unsigned int next_slot);
|
||||
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);
|
||||
#ifndef USER_MODE
|
||||
int multicast_link_write_sock (int groupP, char *dataP, unsigned int sizeP);
|
||||
int bypass_tx_handler(unsigned int fifo, int rw);
|
||||
@@ -19,7 +25,7 @@ int bypass_rx_handler(unsigned int fifo, int rw);
|
||||
void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer);
|
||||
#endif
|
||||
|
||||
void bypass_tx_data (char Type, unsigned int frame, unsigned int next_slot);
|
||||
void bypass_tx_data (emu_transport_info_t Type, unsigned int frame, unsigned int next_slot);
|
||||
|
||||
void emulation_tx_rx(void);
|
||||
|
||||
@@ -37,7 +43,10 @@ void emu_transport_DL(unsigned int frame, unsigned int last_slot,unsigned int ne
|
||||
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(u8);
|
||||
void clear_UE_transport_info(u8);
|
||||
int netlink_init(void);
|
||||
|
||||
#endif /* EMU_PROTO_H_ */
|
||||
|
||||
@@ -24,15 +24,18 @@ unsigned char emu_rx_status;
|
||||
//unsigned short Master_id;
|
||||
//unsigned int Is_primary_master;
|
||||
|
||||
#if !defined(ENABLE_NEW_MULTICAST)
|
||||
pthread_mutex_t emul_low_mutex;
|
||||
pthread_cond_t emul_low_cond;
|
||||
char emul_low_mutex_var;
|
||||
pthread_mutex_t Tx_mutex;
|
||||
pthread_cond_t Tx_cond;
|
||||
char Tx_mutex_var;
|
||||
#endif
|
||||
|
||||
int (*rx_handler) (unsigned char,char*,int);
|
||||
int (*tx_handler) (unsigned char,char*, unsigned int*, unsigned int*);
|
||||
/* 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];
|
||||
u16 eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX];
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Eurecom OpenAirInterface
|
||||
Copyright(c) 1999 - 2012 Eurecom
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information
|
||||
Openair Admin: openair_admin@eurecom.fr
|
||||
Openair Tech : openair_tech@eurecom.fr
|
||||
Forums : http://forums.eurecom.fr/openairinterface
|
||||
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
|
||||
06410 Biot FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef ASSERTIONS_H_
|
||||
#define ASSERTIONS_H_
|
||||
|
||||
#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \
|
||||
do { \
|
||||
if (!(cOND)) { \
|
||||
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__); \
|
||||
fprintf(stderr, #vALUE1": %d\n"#vALUE2": %d\n"#vALUE3": %d\n", \
|
||||
(int)vALUE1, (int)vALUE2, (int)vALUE3); \
|
||||
abort(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
|
||||
do { \
|
||||
if (!(cOND)) { \
|
||||
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__); \
|
||||
fprintf(stderr, #vALUE1": %d\n"#vALUE2": %d\n"#vALUE3": %d\n" \
|
||||
#vALUE4": %d\n", \
|
||||
(int)vALUE1, (int)vALUE2, (int)vALUE3, (int)vALUE4); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define DevParam(vALUE1, vALUE2, vALUE3) \
|
||||
DevCheck(0 == 1, vALUE1, vALUE2, vALUE3)
|
||||
|
||||
#define DevAssert(cOND) \
|
||||
do { \
|
||||
if (!(cOND)) { \
|
||||
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__); \
|
||||
abort(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define DevMessage(mESSAGE) \
|
||||
do { \
|
||||
fprintf(stderr, "%s:%d:%s Execution interrupted: `"#mESSAGE"`.\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__); \
|
||||
abort(); \
|
||||
} while(0)
|
||||
|
||||
#endif /* ASSERTIONS_H_ */
|
||||
@@ -218,6 +218,7 @@ CFLAGS +=-DPROC
|
||||
endif
|
||||
|
||||
CFLAGS += -DENABLE_VCD_FIFO
|
||||
CFLAGS += -DENABLE_NEW_MULTICAST
|
||||
# CFLAGS += -DENABLE_LOG_FIFO
|
||||
|
||||
OBJ = $(PHY_OBJS) $(SIMULATION_OBJS) $(ETHERNET_TRANSPORT_OBJS) $(TOOLS_OBJS) $(SCHED_OBJS) $(STATS_OBJS) $(OAISIM_OBJS) $(NAS_OBJS) $(INT_OBJS) $(UTIL_OBJ)
|
||||
|
||||
Reference in New Issue
Block a user