From d44ccd24abb25e6d17f240e6dae7bfc5d10aaa6c Mon Sep 17 00:00:00 2001 From: Cedric Roux <cedric.roux@eurecom.fr> Date: Wed, 3 Jul 2013 09:27:32 +0000 Subject: [PATCH] - 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 --- .../ETH_TRANSPORT/bypass_session_layer.c | 894 ++++++++++-------- openair1/SIMULATION/ETH_TRANSPORT/defs.h | 97 +- .../SIMULATION/ETH_TRANSPORT/emu_transport.c | 720 +++++++------- openair1/SIMULATION/ETH_TRANSPORT/extern.h | 21 +- .../SIMULATION/ETH_TRANSPORT/multicast_link.c | 396 ++++---- .../SIMULATION/ETH_TRANSPORT/multicast_link.h | 33 +- .../SIMULATION/ETH_TRANSPORT/netlink_init.c | 110 +-- openair1/SIMULATION/ETH_TRANSPORT/proto.h | 17 +- openair1/SIMULATION/ETH_TRANSPORT/vars.h | 7 +- openair2/UTIL/assertions.h | 77 ++ targets/SIMU/USER/Makefile | 1 + 11 files changed, 1259 insertions(+), 1114 deletions(-) create mode 100644 openair2/UTIL/assertions.h diff --git a/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c b/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c index 07e7e243f..3eef10ebe 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c @@ -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 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 + 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)){ +void bypass_init (tx_handler_t tx_handlerP, rx_handler_t rx_handlerP) +{ /***************************************************************************/ -#ifdef USER_MODE - multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group, oai_emulation.info.multicast_ifname); +#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; + 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"); + + +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); } - 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); + + if(num_bytesP==0) { + pthread_mutex_unlock(&emul_low_mutex); + } else { #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: + 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; - } + 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); + 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 - //printf("leaving ...\n"); - return bytes_read; + return bytes_read; } -/******************************************************************************************************/ -#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; +/******************************************************************************************************/ +#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; - - 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; +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; + + 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 diff --git a/openair1/SIMULATION/ETH_TRANSPORT/defs.h b/openair1/SIMULATION/ETH_TRANSPORT/defs.h index d3e0e7c65..14f530032 100755 --- a/openair1/SIMULATION/ETH_TRANSPORT/defs.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/defs.h @@ -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__ */ diff --git a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c index 2fc349916..f2f4f9500 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c @@ -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){ - 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); - } +void emu_transport_sync(void) +{ + LOG_D(EMU, "Entering EMU transport SYNC is primary master %d\n", + oai_emulation.info.is_primary_master); + + if (oai_emulation.info.is_primary_master == 0) { +retry: + bypass_tx_data(WAIT_SM_TRANSPORT,0,0); + // just wait to recieve the master 0 msg + Master_list_rx = oai_emulation.info.master_list - 1; + if (bypass_rx_data(0,0,0,1) == -1) { + /* In case the master is not ready at time we send the first message */ + sleep(1); + goto retry; + } + } else { + bypass_rx_data(0,0,0,0); + bypass_tx_data(WAIT_PM_TRANSPORT,0,0); + } - if (oai_emulation.info.master_list!=0){ + 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; + } - bypass_tx_data(SYNC_TRANSPORT,0,0); - bypass_rx_data(0,0,0); + // i received the sync from all secondary masters + if (emu_rx_status == SYNCED_TRANSPORT) { + emu_tx_status = SYNCED_TRANSPORT; + } - if (emu_rx_status == SYNCED_TRANSPORT){ // i received the sync from all secondary masters - emu_tx_status = SYNCED_TRANSPORT; + LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n"); } - // else emu_transport_sync(last_slot); - LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n"); - } - + LOG_D(EMU, "Leaving EMU transport SYNC is primary master %d\n", + oai_emulation.info.is_primary_master); } -void emu_transport(unsigned int frame, unsigned int last_slot, unsigned int next_slot,lte_subframe_t direction, unsigned char frame_type, int ethernet_flag ){ - - if (ethernet_flag == 0) - return; - - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_IN); - - if ((frame_type == 1) && (direction == SF_S)){ - if (next_slot%2==0) - emu_transport_DL(frame, last_slot,next_slot); - else - emu_transport_UL(frame, last_slot , next_slot); - //DL - }else { - if (next_slot%2 == 0 ) - if ( ((frame_type == 1) && (direction == SF_DL )) || (frame_type == 0) ){ - emu_transport_DL(frame, last_slot,next_slot); +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; } - // 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_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); + 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) { +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); +} - 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); +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); +} - 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); +void emu_transport_release(void) +{ + bypass_tx_data(RELEASE_TRANSPORT,0,0); + LOG_E(EMU," tx RELEASE_TRANSPORT \n"); +} - bypass_rx_data(frame,last_slot, next_slot); - } +unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer, + unsigned int *Nbytes,unsigned int *Nb_flows) +{ + return *Nbytes; } -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); - } - +unsigned int emul_rx_data(void) +{ + return(0); } -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; +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; -unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer, unsigned int Nbytes){ - unsigned short Rx_size=0; - return (Rx_size+2); + 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_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 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"); + 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; -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; - #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 - - //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++) { - - 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]); + //CFI + // not needed yet + + //PHICH + // to be added later + + //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 - } + 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)); +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,"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, + "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 - 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]); - */ + //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); +#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; - - 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]); - } + 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; + + 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]); + } } diff --git a/openair1/SIMULATION/ETH_TRANSPORT/extern.h b/openair1/SIMULATION/ETH_TRANSPORT/extern.h index 173783a6d..9518d337b 100755 --- a/openair1/SIMULATION/ETH_TRANSPORT/extern.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/extern.h @@ -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]; diff --git a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c index c83d3a2a6..f66c69076 100755 --- a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c @@ -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); + /* 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); + } + } - 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); - } +#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; + 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__); + } + return num; } -//------------------------------------------------------------------------------ -void * -multicast_link_main_loop (void *param) +int multicast_link_read_data_from_sock(uint8_t is_master) { -//------------------------------------------------------------------------------ - struct timeval timeout; /* Timeout for select */ - int readsocks; /* Number of sockets ready for reading */ -#ifdef USER_MODE + 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; -#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); + 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(); + LOG_E(EMU, "Multicast select failed (%d:%s)\n", errno, strerror(errno)); + exit(EXIT_FAILURE); } else if (readsocks > 0) { - //msg("calling multicast link read\n"); - multicast_link_read (); - // usleep(1); + LOG_D(EMU, "Multicast Normal read\n"); + multicast_link_read(); } else { - /* Timeout */ - LOG_I(EMU, "Multicast select time-out\n"); + /* Timeout */ + LOG_I(EMU, "Multicast select time-out\n"); + return 1; } - } -#ifdef USER_MODE + return 0; +} -#endif //USER_MODE +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) +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; - 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"); - - } + 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 } diff --git a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.h b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.h index 1df7e985b..b54913c3d 100755 --- a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.h @@ -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 diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index 8ad2d00f4..afb05f4b8 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -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 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); - - ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK); - printf("[NETLINK] fcntl 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)); - - printf("[NETLINK] bind returns %d\n",ret); - - 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)); - - - return(nas_sock_fd); +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); + + ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK); + printf("[NETLINK] fcntl 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)); + + printf("[NETLINK] bind returns %d\n",ret); + + 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)); + + return(nas_sock_fd); } - - - - - - - - diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h index eb914ef6a..e90a83a30 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h @@ -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_ */ diff --git a/openair1/SIMULATION/ETH_TRANSPORT/vars.h b/openair1/SIMULATION/ETH_TRANSPORT/vars.h index 237f23e6f..2b86c5d4f 100755 --- a/openair1/SIMULATION/ETH_TRANSPORT/vars.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/vars.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]; diff --git a/openair2/UTIL/assertions.h b/openair2/UTIL/assertions.h new file mode 100644 index 000000000..269854451 --- /dev/null +++ b/openair2/UTIL/assertions.h @@ -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_ */ diff --git a/targets/SIMU/USER/Makefile b/targets/SIMU/USER/Makefile index 87060cfc0..83145c12d 100644 --- a/targets/SIMU/USER/Makefile +++ b/targets/SIMU/USER/Makefile @@ -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) -- GitLab