Commit d44ccd24 authored by Cedric Roux's avatar Cedric Roux

- 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
parent b62ae47b
/*! \file bypass_session_layer.h /*! \file bypass_session_layer.h
* \brief implementation of emultor tx and rx * \brief implementation of emultor tx and rx
* \author Navid Nikaein and Raymond Knopp * \author Navid Nikaein and Raymond Knopp
* \date 2011 * \date 2011
* \version 1.0 * \version 1.0
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
#include "PHY/defs.h" #include "PHY/defs.h"
#include "defs.h" #include "defs.h"
#include "proto.h"
#include "extern.h" #include "extern.h"
//#include "mac_extern.h"
#include "UTIL/assertions.h"
#include "UTIL/OCG/OCG.h" #include "UTIL/OCG/OCG.h"
#include "UTIL/OCG/OCG_extern.h" #include "UTIL/OCG/OCG_extern.h"
#include "UTIL/LOG/log.h" #include "UTIL/LOG/log.h"
...@@ -19,455 +21,523 @@ ...@@ -19,455 +21,523 @@
#include "multicast_link.h" #include "multicast_link.h"
#endif #endif
/***************************************************************************/
char rx_bufferP[BYPASS_RX_BUFFER_SIZE]; char rx_bufferP[BYPASS_RX_BUFFER_SIZE];
static unsigned int num_bytesP=0; static unsigned int num_bytesP = 0;
int N_P=0,N_R=0; int N_P = 0, N_R = 0;
char bypass_tx_buffer[BYPASS_TX_BUFFER_SIZE]; char bypass_tx_buffer[BYPASS_TX_BUFFER_SIZE];
unsigned int Master_list_rx, Seq_nb; static unsigned int byte_tx_count;
/***************************************************************************/ unsigned int Master_list_rx;
static uint64_t seq_num_tx = 0;
mapping transport_names[] = { mapping transport_names[] = {
{"WAIT PM TRANSPORT INFO", WAIT_PM_TRANSPORT_INFO}, {"WAIT PM TRANSPORT INFO", EMU_TRANSPORT_INFO_WAIT_PM},
{"WAIT SM TRANSPORT INFO", WAIT_SM_TRANSPORT_INFO}, {"WAIT SM TRANSPORT INFO", EMU_TRANSPORT_INFO_WAIT_SM},
{"SYNC TRANSPORT INFO", SYNC_TRANSPORT_INFO}, {"SYNC TRANSPORT INFO", EMU_TRANSPORT_INFO_SYNC},
{"ENB_TRANSPORT INFO", ENB_TRANSPORT_INFO}, {"ENB_TRANSPORT INFO", EMU_TRANSPORT_INFO_ENB},
{"UE TRANSPORT INFO", UE_TRANSPORT_INFO}, {"UE TRANSPORT INFO", EMU_TRANSPORT_INFO_UE},
{"RELEASE TRANSPORT INFO", RELEASE_TRANSPORT_INFO}, {"RELEASE TRANSPORT INFO", EMU_TRANSPORT_INFO_RELEASE},
{NULL, -1} {NULL, -1}
}; };
void init_bypass (void){ void init_bypass (void)
{
msg ("[PHYSIM] INIT BYPASS\n"); LOG_I(EMU, "[PHYSIM] INIT BYPASS\n");
pthread_mutex_init (&Tx_mutex, NULL); #if !defined(ENABLE_NEW_MULTICAST)
pthread_cond_init (&Tx_cond, NULL); pthread_mutex_init (&Tx_mutex, NULL);
Tx_mutex_var = 1; pthread_cond_init (&Tx_cond, NULL);
pthread_mutex_init (&emul_low_mutex, NULL); Tx_mutex_var = 1;
pthread_cond_init (&emul_low_cond, NULL); pthread_mutex_init (&emul_low_mutex, NULL);
emul_low_mutex_var = 1; pthread_cond_init (&emul_low_cond, NULL);
bypass_init (emul_tx_handler, emul_rx_handler); 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 #if defined(USER_MODE)
multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group, oai_emulation.info.multicast_ifname); multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group,
oai_emulation.info.multicast_ifname);
#endif //USER_MODE #endif //USER_MODE
tx_handler = tx_handlerP; tx_handler = tx_handlerP;
rx_handler = rx_handlerP; rx_handler = rx_handlerP;
Master_list_rx=0; Master_list_rx=0;
emu_tx_status = WAIT_SYNC_TRANSPORT; emu_tx_status = WAIT_SYNC_TRANSPORT;
emu_rx_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){
/***************************************************************************/ int bypass_rx_data(unsigned int frame, unsigned int last_slot,
bypass_msg_header_t *messg; unsigned int next_slot, uint8_t is_master)
bypass_proto2multicast_header_t *bypass_read_header; {
eNB_transport_info_t *eNB_info; bypass_msg_header_t *messg;
UE_transport_info_t *UE_info; bypass_proto2multicast_header_t *bypass_read_header;
int ue_info_ix, enb_info_ix; eNB_transport_info_t *eNB_info;
// int tmp_byte_count; UE_transport_info_t *UE_info;
int bytes_read = 0; int ue_info_ix, enb_info_ix;
int bytes_data_to_read; int bytes_read = 0;
// int num_flows; int bytes_data_to_read;
// int current_flow; int m_id, n_enb, n_ue, n_dci, total_tbs = 0, total_header = 0;
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",
// printf("in bypass_rx_data ...\n"); frame, next_slot, is_master);
#if defined(ENABLE_NEW_MULTICAST)
pthread_mutex_lock(&emul_low_mutex); if (multicast_link_read_data_from_sock(is_master) == 1) {
if(emul_low_mutex_var){ /* We got a timeout */
//LOG_T(EMU, " WAIT BYPASS_PHY...\n"); return -1;
pthread_cond_wait(&emul_low_cond, &emul_low_mutex); }
} #else
pthread_mutex_lock(&emul_low_mutex);
if(num_bytesP==0){ if(emul_low_mutex_var) {
//msg("[BYPASS] IDLE_WAIT\n"); pthread_cond_wait(&emul_low_cond, &emul_low_mutex);
//exit(0);
pthread_mutex_unlock(&emul_low_mutex);
}
else{
//LOG_T(EMU,"BYPASS_RX_DATA: IN, Num_bytesp=%d...\n",num_bytesP);
bypass_read_header = (bypass_proto2multicast_header_t *) (&rx_bufferP[bytes_read]);
bytes_read += sizeof (bypass_proto2multicast_header_t);
bytes_data_to_read = bypass_read_header->size;
if(num_bytesP!=bytes_read+bytes_data_to_read) {
LOG_W(EMU, "WARNINIG BYTES2READ # DELIVERED BYTES!!!\n");
} }
else{
messg = (bypass_msg_header_t *) (&rx_bufferP[bytes_read]); if(num_bytesP==0) {
bytes_read += sizeof (bypass_msg_header_t); pthread_mutex_unlock(&emul_low_mutex);
if ( (messg->frame != frame) || (messg->subframe != next_slot>>1) ) } else {
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);
#endif #endif
clear_eNB_transport_info(oai_emulation.info.nb_enb_local+oai_emulation.info.nb_enb_remote); bypass_read_header = (bypass_proto2multicast_header_t *) (
&rx_bufferP[bytes_read]);
if (oai_emulation.info.master[messg->master_id].nb_enb > 0 ){ bytes_read += sizeof (bypass_proto2multicast_header_t);
enb_info_ix =0; bytes_data_to_read = bypass_read_header->size;
total_header=0; if(num_bytesP!=bytes_read+bytes_data_to_read) {
total_header += sizeof(eNB_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE; LOG_W(EMU, "WARNINIG BYTES2READ # DELIVERED BYTES!!!\n");
} else {
eNB_info = (eNB_transport_info_t *) (&rx_bufferP[bytes_read]); messg = (bypass_msg_header_t *) (&rx_bufferP[bytes_read]);
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb; bytes_read += sizeof (bypass_msg_header_t);
n_enb < oai_emulation.info.master[messg->master_id].first_enb+oai_emulation.info.master[messg->master_id].nb_enb ; #if defined(ENABLE_NEW_MULTICAST)
n_enb ++) { LOG_D(EMU, "Received %d bytes [%s] from master_id %d with seq %"PRIuMAX"\n",
total_tbs=0; num_bytesP, map_int_to_str(transport_names, messg->Message_type),
for (n_dci = 0 ; messg->master_id,
n_dci < (eNB_info[enb_info_ix].num_ue_spec_dci+eNB_info[enb_info_ix].num_common_dci); messg->seq_num);
n_dci ++) { DevCheck4((messg->frame == frame) && (messg->subframe == (next_slot>>1)),
total_tbs+=eNB_info[enb_info_ix].tbs[n_dci]; messg->frame, frame, messg->subframe, next_slot>>1);
} #else
enb_info_ix++; if ((messg->frame != frame) || (messg->subframe != next_slot>>1))
if ( (total_tbs + total_header) > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ){ LOG_W(EMU,
LOG_W(EMU,"RX eNB Transport buffer total size %d (header%d,tbs %d) \n", "Received %s from master %d for (frame %d,subframe %d) "
total_header+total_tbs, total_header,total_tbs); "currently (frame %d,subframe %d)\n",
} map_int_to_str(transport_names,messg->Message_type),
memcpy (&eNB_transport_info[n_enb],eNB_info, total_header+total_tbs); messg->master_id,
eNB_info = (eNB_transport_info_t *)((unsigned int)eNB_info + total_header+total_tbs); messg->frame, messg->subframe,
bytes_read+=total_header+total_tbs; frame, next_slot>>1);
} #endif
//chek if MASTER in my List
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb; // switch(Emulation_status){
n_enb < oai_emulation.info.master[messg->master_id].first_enb+oai_emulation.info.master[messg->master_id].nb_enb ; switch(messg->Message_type) {
n_enb ++) //case WAIT_SYNC_TRANSPORT:
fill_phy_enb_vars(n_enb,next_slot);
} case EMU_TRANSPORT_INFO_WAIT_PM:
else{ if (messg->master_id==0 ) {
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));
} }
break;
Master_list_rx=((Master_list_rx) |(1<< messg->master_id)); case EMU_TRANSPORT_INFO_WAIT_SM:
if (Master_list_rx == oai_emulation.info.master_list) { Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
emu_rx_status = SYNCED_TRANSPORT; break;
} case EMU_TRANSPORT_INFO_SYNC:
break;
// determite the total number of remote enb & ue
case UE_TRANSPORT_INFO: 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 #ifdef DEBUG_EMU
LOG_D(EMU," RX UE TRANSPORT INFO from master %d\n",messg->master_id); LOG_D(EMU," RX UE TRANSPORT INFO from master %d\n",messg->master_id);
#endif #endif
clear_UE_transport_info(oai_emulation.info.nb_ue_local+oai_emulation.info.nb_ue_remote); 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 if (oai_emulation.info.master[messg->master_id].nb_ue >
ue_info_ix =0; 0 ) { //&& oai_emulation.info.nb_enb_local >0 ){
total_header=0; // get the header first
total_header += sizeof(UE_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE; ue_info_ix =0;
UE_info = (UE_transport_info_t *) (&rx_bufferP[bytes_read]); total_header=0;
// get the total size of the transport blocks total_header += sizeof(UE_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue; UE_info = (UE_transport_info_t *) (&rx_bufferP[bytes_read]);
n_ue < oai_emulation.info.master[messg->master_id].first_ue+oai_emulation.info.master[messg->master_id].nb_ue ; // get the total size of the transport blocks
n_ue ++) { for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
total_tbs=0; n_ue < oai_emulation.info.master[messg->master_id].first_ue+
for (n_enb = 0;n_enb < UE_info[ue_info_ix].num_eNB; n_enb ++) { oai_emulation.info.master[messg->master_id].nb_ue ;
total_tbs+=UE_info[ue_info_ix].tbs[n_enb]; n_ue ++) {
} total_tbs=0;
ue_info_ix++; for (n_enb = 0; n_enb < UE_info[ue_info_ix].num_eNB; n_enb ++) {
if (total_tbs + total_header > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ){ total_tbs+=UE_info[ue_info_ix].tbs[n_enb];
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); ue_info_ix++;
} if (total_tbs + total_header > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ) {
memcpy (&UE_transport_info[n_ue], UE_info, total_header+total_tbs); LOG_W(EMU,"RX [UE %d] Total size of buffer is %d (header%d,tbs %d) \n",
UE_info = (UE_transport_info_t *)((unsigned int)UE_info + total_header+total_tbs); n_ue, total_header+total_tbs,total_header,total_tbs);
bytes_read+=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 #ifdef DEBUG_EMU
for (n_enb=0; n_enb < UE_info[0].num_eNB; n_enb ++ ) 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", 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].rnti[n_enb],
UE_transport_info[0].eNB_id[n_enb], UE_transport_info[0].eNB_id[n_enb],
UE_transport_info[0].harq_pid[n_enb], UE_transport_info[0].harq_pid[n_enb],
UE_transport_info[0].tbs[n_enb]); UE_transport_info[0].tbs[n_enb]);
#endif #endif
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue; 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 < oai_emulation.info.master[messg->master_id].first_ue +
n_ue ++) { oai_emulation.info.master[messg->master_id].nb_ue ;
fill_phy_ue_vars(n_ue,last_slot); n_ue ++) {
} fill_phy_ue_vars(n_ue,last_slot);
} }
else{ } else {
LOG_T(EMU,"WAIT_UE_TRANSPORT state: no UE transport info from master %d\n", messg->master_id ); 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) { Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
emu_rx_status = SYNCED_TRANSPORT; if (Master_list_rx == oai_emulation.info.master_list) {
} emu_rx_status = SYNCED_TRANSPORT;
break; }
case RELEASE_TRANSPORT_INFO : break;
Master_list_rx = oai_emulation.info.master_list; case EMU_TRANSPORT_INFO_RELEASE :
LOG_E(EMU, "RX RELEASE_TRANSPORT_INFO\n"); Master_list_rx = oai_emulation.info.master_list;
break; LOG_E(EMU, "RX EMU_TRANSPORT_INFO_RELEASE\n");
default: break;
msg("[MAC][BYPASS] ERROR RX UNKNOWN MESSAGE\n"); default:
//mac_xface->macphy_exit(""); LOG_E(EMU, "[MAC][BYPASS] ERROR RX UNKNOWN MESSAGE\n");
break; //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);
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 #ifndef USER_MODE
int bypass_rx_handler(unsigned int fifo, int rw){ int bypass_rx_handler(unsigned int fifo, int rw)
/******************************************************************************************************/ {
// if(rw=='w'){ /******************************************************************************************************/
int bytes_read; int bytes_read;
int bytes_processed=0; int bytes_processed=0;
int header_bytes; //, elapsed_time; int header_bytes; //, elapsed_time;
//printk("[BYPASS] BYPASS_RX_HANDLER IN...\n"); //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) { if (header_bytes> 0) {
bytes_read = rtf_get(fifo_bypass_phy_user2kern, &rx_bufferP[header_bytes],((bypass_proto2multicast_header_t *) (&rx_bufferP[0]))->size); bytes_read = rtf_get(fifo_bypass_phy_user2kern, &rx_bufferP[header_bytes],
// printk("BYTES_READ=%d\n",bytes_read); ((bypass_proto2multicast_header_t *) (&rx_bufferP[0]))->size);
if (bytes_read > 0) { // printk("BYTES_READ=%d\n",bytes_read);
num_bytesP=header_bytes+bytes_read; if (bytes_read > 0) {
emul_low_mutex_var=0; num_bytesP=header_bytes+bytes_read;
//printk("BYPASS_PHY SIGNAL MAC_LOW...\n"); emul_low_mutex_var=0;
pthread_cond_signal(&emul_low_cond); //printk("BYPASS_PHY SIGNAL MAC_LOW...\n");
} pthread_cond_signal(&emul_low_cond);
}
} }
// } // }
return 0; return 0;
} }
#else //USER_MODE #else //USER_MODE
/******************************************************************************************************/ /******************************************************************************************************/
void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer){ void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer)
/******************************************************************************************************/ {
// msg("[BYPASS] BYPASS RX_HANDLER IN ...\n"); /******************************************************************************************************/
if(Num_bytes >0){ if(Num_bytes >0) {
pthread_mutex_lock(&emul_low_mutex); #if !defined(ENABLE_NEW_MULTICAST)
while(!emul_low_mutex_var){ pthread_mutex_lock(&emul_low_mutex);
// msg("[BYPASS] BYPASS: WAIT MAC_LOW...\n"); while(!emul_low_mutex_var) {
pthread_cond_wait(&emul_low_cond, &emul_low_mutex); 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 #endif //USER_MODE
/******************************************************************************************************/ /******************************************************************************************************/
void bypass_signal_mac_phy(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, uint8_t is_master)
// char tt=1; {
/******************************************************************************************************/
if(Master_list_rx != oai_emulation.info.master_list){ if(Master_list_rx != oai_emulation.info.master_list) {
#ifndef USER_MODE #ifndef USER_MODE
rtf_put(fifo_mac_bypass,&tt,1); // the Rx window is still opened (Re)signal bypass_phy (emulate MAC signal) rtf_put(fifo_mac_bypass, &tt, 1);
#endif //USER_MODE /* the Rx window is still opened (Re)signal bypass_phy (emulate MAC signal) */
bypass_rx_data(frame,last_slot, next_slot); #endif
} bypass_rx_data(frame, last_slot, next_slot, is_master);
else Master_list_rx=0; } else {
Master_list_rx=0;
}
} }
#ifndef USER_MODE #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; int tx_bytes=0;
pthread_mutex_lock(&Tx_mutex); pthread_mutex_lock(&Tx_mutex);
while(!Tx_mutex_var){ while(!Tx_mutex_var) {
//msg("[BYPASS]RG WAIT USER_SPACE FIFO SIGNAL..\n"); pthread_cond_wait(&Tx_cond,&Tx_mutex);
pthread_cond_wait(&Tx_cond,&Tx_mutex); }
} Tx_mutex_var=0;
Tx_mutex_var=0; N_P=(int)((sizeP-sizeof (bypass_proto2multicast_header_t))/1000)+2;
N_P=(int)((sizeP-sizeof (bypass_proto2multicast_header_t))/1000)+2; tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],sizeof (bypass_proto2multicast_header_t)); sizeof (bypass_proto2multicast_header_t));
while(tx_bytes<sizeP){ while(tx_bytes<sizeP) {
if(sizeP-tx_bytes<=1000) if(sizeP-tx_bytes<=1000) {
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],sizeP-tx_bytes); tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],
else sizeP-tx_bytes);
tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],1000); } else {
} tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes],1000);
//RG_tx_mutex_var=0; }
pthread_mutex_unlock(&Tx_mutex); }
//RG_tx_mutex_var=0;
return tx_bytes; pthread_mutex_unlock(&Tx_mutex);
return tx_bytes;
} }
#endif #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)
/***************************************************************************/ {
unsigned int num_flows; /***************************************************************************/
bypass_msg_header_t *messg; unsigned int num_flows;
unsigned int byte_tx_count; bypass_msg_header_t *messg;
// eNB_transport_info_t *eNB_info;
int n_enb,n_ue, n_dci,total_tbs=0,total_size=0; LOG_D(EMU, "Entering bypass_tx [%s] for frame %d next_slot %d\n",
messg = (bypass_msg_header_t *) (&bypass_tx_buffer[sizeof (bypass_proto2multicast_header_t)]); map_int_to_str(transport_names, Type), frame, next_slot);
num_flows = 0;
messg->master_id = oai_emulation.info.master_id; //Master_id; int n_enb,n_ue, n_dci,total_tbs=0,total_size=0;
// messg->nb_master = oai_emulation.info.nb_master; messg = (bypass_msg_header_t *) (
messg->nb_enb = oai_emulation.info.nb_enb_local; //Master_id; &bypass_tx_buffer[sizeof (bypass_proto2multicast_header_t)]);
messg->nb_ue = oai_emulation.info.nb_ue_local; //Master_id; num_flows = 0;
messg->nb_flow = num_flows; messg->master_id = oai_emulation.info.master_id; //Master_id;
messg->frame = frame;
messg->subframe = next_slot>>1; messg->nb_enb = oai_emulation.info.nb_enb_local; //Master_id;
messg->nb_ue = oai_emulation.info.nb_ue_local; //Master_id;
byte_tx_count = sizeof (bypass_msg_header_t) + sizeof (bypass_proto2multicast_header_t); messg->nb_flow = num_flows;
messg->frame = frame;
if(Type==WAIT_PM_TRANSPORT){ messg->subframe = next_slot>>1;
messg->Message_type = WAIT_PM_TRANSPORT_INFO; messg->seq_num = seq_num_tx;
LOG_T(EMU,"[TX_DATA] WAIT SYNC PM TRANSPORT\n");
} seq_num_tx++;
else if(Type==WAIT_SM_TRANSPORT){
messg->Message_type = WAIT_SM_TRANSPORT_INFO; byte_tx_count = sizeof (bypass_msg_header_t) + sizeof (
LOG_T(EMU,"[TX_DATA] WAIT SYNC SM TRANSPORT\n"); bypass_proto2multicast_header_t);
}
else if(Type==SYNC_TRANSPORT){ if (Type == WAIT_PM_TRANSPORT) {
messg->Message_type = SYNC_TRANSPORT_INFO; messg->Message_type = EMU_TRANSPORT_INFO_WAIT_PM;
// make sure that sync messages from the masters are received in increasing order of master id LOG_T(EMU,"[TX_DATA] WAIT SYNC PM TRANSPORT\n");
sleep(oai_emulation.info.master_id+1); } else if (Type == WAIT_SM_TRANSPORT) {
LOG_T(EMU,"[TX_DATA] SYNC TRANSPORT\n"); messg->Message_type = EMU_TRANSPORT_INFO_WAIT_SM;
} LOG_T(EMU,"[TX_DATA] WAIT SYNC SM TRANSPORT\n");
else if(Type==ENB_TRANSPORT){ } else if (Type == SYNC_TRANSPORT) {
LOG_D(EMU,"[TX_DATA] ENB TRANSPORT\n"); messg->Message_type = EMU_TRANSPORT_INFO_SYNC;
messg->Message_type = ENB_TRANSPORT_INFO; /* make sure that sync messages from the masters are received in
total_size=0; * increasing order of master id
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++) { sleep(oai_emulation.info.master_id+1);
total_tbs=0; LOG_T(EMU,"[TX_DATA] SYNC TRANSPORT\n");
for (n_dci =0 ; } else if(Type==ENB_TRANSPORT) {
n_dci < (eNB_transport_info[n_enb].num_ue_spec_dci+ eNB_transport_info[n_enb].num_common_dci); LOG_D(EMU,"[TX_DATA] ENB TRANSPORT\n");
n_dci++) { messg->Message_type = EMU_TRANSPORT_INFO_ENB;
total_tbs +=eNB_transport_info[n_enb].tbs[n_dci]; total_size=0;
} total_tbs=0;
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) for (n_enb=oai_emulation.info.first_enb_local;
total_size = sizeof(eNB_transport_info_t)+total_tbs-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE; n_enb<(oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local);
else n_enb++) {
LOG_E(EMU,"[eNB]running out of memory for the eNB emulation transport buffer of size %d\n", MAX_TRANSPORT_BLOCKS_BUFFER_SIZE); total_tbs=0;
memcpy(&bypass_tx_buffer[byte_tx_count], (char*)&eNB_transport_info[n_enb], total_size); for (n_dci =0 ;
byte_tx_count +=total_size; n_dci < (eNB_transport_info[n_enb].num_ue_spec_dci+
} eNB_transport_info[n_enb].num_common_dci);
} n_dci++) {
else if (Type == UE_TRANSPORT){ total_tbs +=eNB_transport_info[n_enb].tbs[n_dci];
LOG_D(EMU,"[TX_DATA] UE TRANSPORT\n"); }
messg->Message_type = UE_TRANSPORT_INFO; if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) {
total_size=0; total_size = sizeof(eNB_transport_info_t)+total_tbs-
total_tbs=0; // compute the actual size of transport_blocks MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
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++){ } else {
for (n_enb=0;n_enb<UE_transport_info[n_ue].num_eNB;n_enb++) { LOG_E(EMU,
total_tbs+=UE_transport_info[n_ue].tbs[n_enb]; "[eNB]running out of memory for the eNB emulation transport buffer of size %d\n",
} MAX_TRANSPORT_BLOCKS_BUFFER_SIZE);
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) }
total_size = sizeof(UE_transport_info_t)+total_tbs-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE; memcpy(&bypass_tx_buffer[byte_tx_count], (char *)&eNB_transport_info[n_enb],
else total_size);
LOG_E(EMU,"[UE]running out of memory for the UE emulation transport buffer of size %d\n", MAX_TRANSPORT_BLOCKS_BUFFER_SIZE); byte_tx_count +=total_size;
memcpy(&bypass_tx_buffer[byte_tx_count], (char*)&UE_transport_info[n_ue], 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){ ((bypass_proto2multicast_header_t *) bypass_tx_buffer)->size = byte_tx_count -
messg->Message_type = RELEASE_TRANSPORT_INFO; sizeof (bypass_proto2multicast_header_t);
}else {
LOG_T(EMU,"[TX_DATA] UNKNOWN MSG \n"); 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); LOG_D(EMU, "Sent %d bytes [%s] with master_id %d and seq %"PRIuMAX"\n",
//if(mac_xface->frame%1000==0) byte_tx_count, map_int_to_str(transport_names, Type),
multicast_link_write_sock (oai_emulation.info.multicast_group, bypass_tx_buffer, byte_tx_count); messg->master_id, messg->seq_num);
} }
#ifndef USER_MODE #ifndef USER_MODE
/*********************************************************************************************************************/ /*********************************************************************************************************************/
int bypass_tx_handler(unsigned int fifo, int rw){ int bypass_tx_handler(unsigned int fifo, int rw)
/***************************************************************************/ {
// if(rw=='r'){ /***************************************************************************/
if(++N_R==N_P){ if(++N_R==N_P) {
//msg("[OPENAIR][RG_BYPASS] TX_handler..\n"); rtf_reset(fifo_bypass_phy_kern2user);
// pthread_mutex_lock(&RG_tx_mutex);
rtf_reset(fifo_bypass_phy_kern2user); Tx_mutex_var=1;
// pthread_mutex_lock(&RG_tx_mutex); N_R=0;
Tx_mutex_var=1;
N_R=0; pthread_cond_signal(&Tx_cond);
// pthread_mutex_unlock(&RG_tx_mutex);
pthread_cond_signal(&Tx_cond);
} }
// }
} }
#endif #endif
/*! \file phy_emulation.h /*! \file phy_emulation.h
* \brief specifies the data structure and variable for phy emulation * \brief specifies the data structure and variable for phy emulation
* \author Navid Nikaein, Raymomd Knopp and Hicham Anouar * \author Navid Nikaein, Raymomd Knopp and Hicham Anouar
* \date 2011 * \date 2011
* \version 1.0 * \version 1.1
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
//#include "SCHED/defs.h"
#include "proto.h"
//#include "UTIL/OCG/OCG.h"
#ifndef __BYPASS_SESSION_LAYER_DEFS_H__ #ifndef __BYPASS_SESSION_LAYER_DEFS_H__
# define __BYPASS_SESSION_LAYER_DEFS_H__ # define __BYPASS_SESSION_LAYER_DEFS_H__
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//#include "openair_defs.h" //#include "openair_defs.h"
#define WAIT_PM_TRANSPORT_INFO 0x1 typedef enum {
#define WAIT_SM_TRANSPORT_INFO 0x2 EMU_TRANSPORT_INFO_ERROR = 0x0,
#define SYNC_TRANSPORT_INFO 0x3 EMU_TRANSPORT_INFO_WAIT_PM,
#define ENB_TRANSPORT_INFO 0X4 EMU_TRANSPORT_INFO_WAIT_SM,
#define UE_TRANSPORT_INFO 0X5 EMU_TRANSPORT_INFO_SYNC,
#define RELEASE_TRANSPORT_INFO 0x6 EMU_TRANSPORT_INFO_ENB,
EMU_TRANSPORT_INFO_UE,
EMU_TRANSPORT_INFO_RELEASE
} emu_transport_info_t;
#define WAIT_PM_TRANSPORT 1 #define WAIT_PM_TRANSPORT 1
#define WAIT_SM_TRANSPORT 2 #define WAIT_SM_TRANSPORT 2
...@@ -41,10 +38,11 @@ ...@@ -41,10 +38,11 @@
#define BYPASS_RX_BUFFER_SIZE 64000 #define BYPASS_RX_BUFFER_SIZE 64000
#define BYPASS_TX_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 { typedef struct {
u32 pbch_flag:1; u32 pbch_flag:1;
u32 pss:2; u32 pss:2;
...@@ -71,8 +69,10 @@ typedef struct { ...@@ -71,8 +69,10 @@ typedef struct {
u8 prach_flag:1; // 0=none,1=active u8 prach_flag:1; // 0=none,1=active
u8 prach_id:6; // this is the PHY preamble index for the prach u8 prach_id:6; // this is the PHY preamble index for the prach
} UE_cntl; } UE_cntl;
#define MAX_TRANSPORT_BLOCKS_BUFFER_SIZE 16384 #define MAX_TRANSPORT_BLOCKS_BUFFER_SIZE 16384
#define MAX_NUM_DCI 5 #define MAX_NUM_DCI 5
typedef struct { typedef struct {
eNB_cntl cntl; eNB_cntl cntl;
u8 num_common_dci; u8 num_common_dci;
...@@ -85,15 +85,6 @@ typedef struct { ...@@ -85,15 +85,6 @@ typedef struct {
u8 transport_blocks[MAX_TRANSPORT_BLOCKS_BUFFER_SIZE]; u8 transport_blocks[MAX_TRANSPORT_BLOCKS_BUFFER_SIZE];
} __attribute__ ((__packed__)) eNB_transport_info_t ; } __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 { typedef struct {
UE_cntl cntl; UE_cntl cntl;
u8 num_eNB; u8 num_eNB;
...@@ -113,54 +104,12 @@ typedef struct bypass_msg_header { ...@@ -113,54 +104,12 @@ typedef struct bypass_msg_header {
unsigned int nb_ue; /*! \brief */ unsigned int nb_ue; /*! \brief */
unsigned int nb_flow; /*! \brief */ unsigned int nb_flow; /*! \brief */
unsigned int frame; unsigned int frame;
unsigned int subframe; unsigned int subframe;
uint64_t seq_num;
}__attribute__ ((__packed__)) bypass_msg_header_t; }__attribute__ ((__packed__)) bypass_msg_header_t;
typedef struct bypass_proto2multicast_header_t { typedef struct bypass_proto2multicast_header_t {
unsigned int size; unsigned int size;
} bypass_proto2multicast_header_t; } bypass_proto2multicast_header_t;
#endif /* __BYPASS_SESSION_LAYER_DEFS_H__ */
/* // 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 //
/*! \file phy_emulation.c /*! \file phy_emulation.c
* \brief implements the underlying protocol for emulated data exchange over Ethernet using IP multicast * \brief implements the underlying protocol for emulated data exchange over Ethernet using IP multicast
* \author Navid Nikaein * \author Navid Nikaein
* \date 2011 * \date 2011
* \version 1.0 * \version 1.1
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
#include "PHY/defs.h" #include "PHY/defs.h"
#include "PHY/extern.h" #include "PHY/extern.h"
#include "defs.h" #include "defs.h"
#include "extern.h" #include "extern.h"
#include "proto.h"
#include "UTIL/OCG/OCG.h" #include "UTIL/OCG/OCG.h"
#include "UTIL/OCG/OCG_extern.h" #include "UTIL/OCG/OCG_extern.h"
#include "UTIL/LOG/log.h" #include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/LOG/vcd_signal_dumper.h"
extern unsigned int Master_list_rx; extern unsigned int Master_list_rx;
//extern unsigned short NODE_ID[1];
extern unsigned char NB_INST; extern unsigned char NB_INST;
//#define DEBUG_CONTROL 1 //#define DEBUG_CONTROL 1
//#define DEBUG_EMU 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); void emu_transport_sync(void)
Master_list_rx=oai_emulation.info.master_list-1; // just wait to recieve the master 0 msg {
bypass_rx_data(0,0,0); LOG_D(EMU, "Entering EMU transport SYNC is primary master %d\n",
} oai_emulation.info.is_primary_master);
else {
bypass_rx_data(0,0,0); if (oai_emulation.info.is_primary_master == 0) {
bypass_tx_data(WAIT_PM_TRANSPORT,0,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); // i received the sync from all secondary masters
bypass_rx_data(0,0,0); 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 LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n");
emu_tx_status = SYNCED_TRANSPORT;
} }
// else emu_transport_sync(last_slot); LOG_D(EMU, "Leaving EMU transport SYNC is primary master %d\n",
LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \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 ){ void emu_transport(unsigned int frame, unsigned int last_slot,
unsigned int next_slot,lte_subframe_t direction,
if (ethernet_flag == 0) unsigned char frame_type,
return; int ethernet_flag )
{
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_IN); if (ethernet_flag == 0) {
return;
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) ){ vcd_signal_dumper_dump_function_by_name(
emu_transport_UL(frame, last_slot , next_slot); 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){ void emu_transport_UL(unsigned int frame, unsigned int last_slot,
// bypass_rx_data(last_slot); unsigned int next_slot)
if (oai_emulation.info.nb_enb_local>0) // send in DL if {
bypass_tx_data(ENB_TRANSPORT,frame, next_slot); LOG_D(EMU, "Entering EMU transport UL, is primary master %d\n",
else oai_emulation.info.is_primary_master);
bypass_tx_data(WAIT_SM_TRANSPORT,frame,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);
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); void emu_transport_release(void)
} {
else { // I am the master bypass_tx_data(RELEASE_TRANSPORT,0,0);
// bypass_tx_data(WAIT_TRANSPORT,last_slot); LOG_E(EMU," tx RELEASE_TRANSPORT \n");
}
if (oai_emulation.info.nb_enb_local>0) // send in DL if
bypass_tx_data(ENB_TRANSPORT,frame, next_slot);
else
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot); 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) { unsigned int emul_rx_data(void)
{
return(0);
if (oai_emulation.info.is_primary_master==0){
// bypass_rx_data(last_slot, next_slot);
if (oai_emulation.info.nb_ue_local>0)
bypass_tx_data(UE_TRANSPORT,frame, next_slot);
else
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot);
}
else {
// bypass_tx_data(WAIT_TRANSPORT,last_slot);
if (oai_emulation.info.nb_ue_local>0)
bypass_tx_data(UE_TRANSPORT,frame, next_slot);
else
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot);
}
} }
void emu_transport_release(void){ unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer,
bypass_tx_data(RELEASE_TRANSPORT,0,0); unsigned int Nbytes)
LOG_E(EMU," tx RELEASE_TRANSPORT \n"); {
} unsigned short Rx_size=0;
return (Rx_size+2);
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_data(void){ void clear_eNB_transport_info(u8 nb_eNB)
return(0); {
} u8 eNB_id;
unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer, unsigned int Nbytes){ for (eNB_id=0; eNB_id<nb_eNB; eNB_id++) {
unsigned short Rx_size=0; eNB_transport_info_TB_index[eNB_id]=0;
return (Rx_size+2); 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) { void clear_UE_transport_info(u8 nb_UE)
u8 eNB_id; {
u8 UE_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) { for (UE_id=0; UE_id<nb_UE; UE_id++) {
u8 UE_id; UE_transport_info_TB_index[UE_id]=0;
memset((void *)&UE_transport_info[UE_id].cntl,0,sizeof(UE_cntl));
for (UE_id=0;UE_id<nb_UE;UE_id++) { }
UE_transport_info_TB_index[UE_id]=0; // LOG_T(EMU, "EMUL clear_UE_transport_info\n");
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 #ifdef DEBUG_EMU
LOG_D(EMU," pbch fill phy eNB %d vars for slot %d \n",enb_id, next_slot); LOG_D(EMU, " pbch fill phy eNB %d vars for slot %d fault %d\n",
#endif enb_id, next_slot, network_fault);
// eNB #endif
// PBCH : copy payload // 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; *(u32 *)PHY_vars_eNB_g[enb_id]->pbch_pdu =
/* LOG_I(EMU," RX slot %d ENB TRANSPORT pbch payload %d pdu[0] %d pdu[0] %d \n", eNB_transport_info[enb_id].cntl.pbch_payload;
next_slot , /* LOG_I(EMU," RX slot %d ENB TRANSPORT pbch payload %d pdu[0] %d pdu[0] %d \n",
eNB_transport_info[enb_id].cntl.pbch_payload, next_slot ,
((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[0], eNB_transport_info[enb_id].cntl.pbch_payload,
((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[1]); ((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[0],
((u8*)PHY_vars_eNB_g[enb_id]->pbch_pdu)[1]);
*/ */
// } // }
//CFI //CFI
// not needed yet // not needed yet
//PHICH //PHICH
// to be added later // to be added later
//DCI //DCI
nb_total_dci= eNB_transport_info[enb_id].num_ue_spec_dci+ eNB_transport_info[enb_id].num_common_dci; nb_total_dci= eNB_transport_info[enb_id].num_ue_spec_dci+
PHY_vars_eNB_g[enb_id]->num_ue_spec_dci[(next_slot>>1)&1] = eNB_transport_info[enb_id].num_ue_spec_dci; eNB_transport_info[enb_id].num_common_dci;
PHY_vars_eNB_g[enb_id]->num_common_dci[(next_slot>>1)&1] = 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;
if (nb_total_dci >0) { PHY_vars_eNB_g[enb_id]->num_common_dci[(next_slot>>1)&1] =
eNB_transport_info[enb_id].num_common_dci;
memcpy(PHY_vars_eNB_g[enb_id]->dci_alloc[(next_slot>>1)&1],
&eNB_transport_info[enb_id].dci_alloc, if (nb_total_dci >0) {
(nb_total_dci)* sizeof(DCI_ALLOC_t));
memcpy(PHY_vars_eNB_g[enb_id]->dci_alloc[(next_slot>>1)&1],
&eNB_transport_info[enb_id].dci_alloc,
n_dci_dl=0; (nb_total_dci)* sizeof(DCI_ALLOC_t));
// fill dlsch_eNB structure from DCI
for (n_dci =0 ; n_dci_dl=0;
n_dci < nb_total_dci; // fill dlsch_eNB structure from DCI
n_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 //exclude ul dci
#ifdef DEBUG_EMU if (eNB_transport_info[enb_id].dci_alloc[n_dci_dl].format > 0) {
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]);
#ifdef DEBUG_EMU #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 #endif
break; switch (eNB_transport_info[enb_id].dlsch_type[n_dci_dl]) {
case 1: //RA: case 0: //SI:
memcpy(PHY_vars_eNB_g[enb_id]->dlsch_eNB_SI->harq_processes[0]->b,
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].transport_blocks[payload_offset], eNB_transport_info[enb_id].tbs[n_dci_dl]);
eNB_transport_info[enb_id].tbs[n_dci_dl]);
#ifdef DEBUG_EMU #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 #endif
break; break;
case 1: //RA:
case 2://TB0:
harq_pid = eNB_transport_info[enb_id].harq_pid[n_dci_dl]; memcpy(PHY_vars_eNB_g[enb_id]->dlsch_eNB_ra->harq_processes[0]->b,
ue_id = eNB_transport_info[enb_id].ue_id[n_dci_dl]; &eNB_transport_info[enb_id].transport_blocks[payload_offset],
PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][0]->rnti= eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti; eNB_transport_info[enb_id].tbs[n_dci_dl]);
dlsch_eNB = PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][0];
#ifdef DEBUG_EMU #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", LOG_D(EMU, "RA eNB_transport_info[enb_id].tbs[n_dci_dl]%d \n",
enb_id, ue_id, eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti, eNB_transport_info[enb_id].tbs[n_dci_dl]);
n_dci_dl, harq_pid, eNB_transport_info[enb_id].tbs[n_dci_dl]); #endif
int i; break;
for (i=0;i<eNB_transport_info[enb_id].tbs[n_dci_dl];i++) case 2://TB0:
msg("%x.",(unsigned char) eNB_transport_info[enb_id].transport_blocks[payload_offset+i]); harq_pid = eNB_transport_info[enb_id].harq_pid[n_dci_dl];
#endif ue_id = eNB_transport_info[enb_id].ue_id[n_dci_dl];
memcpy(dlsch_eNB->harq_processes[harq_pid]->b, PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][0]->rnti=
&eNB_transport_info[enb_id].transport_blocks[payload_offset], eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti;
eNB_transport_info[enb_id].tbs[n_dci_dl]); dlsch_eNB = PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][0];
break; #ifdef DEBUG_EMU
LOG_D(EMU,
case 3://TB1: " enb_id %d ue id is %d rnti is %x dci index %d, harq_pid %d tbs %d \n",
harq_pid = eNB_transport_info[enb_id].harq_pid[n_dci_dl]; enb_id, ue_id, eNB_transport_info[enb_id].dci_alloc[n_dci_dl].rnti,
ue_id = eNB_transport_info[enb_id].ue_id[n_dci_dl]; n_dci_dl, harq_pid, eNB_transport_info[enb_id].tbs[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; int i;
dlsch_eNB = PHY_vars_eNB_g[enb_id]->dlsch_eNB[ue_id][1]; for (i=0; i<eNB_transport_info[enb_id].tbs[n_dci_dl]; i++) {
LOG_T(EMU, "%x.",
memcpy(dlsch_eNB->harq_processes[harq_pid]->b, (unsigned char) eNB_transport_info[enb_id].transport_blocks[payload_offset+i]);
&eNB_transport_info[enb_id].transport_blocks[payload_offset], }
eNB_transport_info[enb_id].tbs[n_dci_dl]); #endif
break; 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]);
payload_offset += eNB_transport_info[enb_id].tbs[n_dci_dl]; break;
} case 3://TB1:
n_dci_dl++; 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 #ifdef DEBUG_EMU
LOG_D(EMU, "Fill phy eNB vars done next slot %d !\n", next_slot); LOG_D(EMU, "Fill phy eNB vars done next slot %d !\n", next_slot);
#endif #endif
} }
} }
void fill_phy_ue_vars(unsigned int ue_id, unsigned int last_slot) { void fill_phy_ue_vars(unsigned int ue_id, unsigned int last_slot)
{
int n_enb;//index int n_enb;//index
int enb_id; int enb_id;
// int harq_id; // int harq_id;
// int payload_offset = 0; // int payload_offset = 0;
unsigned short rnti; unsigned short rnti;
unsigned int harq_pid; unsigned int harq_pid;
LTE_UE_ULSCH_t *ulsch; LTE_UE_ULSCH_t *ulsch;
PUCCH_FMT_t pucch_format; PUCCH_FMT_t pucch_format;
// u8 ue_transport_info_index[NUMBER_OF_eNB_MAX]; // u8 ue_transport_info_index[NUMBER_OF_eNB_MAX];
u8 subframe = (last_slot+1)>>1; u8 subframe = (last_slot+1)>>1;
memcpy (&ue_cntl_delay[ue_id][(last_slot+1)%2], memcpy (&ue_cntl_delay[ue_id][(last_slot+1)%2],
&UE_transport_info[ue_id].cntl, &UE_transport_info[ue_id].cntl,
sizeof(UE_cntl)); sizeof(UE_cntl));
#ifdef DEBUG_EMU #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", LOG_D(EMU,
last_slot,subframe,ue_id, "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",
UE_transport_info[ue_id].cntl.prach_flag,
ue_cntl_delay[ue_id][last_slot%2].prach_flag, last_slot,subframe,ue_id,
UE_transport_info[ue_id].cntl.prach_id, UE_transport_info[ue_id].cntl.prach_flag,
ue_cntl_delay[ue_id][last_slot%2].prach_id, ue_cntl_delay[ue_id][last_slot%2].prach_flag,
UE_transport_info[ue_id].cntl.sr, UE_transport_info[ue_id].cntl.prach_id,
ue_cntl_delay[ue_id][last_slot%2].sr, ue_cntl_delay[ue_id][last_slot%2].prach_id,
UE_transport_info[ue_id].cntl.pucch_sel, UE_transport_info[ue_id].cntl.sr,
ue_cntl_delay[ue_id][last_slot%2].pucch_sel ); ue_cntl_delay[ue_id][last_slot%2].sr,
#endif UE_transport_info[ue_id].cntl.pucch_sel,
//ue_cntl_delay[subframe%2].prach_flag ; ue_cntl_delay[ue_id][last_slot%2].pucch_sel );
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 #endif
for (n_enb=0; n_enb < UE_transport_info[ue_id].num_eNB; n_enb++){ //ue_cntl_delay[subframe%2].prach_flag ;
#ifdef DEBUG_EMU PHY_vars_UE_g[ue_id]->generate_prach =
/* LOG_D(EMU,"Setting ulsch vars for ue %d rnti %x harq pid is %d \n", ue_cntl_delay[ue_id][last_slot%2].prach_flag;//UE_transport_info[ue_id].cntl.prach_flag;
ue_id, UE_transport_info[ue_id].rnti[n_enb], if (PHY_vars_UE_g[ue_id]->generate_prach == 1) {
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]); // 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 #endif
rnti = UE_transport_info[ue_id].rnti[n_enb]; rnti = UE_transport_info[ue_id].rnti[n_enb];
enb_id = UE_transport_info[ue_id].eNB_id[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; 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]; harq_pid = UE_transport_info[ue_id].harq_pid[n_enb];
//ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]; //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[0] =
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; ue_cntl_delay[ue_id][last_slot%2].pusch_ri & 0x1;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[1] =
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[0]= ue_cntl_delay[ue_id][last_slot%2].pusch_ack & 0x1; (ue_cntl_delay[ue_id][last_slot%2].pusch_ri>>1) & 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; PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[0]=
ue_cntl_delay[ue_id][last_slot%2].pusch_ack & 0x1;
if (last_slot%2 == 1 ) { PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[1]=
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O = ue_cntl_delay[ue_id][last_slot%2].length_uci; (ue_cntl_delay[ue_id][last_slot%2].pusch_ack>>1) & 0x1;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->uci_format = ue_cntl_delay[ue_id][last_slot%2].uci_format; //*(u32 *)ulsch->o = ue_cntl_delay[ue_id][last_slot%2].pusch_uci;
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o, if (last_slot%2 == 1 ) {
ue_cntl_delay[ue_id][last_slot%2].pusch_uci, PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O =
MAX_CQI_BYTES); ue_cntl_delay[ue_id][last_slot%2].length_uci;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->uci_format =
ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]; ue_cntl_delay[ue_id][last_slot%2].uci_format;
// 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", memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o,
ue_id, subframe, last_slot, enb_id, ue_id, harq_pid, ue_cntl_delay[ue_id][last_slot%2].pusch_uci,
((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1, MAX_CQI_BYTES);
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O);
} ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id];
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->harq_processes[harq_pid]->b, // if (((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1)
UE_transport_info[ue_id].transport_blocks, LOG_D(EMU,
UE_transport_info[ue_id].tbs[enb_id]); "[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,
//ue_transport_info_index[enb_id]+=UE_transport_info[ue_id].tbs[enb_id]; ((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1,
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O);
//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]); 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]);
}
} }
/*! \file extern.h /*! \file extern.h
* \brief specifies the extern variables for phy emulation * \brief specifies the extern variables for phy emulation
* \author Navid Nikaein and Raymomd Knopp and Hicham Anouar * \author Navid Nikaein and Raymomd Knopp and Hicham Anouar
* \date 2011 * \date 2011
* \version 1.0 * \version 1.1
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
#ifndef __BYPASS_SESSION_LAYER_EXTERN_H__ #ifndef __BYPASS_SESSION_LAYER_EXTERN_H__
# define __BYPASS_SESSION_LAYER_EXTERN_H__ # define __BYPASS_SESSION_LAYER_EXTERN_H__
...@@ -23,16 +23,17 @@ extern unsigned char emu_rx_status; ...@@ -23,16 +23,17 @@ extern unsigned char emu_rx_status;
//extern unsigned short Master_id; //extern unsigned short Master_id;
//extern unsigned int Is_primary_master; //extern unsigned int Is_primary_master;
#if !defined(ENABLE_NEW_MULTICAST)
extern pthread_mutex_t emul_low_mutex; extern pthread_mutex_t emul_low_mutex;
extern pthread_cond_t emul_low_cond; extern pthread_cond_t emul_low_cond;
extern char emul_low_mutex_var; extern char emul_low_mutex_var;
extern pthread_mutex_t Tx_mutex; extern pthread_mutex_t Tx_mutex;
extern pthread_cond_t Tx_cond; extern pthread_cond_t Tx_cond;
extern char Tx_mutex_var; extern char Tx_mutex_var;
#endif
extern rx_handler_t rx_handler;
extern int (*rx_handler) (unsigned char,char*,int); extern tx_handler_t tx_handler;
extern int (*tx_handler) (unsigned char,char*, unsigned int*, unsigned int*);
extern eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX]; extern eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX];
extern u16 eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX]; extern u16 eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX];
......
/*! \file multicast.h /*! \file multicast.h
* \brief * \brief
* \author Lionel Gauthier and Navid Nikaein * \author Lionel Gauthier and Navid Nikaein
* \date 2011 * \date 2011
* \version 1.0 * \version 1.1
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
...@@ -26,110 +26,117 @@ ...@@ -26,110 +26,117 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/select.h> #include <sys/select.h>
//#include "openair_defs.h"
//#include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
//#include "openair_defs.h"
#define MULTICAST_LINK_C #define MULTICAST_LINK_C
#include "socket.h" #include "socket.h"
#include "multicast_link.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 #ifdef USER_MODE
//#include <rtai.h>
# define msg printf
# include "UTIL/LOG/log.h" # include "UTIL/LOG/log.h"
#endif //USER_MODE #endif //USER_MODE
//#include "extern.h"
extern unsigned short Master_id; extern unsigned short Master_id;
#define MULTICAST_LINK_NUM_GROUPS 4 #define MULTICAST_LINK_NUM_GROUPS 4
char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS] = { char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS] = {
"239.0.0.161\0", "239.0.0.161",
"239.0.0.162\0", "239.0.0.162",
"239.0.0.163\0", "239.0.0.163",
"239.0.0.164\0" "239.0.0.164"
}; };
static multicast_group_t group_list[MULTICAST_LINK_NUM_GROUPS]; 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() */ /* Socket file descriptors we want to wake up for, using select() */
static int highsock; /* Highest #'d file descriptor, needed for 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 pthread_t main_loop_thread;
static void (*rx_handler) (unsigned int, char*); #endif
static unsigned char multicast_group; static void (*rx_handler) (unsigned int, char *);
static char *multicast_if; static unsigned char multicast_group;
static char *multicast_if;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
multicast_link_init () multicast_link_init ()
{ {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int group; int group;
int multicast_loop; int multicast_loop;
int reuse_addr = 1; /* Used so we can re-bind to our port int reuse_addr = 1;
while a previous connection is still static struct ip_mreq command;
in TIME_WAIT state. */ struct sockaddr_in sin;
static struct ip_mreq command; // struct ifreq ifr;
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);
// for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) {
multicast_loop = 0; strcpy (group_list[group].host_addr, multicast_group_list[group]);
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_MULTICAST_LOOP, &multicast_loop, sizeof (multicast_loop)) < 0) { group_list[group].port = 46014 + group;
msg ("[MULTICAST] ERROR: %s line %d multicast_link_main_loop() IP_MULTICAST_LOOP %m", __FILE__, __LINE__); group_list[group].socket = make_socket_inet(
exit (EXIT_FAILURE); SOCK_DGRAM,
} &group_list[group].port, &sin);
// Join the broadcast group:
command.imr_multiaddr.s_addr = inet_addr (group_list[group].host_addr); LOG_D(EMU, "multicast_link_init(): Created socket %d for group %d, port %d\n",
command.imr_interface.s_addr = htonl (INADDR_ANY); group_list[group].socket,group,group_list[group].port);
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);
}
/* 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)); #if !defined(ENABLE_TCP_MULTICAST)
group_list[group].sock_remote_addr.sin_family = AF_INET; /* Make the socket blocking */
group_list[group].sock_remote_addr.sin_addr.s_addr = inet_addr (multicast_group_list[group]); socket_setnonblocking(group_list[group].socket);
group_list[group].sock_remote_addr.sin_port = htons (group_list[group].port); #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 ...@@ -137,86 +144,69 @@ void
multicast_link_build_select_list () multicast_link_build_select_list ()
{ {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int group; int group;
/* First put together fd_set for select(), which will /* First put together fd_set for select(), which will
consist of the sock veriable in case a new connection consist of the sock veriable in case a new connection
is coming in, plus all the sockets we have already is coming in, plus all the sockets we have already
accepted. */ accepted. */
/* FD_ZERO() clears out the fd_set called socks, so that /* FD_ZERO() clears out the fd_set called socks, so that
it doesn't contain any file descriptors. */ it doesn't contain any file descriptors. */
FD_ZERO (&socks); FD_ZERO (&socks);
/* Loops through all the possible connections and adds /* Loops through all the possible connections and adds
those sockets to the fd_set */ those sockets to the fd_set */
for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) { for (group = 0; group < MULTICAST_LINK_NUM_GROUPS; group++) {
if (group_list[group].socket != 0) { if (group_list[group].socket != 0) {
FD_SET (group_list[group].socket, &socks); FD_SET (group_list[group].socket, &socks);
if (group_list[group].socket > highsock) if (group_list[group].socket > highsock) {
highsock = group_list[group].socket; highsock = group_list[group].socket;
}
}
} }
}
} }
//------------------------------------------------------------------------------
void void
multicast_link_read_data (int groupP) multicast_link_read_data (int groupP)
{ {
//------------------------------------------------------------------------------ int num_bytes;
#ifdef BYPASS_PHY if ((groupP <= MULTICAST_LINK_NUM_GROUPS) && (groupP >= 0)) {
//pthread_mutex_lock(&Bypass_phy_wr_mutex); if ((num_bytes = recvfrom (group_list[groupP].socket,
// while(Bypass_phy_wr){ group_list[groupP].rx_buffer, 40000, 0, 0, 0)) < 0) {
// msg("[Multicast read] BYPASS_PHY_NOT_YET READY, Waiting for signal\n"); LOG_E(EMU, "[MULTICAST] recvfrom has failed (%d:%s)\n (%s:%d)\n",
// pthread_cond_wait(&Bypass_phy_wr_cond,&Bypass_phy_wr_mutex); errno, strerror(errno), __FILE__, __LINE__);
// } } else {
//msg("[Multicast read] BYPASS_PHY TX Signal\n"); rx_handler(num_bytes,group_list[groupP].rx_buffer);
//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__);
} else { } else {
// msg("multicast_link_read_data: groupP=%d,rx_buffer = %p,NUm_bytes=%d\n",groupP,group_list[groupP].rx_buffer,num_bytes ); LOG_E(EMU, "[MULTICAST] ERROR: groupP out of bounds %d\n", groupP);
//msg("MULTICAST calling rx_handler\n");
rx_handler(num_bytes,group_list[groupP].rx_buffer);
} }
}
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 void
multicast_link_read () 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 /* Run through our sockets and check to see if anything
happened with them, if so 'service' them. */ happened with them, if so 'service' them. */
for (group = multicast_group; group < MULTICAST_LINK_NUM_GROUPS ; group++) { for (group = multicast_group; group < MULTICAST_LINK_NUM_GROUPS ; group++) {
if (FD_ISSET (group_list[group].socket, &socks)) { if (FD_ISSET (group_list[group].socket, &socks)) {
multicast_link_read_data (group); multicast_link_read_data (group);
break; break;
} }
} /* for (all entries in queue) */ } /* for (all entries in queue) */
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -224,73 +214,89 @@ int ...@@ -224,73 +214,89 @@ int
multicast_link_write_sock (int groupP, char *dataP, uint32_t sizeP) multicast_link_write_sock (int groupP, char *dataP, uint32_t sizeP)
{ {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int 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) { if ((num = sendto (group_list[groupP].socket, dataP, sizeP, 0,
fprintf (stderr, "ERROR: %s line %d multicast_link_write_sock()/sendto() %m", __FILE__, __LINE__); (struct sockaddr *) &group_list[groupP].sock_remote_addr,
} sizeof (group_list[groupP].sock_remote_addr))) < 0) {
return num; LOG_E(EMU, "[MULTICAST] sendto has failed (%d:%s)\n (%s:%d)\n",
errno, strerror(errno),
__FILE__, __LINE__);
}
return num;
} }
//------------------------------------------------------------------------------ int multicast_link_read_data_from_sock(uint8_t is_master)
void *
multicast_link_main_loop (void *param)
{ {
//------------------------------------------------------------------------------ struct timeval timeout, *timeout_p;
struct timeval timeout; /* Timeout for select */ int readsocks; /* Number of sockets ready for reading */
int readsocks; /* Number of sockets ready for reading */
#ifdef USER_MODE 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 (); 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) { if (readsocks < 0) {
LOG_E(EMU, "Multicast select failed (%d:%s)\n", errno, strerror(errno)); LOG_E(EMU, "Multicast select failed (%d:%s)\n", errno, strerror(errno));
// exit(); exit(EXIT_FAILURE);
} else if (readsocks > 0) { } else if (readsocks > 0) {
//msg("calling multicast link read\n"); LOG_D(EMU, "Multicast Normal read\n");
multicast_link_read (); multicast_link_read();
// usleep(1);
} else { } else {
/* Timeout */ /* Timeout */
LOG_I(EMU, "Multicast select time-out\n"); LOG_I(EMU, "Multicast select time-out\n");
return 1;
} }
} return 0;
#ifdef USER_MODE }
#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 *),
void unsigned char multicast_group, char *multicast_ifname)
multicast_link_start ( void (*rx_handlerP) (unsigned int, char*), unsigned char multicast_group, char * multicast_ifname)
{ {
//----------------------------------------------------------------------------- rx_handler = rx_handlerP;
rx_handler = rx_handlerP; multicast_group = multicast_group;
multicast_group = multicast_group; multicast_if = multicast_ifname;
multicast_if = multicast_ifname; LOG_I(EMU, "[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n",
msg("[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n", (multicast_if == NULL) ? "not specified" : multicast_if, multicast_group,
(multicast_if == NULL) ? "not specified" : multicast_if, multicast_group, rx_handler); rx_handler);
#ifdef BYPASS_PHY
// pthread_mutex_init(&Bypass_phy_wr_mutex,NULL); multicast_link_init ();
//pthread_cond_init(&Bypass_phy_wr_cond,NULL); #if ! defined(ENABLE_NEW_MULTICAST)
//Bypass_phy_wr=0; LOG_D(EMU, "[MULTICAST] multicast link start thread\n");
#endif //BYPASS_PHY if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop,
multicast_link_init (); NULL) != 0) {
msg("[MULTICAST] multicast link start thread\n"); LOG_E(EMU, "[MULTICAST LINK] Error in pthread_create (%d:%s)\n",
if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop, NULL) != 0) { errno, strerror(errno));
msg ("[MULTICAST LINK] Thread started\n"); exit(EXIT_FAILURE);
exit (-2); } else {
} else { pthread_detach(main_loop_thread); // disassociate from parent
pthread_detach (main_loop_thread); // disassociate from parent LOG_I(EMU, "[MULTICAST LINK] Thread detached\n");
msg ("[MULTICAST LINK] Thread detached\n"); }
#endif
}
} }
/*! \file multicast.h /*! \file multicast.h
* \brief * \brief
* \author Lionel Gauthier and Navid Nikaein * \author Lionel Gauthier and Navid Nikaein
* \date 2011 * \date 2011
* \version 1.0 * \version 1.1
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
#ifndef __MULTICAST_LINK_H__ #ifndef __MULTICAST_LINK_H__
# define __MULTICAST_LINK_H__ # define __MULTICAST_LINK_H__
...@@ -18,27 +18,24 @@ ...@@ -18,27 +18,24 @@
# endif # endif
# include "stdint.h" # include "stdint.h"
private_multicast_link (typedef struct multicast_group_t { private_multicast_link (typedef struct multicast_group_t {
int socket; int socket;
struct sockaddr_in sock_remote_addr;
char host_addr[16]; char host_addr[16];
uint16_t port; uint16_t port;
struct sockaddr_in sock_remote_addr;
char rx_buffer[40000]; char rx_buffer[40000];
} multicast_group_t;) } multicast_group_t;)
private_multicast_link(void multicast_link_init ()); private_multicast_link(void multicast_link_init ());
private_multicast_link(void multicast_link_read_data (int groupP)); private_multicast_link(void multicast_link_read_data (int groupP));
private_multicast_link(void multicast_link_read ()); private_multicast_link(void multicast_link_read ());
private_multicast_link(void *multicast_link_main_loop (void *param)); 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(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)); public_multicast_link(void multicast_link_start ( void (*rx_handlerP) (unsigned int, char*), unsigned char multicast_group, char * multicast_ifname));
#ifdef BYPASS_PHY # ifdef BYPASS_PHY
public_multicast_link( pthread_mutex_t Bypass_phy_wr_mutex); public_multicast_link(pthread_mutex_t Bypass_phy_wr_mutex);
public_multicast_link( pthread_cond_t Bypass_phy_wr_cond); public_multicast_link(pthread_cond_t Bypass_phy_wr_cond);
public_multicast_link( char Bypass_phy_wr); public_multicast_link(char Bypass_phy_wr);
#endif //BYPASS_PHY # endif //BYPASS_PHY
#endif #endif
/*! \file netlink_init.c /*! \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 * \author Navid Nikaein and Raymomd Knopp
* \date 2011 * \date 2011
* \version 1.0 * \version 1.0
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/netlink.h> #include <linux/netlink.h>
...@@ -25,62 +25,50 @@ struct msghdr nas_msg; ...@@ -25,62 +25,50 @@ struct msghdr nas_msg;
#define GRAAL_NETLINK_ID 31 #define GRAAL_NETLINK_ID 31
int netlink_init(void) { int netlink_init(void)
{
int ret;
int ret;
nas_sock_fd = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID);
if (nas_sock_fd == -1) {
nas_sock_fd = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID); printf("[NETLINK] Error opening socket %d\n",nas_sock_fd);
if (nas_sock_fd==-1) { return(-1);
printf("[NETLINK] Error opening socket %d\n",nas_sock_fd); }
return(-1); printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd);
}
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);
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;
memset(&nas_src_addr, 0, sizeof(nas_src_addr)); nas_src_addr.nl_pid = 1;//getpid(); /* self pid */
nas_src_addr.nl_family = AF_NETLINK; nas_src_addr.nl_groups = 0; /* not in mcast groups */
nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ ret = bind(nas_sock_fd, (struct sockaddr *)&nas_src_addr,
nas_src_addr.nl_groups = 0; /* not in mcast groups */ sizeof(nas_src_addr));
ret = bind(nas_sock_fd, (struct sockaddr*)&nas_src_addr,
sizeof(nas_src_addr)); printf("[NETLINK] bind returns %d\n",ret);
printf("[NETLINK] bind returns %d\n",ret); memset(&nas_dest_addr, 0, sizeof(nas_dest_addr));
nas_dest_addr.nl_family = AF_NETLINK;
memset(&nas_dest_addr, 0, sizeof(nas_dest_addr)); nas_dest_addr.nl_pid = 0; /* For Linux Kernel */
nas_dest_addr.nl_family = AF_NETLINK; nas_dest_addr.nl_groups = 0; /* unicast */
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=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); nas_nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
/* Fill the netlink message header */ nas_nlh->nlmsg_pid = 1;//getpid(); /* self pid */
nas_nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nas_nlh->nlmsg_flags = 0;
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;
nas_iov.iov_base = (void *)nas_nlh; memset(&nas_msg,0,sizeof(nas_msg));
nas_iov.iov_len = nas_nlh->nlmsg_len; nas_msg.msg_name = (void *)&nas_dest_addr;
memset(&nas_msg,0,sizeof(nas_msg)); nas_msg.msg_namelen = sizeof(nas_dest_addr);
nas_msg.msg_name = (void *)&nas_dest_addr; nas_msg.msg_iov = &nas_iov;
nas_msg.msg_namelen = sizeof(nas_dest_addr); nas_msg.msg_iovlen = 1;
nas_msg.msg_iov = &nas_iov;
nas_msg.msg_iovlen = 1; /* Read message from kernel */
memset(nas_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
/* Read message from kernel */ return(nas_sock_fd);
memset(nas_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
return(nas_sock_fd);
} }
...@@ -5,12 +5,18 @@ ...@@ -5,12 +5,18 @@
* \version 1.0 * \version 1.0
* \company Eurecom * \company Eurecom
* \email: navid.nikaein@eurecom.fr * \email: navid.nikaein@eurecom.fr
*/ */
#include "SIMULATION/ETH_TRANSPORT/defs.h"
#ifndef EMU_PROTO_H_
#define EMU_PROTO_H_
void init_bypass (void); 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)); 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); 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); void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot,
unsigned int next_slot, uint8_t is_master);
#ifndef USER_MODE #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 bypass_tx_handler(unsigned int fifo, int rw); int bypass_tx_handler(unsigned int fifo, int rw);
...@@ -19,7 +25,7 @@ int bypass_rx_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); void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer);
#endif #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); void emulation_tx_rx(void);
...@@ -37,7 +43,10 @@ void emu_transport_DL(unsigned int frame, unsigned int last_slot,unsigned int ne ...@@ -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_UL(unsigned int frame, unsigned int last_slot,unsigned int next_slot);
void emu_transport_release(void); void emu_transport_release(void);
int multicast_link_read_data_from_sock(uint8_t eNB_flag);
void clear_eNB_transport_info(u8); void clear_eNB_transport_info(u8);
void clear_UE_transport_info(u8); void clear_UE_transport_info(u8);
int netlink_init(void); int netlink_init(void);
#endif /* EMU_PROTO_H_ */
...@@ -24,15 +24,18 @@ unsigned char emu_rx_status; ...@@ -24,15 +24,18 @@ unsigned char emu_rx_status;
//unsigned short Master_id; //unsigned short Master_id;
//unsigned int Is_primary_master; //unsigned int Is_primary_master;
#if !defined(ENABLE_NEW_MULTICAST)
pthread_mutex_t emul_low_mutex; pthread_mutex_t emul_low_mutex;
pthread_cond_t emul_low_cond; pthread_cond_t emul_low_cond;
char emul_low_mutex_var; char emul_low_mutex_var;
pthread_mutex_t Tx_mutex; pthread_mutex_t Tx_mutex;
pthread_cond_t Tx_cond; pthread_cond_t Tx_cond;
char Tx_mutex_var; char Tx_mutex_var;
#endif
int (*rx_handler) (unsigned char,char*,int); /* Handlers for RX and TX */
int (*tx_handler) (unsigned char,char*, unsigned int*, unsigned int*); rx_handler_t rx_handler;
tx_handler_t tx_handler;
eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX]; eNB_transport_info_t eNB_transport_info[NUMBER_OF_eNB_MAX];
u16 eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX]; u16 eNB_transport_info_TB_index[NUMBER_OF_eNB_MAX];
......
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2012 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include <stdio.h>
#ifndef ASSERTIONS_H_
#define ASSERTIONS_H_
#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \
do { \
if (!(cOND)) { \
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
__FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, #vALUE1": %d\n"#vALUE2": %d\n"#vALUE3": %d\n", \
(int)vALUE1, (int)vALUE2, (int)vALUE3); \
abort(); \
} \
} while(0)
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
do { \
if (!(cOND)) { \
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
__FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, #vALUE1": %d\n"#vALUE2": %d\n"#vALUE3": %d\n" \
#vALUE4": %d\n", \
(int)vALUE1, (int)vALUE2, (int)vALUE3, (int)vALUE4); \
exit(EXIT_FAILURE); \
} \
} while(0)
#define DevParam(vALUE1, vALUE2, vALUE3) \
DevCheck(0 == 1, vALUE1, vALUE2, vALUE3)
#define DevAssert(cOND) \
do { \
if (!(cOND)) { \
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} \
} while(0)
#define DevMessage(mESSAGE) \
do { \
fprintf(stderr, "%s:%d:%s Execution interrupted: `"#mESSAGE"`.\n", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} while(0)
#endif /* ASSERTIONS_H_ */
...@@ -218,6 +218,7 @@ CFLAGS +=-DPROC ...@@ -218,6 +218,7 @@ CFLAGS +=-DPROC
endif endif
CFLAGS += -DENABLE_VCD_FIFO CFLAGS += -DENABLE_VCD_FIFO
CFLAGS += -DENABLE_NEW_MULTICAST
# CFLAGS += -DENABLE_LOG_FIFO # 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) OBJ = $(PHY_OBJS) $(SIMULATION_OBJS) $(ETHERNET_TRANSPORT_OBJS) $(TOOLS_OBJS) $(SCHED_OBJS) $(STATS_OBJS) $(OAISIM_OBJS) $(NAS_OBJS) $(INT_OBJS) $(UTIL_OBJ)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment