- Update multicast:

* Remove recv thread
	* Update logs to LOG api
	* Retransmit Initial message if master not ready
	* Assert if packets lost -> break the execution if there is a drift in slots

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4006 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
Cedric Roux
2013-07-03 09:27:32 +00:00
parent b62ae47b90
commit d44ccd24ab
11 changed files with 1273 additions and 1128 deletions
@@ -1,16 +1,18 @@
/*! \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 @@
#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;
}
/***************************************************************************/
void bypass_init ( unsigned int (*tx_handlerP) (unsigned char,char*, unsigned int*, unsigned int*),unsigned int (*rx_handlerP) (unsigned char,char*,unsigned int)){
/***************************************************************************/
#ifdef USER_MODE
multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group, oai_emulation.info.multicast_ifname);
#endif //USER_MODE
tx_handler = tx_handlerP;
rx_handler = rx_handlerP;
Master_list_rx=0;
emu_tx_status = WAIT_SYNC_TRANSPORT;
emu_rx_status = WAIT_SYNC_TRANSPORT;
}
/***************************************************************************/
int bypass_rx_data (unsigned int frame, unsigned int last_slot, unsigned int next_slot){
/***************************************************************************/
bypass_msg_header_t *messg;
bypass_proto2multicast_header_t *bypass_read_header;
eNB_transport_info_t *eNB_info;
UE_transport_info_t *UE_info;
int ue_info_ix, enb_info_ix;
// int tmp_byte_count;
int bytes_read = 0;
int bytes_data_to_read;
// int num_flows;
// int current_flow;
int m_id, n_enb, n_ue, n_dci, total_tbs=0, total_header=0;
// printf("in bypass_rx_data ...\n");
pthread_mutex_lock(&emul_low_mutex);
if(emul_low_mutex_var){
//LOG_T(EMU, " WAIT BYPASS_PHY...\n");
pthread_cond_wait(&emul_low_cond, &emul_low_mutex);
}
if(num_bytesP==0){
//msg("[BYPASS] IDLE_WAIT\n");
//exit(0);
pthread_mutex_unlock(&emul_low_mutex);
}
else{
//LOG_T(EMU,"BYPASS_RX_DATA: IN, Num_bytesp=%d...\n",num_bytesP);
bypass_read_header = (bypass_proto2multicast_header_t *) (&rx_bufferP[bytes_read]);
bytes_read += sizeof (bypass_proto2multicast_header_t);
bytes_data_to_read = bypass_read_header->size;
if(num_bytesP!=bytes_read+bytes_data_to_read) {
LOG_W(EMU, "WARNINIG BYTES2READ # DELIVERED BYTES!!!\n");
}
else{
messg = (bypass_msg_header_t *) (&rx_bufferP[bytes_read]);
bytes_read += sizeof (bypass_msg_header_t);
if ( (messg->frame != frame) || (messg->subframe != next_slot>>1) )
LOG_W(EMU, "Received %s from master %d for (frame %d,subframe %d) currently (frame %d,subframe %d)\n",
map_int_to_str(transport_names,messg->Message_type), messg->master_id,
messg->frame, messg->subframe,
frame, next_slot>>1);
//chek if MASTER in my List
// switch(Emulation_status){
switch(messg->Message_type){
//case WAIT_SYNC_TRANSPORT:
case WAIT_PM_TRANSPORT_INFO:
if (messg->master_id==0 )
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
break;
case WAIT_SM_TRANSPORT_INFO:
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
break;
case SYNC_TRANSPORT_INFO:
// determite the total number of remote enb & ue
oai_emulation.info.nb_enb_remote += messg->nb_enb;
oai_emulation.info.nb_ue_remote += messg->nb_ue;
// determine the index of local enb and ue wrt the remote ones
if ( messg->master_id < oai_emulation.info.master_id ){
oai_emulation.info.first_enb_local +=messg->nb_enb;
oai_emulation.info.first_ue_local +=messg->nb_ue;
}
// store param for enb per master
if ((oai_emulation.info.master[messg->master_id].nb_enb = messg->nb_enb) > 0 ){
for (m_id=0;m_id < messg->master_id; m_id++ ){
oai_emulation.info.master[messg->master_id].first_enb+=oai_emulation.info.master[m_id].nb_enb;
}
LOG_I(EMU, "[ENB] WAIT_SYNC_TRANSPORT state: for master %d (first enb %d, totan enb %d)\n",
messg->master_id,
oai_emulation.info.master[messg->master_id].first_enb,
oai_emulation.info.master[messg->master_id].nb_enb);
}
// store param for ue per master
if ((oai_emulation.info.master[messg->master_id].nb_ue = messg->nb_ue) > 0){
for (m_id=0;m_id < messg->master_id; m_id++ ){
oai_emulation.info.master[messg->master_id].first_ue+=oai_emulation.info.master[m_id].nb_ue;
}
LOG_I(EMU, "[UE]WAIT_SYNC_TRANSPORT state: for master %d (first ue %d, total ue%d)\n",
messg->master_id,
oai_emulation.info.master[messg->master_id].first_ue,
oai_emulation.info.master[messg->master_id].nb_ue );
}
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
if (Master_list_rx == oai_emulation.info.master_list) {
emu_rx_status = SYNCED_TRANSPORT;
}
LOG_I(EMU,"WAIT_SYNC_TRANSPORT state: m_id %d total enb remote %d total ue remote %d \n",
messg->master_id,oai_emulation.info.nb_enb_remote, oai_emulation.info.nb_ue_remote );
break;
//case WAIT_ENB_TRANSPORT:
case ENB_TRANSPORT_INFO:
#ifdef DEBUG_EMU
LOG_D(EMU," RX ENB_TRANSPORT INFO from master %d \n",messg->master_id);
#endif #endif
clear_eNB_transport_info(oai_emulation.info.nb_enb_local+oai_emulation.info.nb_enb_remote); bypass_init (emul_tx_handler, emul_rx_handler);
if (oai_emulation.info.master[messg->master_id].nb_enb > 0 ){
enb_info_ix =0;
total_header=0;
total_header += sizeof(eNB_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
eNB_info = (eNB_transport_info_t *) (&rx_bufferP[bytes_read]);
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
n_enb < oai_emulation.info.master[messg->master_id].first_enb+oai_emulation.info.master[messg->master_id].nb_enb ;
n_enb ++) {
total_tbs=0;
for (n_dci = 0 ;
n_dci < (eNB_info[enb_info_ix].num_ue_spec_dci+eNB_info[enb_info_ix].num_common_dci);
n_dci ++) {
total_tbs+=eNB_info[enb_info_ix].tbs[n_dci];
}
enb_info_ix++;
if ( (total_tbs + total_header) > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ){
LOG_W(EMU,"RX eNB Transport buffer total size %d (header%d,tbs %d) \n",
total_header+total_tbs, total_header,total_tbs);
}
memcpy (&eNB_transport_info[n_enb],eNB_info, total_header+total_tbs);
eNB_info = (eNB_transport_info_t *)((unsigned int)eNB_info + total_header+total_tbs);
bytes_read+=total_header+total_tbs;
}
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
n_enb < oai_emulation.info.master[messg->master_id].first_enb+oai_emulation.info.master[messg->master_id].nb_enb ;
n_enb ++)
fill_phy_enb_vars(n_enb,next_slot);
}
else{
LOG_T(EMU,"WAIT_ENB_TRANSPORT state: no enb transport info from master %d \n", messg->master_id);
}
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
if (Master_list_rx == oai_emulation.info.master_list) {
emu_rx_status = SYNCED_TRANSPORT;
}
break;
case UE_TRANSPORT_INFO:
#ifdef DEBUG_EMU
LOG_D(EMU," RX UE TRANSPORT INFO from master %d\n",messg->master_id);
#endif
clear_UE_transport_info(oai_emulation.info.nb_ue_local+oai_emulation.info.nb_ue_remote);
if (oai_emulation.info.master[messg->master_id].nb_ue > 0 ){ //&& oai_emulation.info.nb_enb_local >0 ){
// get the header first
ue_info_ix =0;
total_header=0;
total_header += sizeof(UE_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
UE_info = (UE_transport_info_t *) (&rx_bufferP[bytes_read]);
// get the total size of the transport blocks
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
n_ue < oai_emulation.info.master[messg->master_id].first_ue+oai_emulation.info.master[messg->master_id].nb_ue ;
n_ue ++) {
total_tbs=0;
for (n_enb = 0;n_enb < UE_info[ue_info_ix].num_eNB; n_enb ++) {
total_tbs+=UE_info[ue_info_ix].tbs[n_enb];
}
ue_info_ix++;
if (total_tbs + total_header > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ){
LOG_W(EMU,"RX [UE %d] Total size of buffer is %d (header%d,tbs %d) \n",
n_ue, total_header+total_tbs,total_header,total_tbs);
}
memcpy (&UE_transport_info[n_ue], UE_info, total_header+total_tbs);
UE_info = (UE_transport_info_t *)((unsigned int)UE_info + total_header+total_tbs);
bytes_read+=total_header+total_tbs;
}
#ifdef DEBUG_EMU
for (n_enb=0; n_enb < UE_info[0].num_eNB; n_enb ++ )
LOG_T(EMU,"dump ue transport info rnti %x enb_id %d, harq_id %d tbs %d\n",
UE_transport_info[0].rnti[n_enb],
UE_transport_info[0].eNB_id[n_enb],
UE_transport_info[0].harq_pid[n_enb],
UE_transport_info[0].tbs[n_enb]);
#endif
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
n_ue < oai_emulation.info.master[messg->master_id].first_ue + oai_emulation.info.master[messg->master_id].nb_ue ;
n_ue ++) {
fill_phy_ue_vars(n_ue,last_slot);
}
}
else{
LOG_T(EMU,"WAIT_UE_TRANSPORT state: no UE transport info from master %d\n", messg->master_id );
}
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
if (Master_list_rx == oai_emulation.info.master_list) {
emu_rx_status = SYNCED_TRANSPORT;
}
break;
case RELEASE_TRANSPORT_INFO :
Master_list_rx = oai_emulation.info.master_list;
LOG_E(EMU, "RX RELEASE_TRANSPORT_INFO\n");
break;
default:
msg("[MAC][BYPASS] ERROR RX UNKNOWN MESSAGE\n");
//mac_xface->macphy_exit("");
break;
}
}
num_bytesP=0;
emul_low_mutex_var=1;
//msg("[BYPASS] CALLING_SIGNAL_HIGH_MAC\n");
pthread_cond_signal(&emul_low_cond);
pthread_mutex_unlock(&emul_low_mutex);
bypass_signal_mac_phy(frame,last_slot, next_slot);
}
//printf("leaving ...\n");
return bytes_read;
} }
/******************************************************************************************************/ /***************************************************************************/
#ifndef USER_MODE void bypass_init (tx_handler_t tx_handlerP, rx_handler_t rx_handlerP)
int bypass_rx_handler(unsigned int fifo, int rw){ {
/******************************************************************************************************/ /***************************************************************************/
// if(rw=='w'){ #if defined(USER_MODE)
int bytes_read; multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group,
int bytes_processed=0; oai_emulation.info.multicast_ifname);
int header_bytes; //, elapsed_time; #endif //USER_MODE
tx_handler = tx_handlerP;
rx_handler = rx_handlerP;
Master_list_rx=0;
emu_tx_status = WAIT_SYNC_TRANSPORT;
emu_rx_status = WAIT_SYNC_TRANSPORT;
}
int bypass_rx_data(unsigned int frame, unsigned int last_slot,
unsigned int next_slot, uint8_t is_master)
{
bypass_msg_header_t *messg;
bypass_proto2multicast_header_t *bypass_read_header;
eNB_transport_info_t *eNB_info;
UE_transport_info_t *UE_info;
int ue_info_ix, enb_info_ix;
int bytes_read = 0;
int bytes_data_to_read;
int m_id, n_enb, n_ue, n_dci, total_tbs = 0, total_header = 0;
LOG_D(EMU, "Entering bypass_rx for frame %d next_slot %d is_master %u\n",
frame, next_slot, is_master);
#if defined(ENABLE_NEW_MULTICAST)
if (multicast_link_read_data_from_sock(is_master) == 1) {
/* We got a timeout */
return -1;
}
#else
pthread_mutex_lock(&emul_low_mutex);
if(emul_low_mutex_var) {
pthread_cond_wait(&emul_low_cond, &emul_low_mutex);
}
if(num_bytesP==0) {
pthread_mutex_unlock(&emul_low_mutex);
} else {
#endif
bypass_read_header = (bypass_proto2multicast_header_t *) (
&rx_bufferP[bytes_read]);
bytes_read += sizeof (bypass_proto2multicast_header_t);
bytes_data_to_read = bypass_read_header->size;
if(num_bytesP!=bytes_read+bytes_data_to_read) {
LOG_W(EMU, "WARNINIG BYTES2READ # DELIVERED BYTES!!!\n");
} else {
messg = (bypass_msg_header_t *) (&rx_bufferP[bytes_read]);
bytes_read += sizeof (bypass_msg_header_t);
#if defined(ENABLE_NEW_MULTICAST)
LOG_D(EMU, "Received %d bytes [%s] from master_id %d with seq %"PRIuMAX"\n",
num_bytesP, map_int_to_str(transport_names, messg->Message_type),
messg->master_id,
messg->seq_num);
DevCheck4((messg->frame == frame) && (messg->subframe == (next_slot>>1)),
messg->frame, frame, messg->subframe, next_slot>>1);
#else
if ((messg->frame != frame) || (messg->subframe != next_slot>>1))
LOG_W(EMU,
"Received %s from master %d for (frame %d,subframe %d) "
"currently (frame %d,subframe %d)\n",
map_int_to_str(transport_names,messg->Message_type),
messg->master_id,
messg->frame, messg->subframe,
frame, next_slot>>1);
#endif
//chek if MASTER in my List
// switch(Emulation_status){
switch(messg->Message_type) {
//case WAIT_SYNC_TRANSPORT:
case EMU_TRANSPORT_INFO_WAIT_PM:
if (messg->master_id==0 ) {
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
}
break;
case EMU_TRANSPORT_INFO_WAIT_SM:
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
break;
case EMU_TRANSPORT_INFO_SYNC:
// determite the total number of remote enb & ue
oai_emulation.info.nb_enb_remote += messg->nb_enb;
oai_emulation.info.nb_ue_remote += messg->nb_ue;
// determine the index of local enb and ue wrt the remote ones
if ( messg->master_id < oai_emulation.info.master_id ) {
oai_emulation.info.first_enb_local +=messg->nb_enb;
oai_emulation.info.first_ue_local +=messg->nb_ue;
}
// store param for enb per master
if ((oai_emulation.info.master[messg->master_id].nb_enb = messg->nb_enb) > 0 ) {
for (m_id=0; m_id < messg->master_id; m_id++ ) {
oai_emulation.info.master[messg->master_id].first_enb+=oai_emulation.info.master[m_id].nb_enb;
}
LOG_I(EMU,
"[ENB] WAIT_SYNC_TRANSPORT state: for master %d (first enb %d, totan enb %d)\n",
messg->master_id,
oai_emulation.info.master[messg->master_id].first_enb,
oai_emulation.info.master[messg->master_id].nb_enb);
}
// store param for ue per master
if ((oai_emulation.info.master[messg->master_id].nb_ue = messg->nb_ue) > 0) {
for (m_id=0; m_id < messg->master_id; m_id++ ) {
oai_emulation.info.master[messg->master_id].first_ue+=oai_emulation.info.master[m_id].nb_ue;
}
LOG_I(EMU,
"[UE]WAIT_SYNC_TRANSPORT state: for master %d (first ue %d, total ue%d)\n",
messg->master_id,
oai_emulation.info.master[messg->master_id].first_ue,
oai_emulation.info.master[messg->master_id].nb_ue );
}
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
if (Master_list_rx == oai_emulation.info.master_list) {
emu_rx_status = SYNCED_TRANSPORT;
}
LOG_I(EMU,
"WAIT_SYNC_TRANSPORT state: m_id %d total enb remote %d total ue remote %d \n",
messg->master_id,oai_emulation.info.nb_enb_remote,
oai_emulation.info.nb_ue_remote );
break;
//case WAIT_ENB_TRANSPORT:
case EMU_TRANSPORT_INFO_ENB:
#ifdef DEBUG_EMU
LOG_D(EMU," RX ENB_TRANSPORT INFO from master %d \n",messg->master_id);
#endif
clear_eNB_transport_info(oai_emulation.info.nb_enb_local+
oai_emulation.info.nb_enb_remote);
if (oai_emulation.info.master[messg->master_id].nb_enb > 0 ) {
enb_info_ix =0;
total_header=0;
total_header += sizeof(eNB_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
eNB_info = (eNB_transport_info_t *) (&rx_bufferP[bytes_read]);
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
n_enb < oai_emulation.info.master[messg->master_id].first_enb+
oai_emulation.info.master[messg->master_id].nb_enb ;
n_enb ++) {
total_tbs=0;
for (n_dci = 0 ;
n_dci < (eNB_info[enb_info_ix].num_ue_spec_dci+
eNB_info[enb_info_ix].num_common_dci);
n_dci ++) {
total_tbs+=eNB_info[enb_info_ix].tbs[n_dci];
}
enb_info_ix++;
if ( (total_tbs + total_header) > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ) {
LOG_W(EMU,"RX eNB Transport buffer total size %d (header%d,tbs %d) \n",
total_header+total_tbs, total_header,total_tbs);
}
memcpy (&eNB_transport_info[n_enb],eNB_info, total_header+total_tbs);
eNB_info = (eNB_transport_info_t *)((unsigned int)eNB_info + total_header+
total_tbs);
bytes_read+=total_header+total_tbs;
}
for (n_enb = oai_emulation.info.master[messg->master_id].first_enb;
n_enb < oai_emulation.info.master[messg->master_id].first_enb+
oai_emulation.info.master[messg->master_id].nb_enb ;
n_enb ++) {
fill_phy_enb_vars(n_enb, next_slot);
}
} else {
LOG_T(EMU,"WAIT_ENB_TRANSPORT state: no enb transport info from master %d \n",
messg->master_id);
}
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
if (Master_list_rx == oai_emulation.info.master_list) {
emu_rx_status = SYNCED_TRANSPORT;
}
break;
case EMU_TRANSPORT_INFO_UE:
#ifdef DEBUG_EMU
LOG_D(EMU," RX UE TRANSPORT INFO from master %d\n",messg->master_id);
#endif
clear_UE_transport_info(oai_emulation.info.nb_ue_local+
oai_emulation.info.nb_ue_remote);
if (oai_emulation.info.master[messg->master_id].nb_ue >
0 ) { //&& oai_emulation.info.nb_enb_local >0 ){
// get the header first
ue_info_ix =0;
total_header=0;
total_header += sizeof(UE_transport_info_t)-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
UE_info = (UE_transport_info_t *) (&rx_bufferP[bytes_read]);
// get the total size of the transport blocks
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
n_ue < oai_emulation.info.master[messg->master_id].first_ue+
oai_emulation.info.master[messg->master_id].nb_ue ;
n_ue ++) {
total_tbs=0;
for (n_enb = 0; n_enb < UE_info[ue_info_ix].num_eNB; n_enb ++) {
total_tbs+=UE_info[ue_info_ix].tbs[n_enb];
}
ue_info_ix++;
if (total_tbs + total_header > MAX_TRANSPORT_BLOCKS_BUFFER_SIZE ) {
LOG_W(EMU,"RX [UE %d] Total size of buffer is %d (header%d,tbs %d) \n",
n_ue, total_header+total_tbs,total_header,total_tbs);
}
memcpy (&UE_transport_info[n_ue], UE_info, total_header+total_tbs);
UE_info = (UE_transport_info_t *)((unsigned int)UE_info + total_header+
total_tbs);
bytes_read+=total_header+total_tbs;
}
#ifdef DEBUG_EMU
for (n_enb=0; n_enb < UE_info[0].num_eNB; n_enb ++ )
LOG_T(EMU,"dump ue transport info rnti %x enb_id %d, harq_id %d tbs %d\n",
UE_transport_info[0].rnti[n_enb],
UE_transport_info[0].eNB_id[n_enb],
UE_transport_info[0].harq_pid[n_enb],
UE_transport_info[0].tbs[n_enb]);
#endif
for (n_ue = oai_emulation.info.master[messg->master_id].first_ue;
n_ue < oai_emulation.info.master[messg->master_id].first_ue +
oai_emulation.info.master[messg->master_id].nb_ue ;
n_ue ++) {
fill_phy_ue_vars(n_ue,last_slot);
}
} else {
LOG_T(EMU,"WAIT_UE_TRANSPORT state: no UE transport info from master %d\n",
messg->master_id);
}
Master_list_rx=((Master_list_rx) |(1<< messg->master_id));
if (Master_list_rx == oai_emulation.info.master_list) {
emu_rx_status = SYNCED_TRANSPORT;
}
break;
case EMU_TRANSPORT_INFO_RELEASE :
Master_list_rx = oai_emulation.info.master_list;
LOG_E(EMU, "RX EMU_TRANSPORT_INFO_RELEASE\n");
break;
default:
LOG_E(EMU, "[MAC][BYPASS] ERROR RX UNKNOWN MESSAGE\n");
//mac_xface->macphy_exit("");
break;
}
}
num_bytesP=0;
#if !defined(ENABLE_NEW_MULTICAST)
emul_low_mutex_var=1;
pthread_cond_signal(&emul_low_cond);
pthread_mutex_unlock(&emul_low_mutex);
#endif
bypass_signal_mac_phy(frame,last_slot, next_slot, is_master);
#if !defined(ENABLE_NEW_MULTICAST)
}
#endif
return bytes_read;
}
/******************************************************************************************************/
#ifndef USER_MODE
int bypass_rx_handler(unsigned int fifo, int rw)
{
/******************************************************************************************************/
int bytes_read;
int bytes_processed=0;
int header_bytes; //, elapsed_time;
//printk("[BYPASS] BYPASS_RX_HANDLER IN...\n"); //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;
messg = (bypass_msg_header_t *) (&bypass_tx_buffer[sizeof (bypass_proto2multicast_header_t)]);
num_flows = 0;
messg->master_id = oai_emulation.info.master_id; //Master_id;
// messg->nb_master = oai_emulation.info.nb_master;
messg->nb_enb = oai_emulation.info.nb_enb_local; //Master_id;
messg->nb_ue = oai_emulation.info.nb_ue_local; //Master_id;
messg->nb_flow = num_flows;
messg->frame = frame;
messg->subframe = next_slot>>1;
byte_tx_count = sizeof (bypass_msg_header_t) + sizeof (bypass_proto2multicast_header_t); LOG_D(EMU, "Entering bypass_tx [%s] for frame %d next_slot %d\n",
map_int_to_str(transport_names, Type), frame, next_slot);
if(Type==WAIT_PM_TRANSPORT){
messg->Message_type = WAIT_PM_TRANSPORT_INFO; int n_enb,n_ue, n_dci,total_tbs=0,total_size=0;
LOG_T(EMU,"[TX_DATA] WAIT SYNC PM TRANSPORT\n"); messg = (bypass_msg_header_t *) (
} &bypass_tx_buffer[sizeof (bypass_proto2multicast_header_t)]);
else if(Type==WAIT_SM_TRANSPORT){ num_flows = 0;
messg->Message_type = WAIT_SM_TRANSPORT_INFO; messg->master_id = oai_emulation.info.master_id; //Master_id;
LOG_T(EMU,"[TX_DATA] WAIT SYNC SM TRANSPORT\n");
} messg->nb_enb = oai_emulation.info.nb_enb_local; //Master_id;
else if(Type==SYNC_TRANSPORT){ messg->nb_ue = oai_emulation.info.nb_ue_local; //Master_id;
messg->Message_type = SYNC_TRANSPORT_INFO; messg->nb_flow = num_flows;
// make sure that sync messages from the masters are received in increasing order of master id messg->frame = frame;
sleep(oai_emulation.info.master_id+1); messg->subframe = next_slot>>1;
LOG_T(EMU,"[TX_DATA] SYNC TRANSPORT\n"); messg->seq_num = seq_num_tx;
}
else if(Type==ENB_TRANSPORT){ seq_num_tx++;
LOG_D(EMU,"[TX_DATA] ENB TRANSPORT\n");
messg->Message_type = ENB_TRANSPORT_INFO; byte_tx_count = sizeof (bypass_msg_header_t) + sizeof (
total_size=0; bypass_proto2multicast_header_t);
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++) { if (Type == WAIT_PM_TRANSPORT) {
total_tbs=0; messg->Message_type = EMU_TRANSPORT_INFO_WAIT_PM;
for (n_dci =0 ; LOG_T(EMU,"[TX_DATA] WAIT SYNC PM TRANSPORT\n");
n_dci < (eNB_transport_info[n_enb].num_ue_spec_dci+ eNB_transport_info[n_enb].num_common_dci); } else if (Type == WAIT_SM_TRANSPORT) {
n_dci++) { messg->Message_type = EMU_TRANSPORT_INFO_WAIT_SM;
total_tbs +=eNB_transport_info[n_enb].tbs[n_dci]; LOG_T(EMU,"[TX_DATA] WAIT SYNC SM TRANSPORT\n");
} } else if (Type == SYNC_TRANSPORT) {
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) messg->Message_type = EMU_TRANSPORT_INFO_SYNC;
total_size = sizeof(eNB_transport_info_t)+total_tbs-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE; /* make sure that sync messages from the masters are received in
else * increasing order of master id
LOG_E(EMU,"[eNB]running out of memory for the eNB emulation transport buffer of size %d\n", MAX_TRANSPORT_BLOCKS_BUFFER_SIZE); */
memcpy(&bypass_tx_buffer[byte_tx_count], (char*)&eNB_transport_info[n_enb], total_size); sleep(oai_emulation.info.master_id+1);
byte_tx_count +=total_size; LOG_T(EMU,"[TX_DATA] SYNC TRANSPORT\n");
} } else if(Type==ENB_TRANSPORT) {
} LOG_D(EMU,"[TX_DATA] ENB TRANSPORT\n");
else if (Type == UE_TRANSPORT){ messg->Message_type = EMU_TRANSPORT_INFO_ENB;
LOG_D(EMU,"[TX_DATA] UE TRANSPORT\n"); total_size=0;
messg->Message_type = UE_TRANSPORT_INFO; total_tbs=0;
total_size=0; for (n_enb=oai_emulation.info.first_enb_local;
total_tbs=0; // compute the actual size of transport_blocks n_enb<(oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local);
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++){ n_enb++) {
for (n_enb=0;n_enb<UE_transport_info[n_ue].num_eNB;n_enb++) { total_tbs=0;
total_tbs+=UE_transport_info[n_ue].tbs[n_enb]; for (n_dci =0 ;
} n_dci < (eNB_transport_info[n_enb].num_ue_spec_dci+
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) eNB_transport_info[n_enb].num_common_dci);
total_size = sizeof(UE_transport_info_t)+total_tbs-MAX_TRANSPORT_BLOCKS_BUFFER_SIZE; n_dci++) {
else total_tbs +=eNB_transport_info[n_enb].tbs[n_dci];
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); if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) {
byte_tx_count +=total_size; total_size = sizeof(eNB_transport_info_t)+total_tbs-
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
} else {
LOG_E(EMU,
"[eNB]running out of memory for the eNB emulation transport buffer of size %d\n",
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE);
}
memcpy(&bypass_tx_buffer[byte_tx_count], (char *)&eNB_transport_info[n_enb],
total_size);
byte_tx_count +=total_size;
}
} else if (Type == UE_TRANSPORT) {
LOG_D(EMU,"[TX_DATA] UE TRANSPORT\n");
messg->Message_type = EMU_TRANSPORT_INFO_UE;
total_size=0;
total_tbs=0; // compute the actual size of transport_blocks
for (n_ue = oai_emulation.info.first_ue_local;
n_ue < (oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local);
n_ue++) {
for (n_enb=0; n_enb<UE_transport_info[n_ue].num_eNB; n_enb++) {
total_tbs+=UE_transport_info[n_ue].tbs[n_enb];
}
if (total_tbs <= MAX_TRANSPORT_BLOCKS_BUFFER_SIZE) {
total_size = sizeof(UE_transport_info_t)+total_tbs-
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE;
} else {
LOG_E(EMU,
"[UE]running out of memory for the UE emulation transport buffer of size %d\n",
MAX_TRANSPORT_BLOCKS_BUFFER_SIZE);
}
memcpy(&bypass_tx_buffer[byte_tx_count], (char *)&UE_transport_info[n_ue],
total_size);
byte_tx_count +=total_size;
}
} else if (Type == RELEASE_TRANSPORT) {
messg->Message_type = EMU_TRANSPORT_INFO_RELEASE;
} else {
LOG_E(EMU,"[TX_DATA] UNKNOWN MSG \n");
} }
}
else if (Type == RELEASE_TRANSPORT){
messg->Message_type = RELEASE_TRANSPORT_INFO;
}else {
LOG_T(EMU,"[TX_DATA] UNKNOWN MSG \n");
}
((bypass_proto2multicast_header_t *) bypass_tx_buffer)->size = byte_tx_count - sizeof (bypass_proto2multicast_header_t); ((bypass_proto2multicast_header_t *) bypass_tx_buffer)->size = byte_tx_count -
//if(mac_xface->frame%1000==0) sizeof (bypass_proto2multicast_header_t);
multicast_link_write_sock (oai_emulation.info.multicast_group, bypass_tx_buffer, byte_tx_count);
multicast_link_write_sock (oai_emulation.info.multicast_group,
bypass_tx_buffer, byte_tx_count);
LOG_D(EMU, "Sent %d bytes [%s] with master_id %d and seq %"PRIuMAX"\n",
byte_tx_count, map_int_to_str(transport_names, Type),
messg->master_id, messg->seq_num);
} }
#ifndef USER_MODE #ifndef USER_MODE
/*********************************************************************************************************************/ /*********************************************************************************************************************/
int bypass_tx_handler(unsigned int fifo, int rw){ 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
+23 -74
View File
@@ -1,29 +1,26 @@
/*! \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 @@
#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 {
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 {
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 {
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 //
+384 -340
View File
@@ -1,397 +1,441 @@
/*! \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){ void emu_transport_sync(void)
{
if (oai_emulation.info.is_primary_master==0){ LOG_D(EMU, "Entering EMU transport SYNC is primary master %d\n",
oai_emulation.info.is_primary_master);
bypass_tx_data(WAIT_SM_TRANSPORT,0,0); if (oai_emulation.info.is_primary_master == 0) {
Master_list_rx=oai_emulation.info.master_list-1; // just wait to recieve the master 0 msg retry:
bypass_rx_data(0,0,0); bypass_tx_data(WAIT_SM_TRANSPORT,0,0);
} // just wait to recieve the master 0 msg
else { Master_list_rx = oai_emulation.info.master_list - 1;
bypass_rx_data(0,0,0); if (bypass_rx_data(0,0,0,1) == -1) {
bypass_tx_data(WAIT_PM_TRANSPORT,0,0); /* In case the master is not ready at time we send the first message */
} sleep(1);
goto retry;
if (oai_emulation.info.master_list!=0){ }
} else {
bypass_tx_data(SYNC_TRANSPORT,0,0); bypass_rx_data(0,0,0,0);
bypass_rx_data(0,0,0); bypass_tx_data(WAIT_PM_TRANSPORT,0,0);
if (emu_rx_status == SYNCED_TRANSPORT){ // i received the sync from all secondary masters
emu_tx_status = SYNCED_TRANSPORT;
} }
// else emu_transport_sync(last_slot);
LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n");
}
}
void emu_transport(unsigned int frame, unsigned int last_slot, unsigned int next_slot,lte_subframe_t direction, unsigned char frame_type, int ethernet_flag ){ if (oai_emulation.info.master_list!=0) {
retry2:
if (ethernet_flag == 0) bypass_tx_data(SYNC_TRANSPORT,0,0);
return; if (bypass_rx_data(0,0,0,0) == -1) {
goto retry2;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_IN); }
if ((frame_type == 1) && (direction == SF_S)){ // i received the sync from all secondary masters
if (next_slot%2==0) if (emu_rx_status == SYNCED_TRANSPORT) {
emu_transport_DL(frame, last_slot,next_slot); emu_tx_status = SYNCED_TRANSPORT;
else }
emu_transport_UL(frame, last_slot , next_slot);
//DL LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n");
}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 LOG_D(EMU, "Leaving EMU transport SYNC is primary master %d\n",
if ( ((frame_type == 1) && (direction == SF_UL)) || (frame_type == 0) ){ oai_emulation.info.is_primary_master);
emu_transport_UL(frame, last_slot , next_slot); }
void emu_transport(unsigned int frame, unsigned int last_slot,
unsigned int next_slot,lte_subframe_t direction,
unsigned char frame_type,
int ethernet_flag )
{
if (ethernet_flag == 0) {
return;
} }
} vcd_signal_dumper_dump_function_by_name(
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_IN);
if ((frame_type == 1) && (direction == SF_S)) {
if (next_slot%2==0) {
emu_transport_DL(frame, last_slot,next_slot);
} else {
emu_transport_UL(frame, last_slot , next_slot);
}
//DL
} else {
if (next_slot%2 == 0 )
if ( ((frame_type == 1) && (direction == SF_DL )) || (frame_type == 0) ) {
emu_transport_DL(frame, last_slot,next_slot);
}
// UL
if ( ((frame_type == 1) && (direction == SF_UL)) || (frame_type == 0) ) {
emu_transport_UL(frame, last_slot , next_slot);
}
}
vcd_signal_dumper_dump_function_by_name(
VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_OUT);
} }
void emu_transport_DL(unsigned int frame, unsigned int last_slot, unsigned int next_slot) { void emu_transport_DL(unsigned int frame, unsigned int last_slot,
unsigned int next_slot)
if (oai_emulation.info.is_primary_master==0){ {
// bypass_rx_data(last_slot); LOG_D(EMU, "Entering EMU transport DL, is primary master %d\n",
if (oai_emulation.info.nb_enb_local>0) // send in DL if oai_emulation.info.is_primary_master);
bypass_tx_data(ENB_TRANSPORT,frame, next_slot); if (oai_emulation.info.is_primary_master==0) {
else // bypass_rx_data(last_slot);
bypass_tx_data(WAIT_SM_TRANSPORT,frame,next_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); bypass_rx_data(frame, last_slot, next_slot, 1);
} } else {
else { // I am the master bypass_tx_data(WAIT_SM_TRANSPORT,frame,next_slot);
// bypass_tx_data(WAIT_TRANSPORT,last_slot); bypass_rx_data(frame, last_slot, next_slot, 0);
}
if (oai_emulation.info.nb_enb_local>0) // send in DL if } else { // I am the master
bypass_tx_data(ENB_TRANSPORT,frame, next_slot); // bypass_tx_data(WAIT_TRANSPORT,last_slot);
else
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot);
}
if (oai_emulation.info.nb_enb_local>0) { // send in DL if
bypass_tx_data(ENB_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot, 1);
} else {
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot, 0);
}
}
LOG_D(EMU, "Leaving EMU transport DL, is primary master %d\n",
oai_emulation.info.is_primary_master);
} }
void emu_transport_UL(unsigned int frame, unsigned int last_slot, unsigned int next_slot) { void emu_transport_UL(unsigned int frame, unsigned int last_slot,
unsigned int next_slot)
{
if (oai_emulation.info.is_primary_master==0){ LOG_D(EMU, "Entering EMU transport UL, is primary master %d\n",
// bypass_rx_data(last_slot, next_slot); oai_emulation.info.is_primary_master);
if (oai_emulation.info.nb_ue_local>0) if (oai_emulation.info.is_primary_master==0) {
bypass_tx_data(UE_TRANSPORT,frame, next_slot); // bypass_rx_data(last_slot, next_slot);
else if (oai_emulation.info.nb_ue_local>0) {
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot); bypass_tx_data(UE_TRANSPORT, frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot, 1);
bypass_rx_data(frame,last_slot, next_slot); } else {
} bypass_tx_data(WAIT_SM_TRANSPORT, frame, next_slot);
else { bypass_rx_data(frame,last_slot, next_slot, 0);
// bypass_tx_data(WAIT_TRANSPORT,last_slot); }
if (oai_emulation.info.nb_ue_local>0) } else {
bypass_tx_data(UE_TRANSPORT,frame, next_slot); // bypass_tx_data(WAIT_TRANSPORT,last_slot);
else if (oai_emulation.info.nb_ue_local>0) {
bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot); bypass_tx_data(UE_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot, 1);
bypass_rx_data(frame,last_slot, next_slot); } else {
} bypass_tx_data(WAIT_SM_TRANSPORT,frame, next_slot);
bypass_rx_data(frame,last_slot, next_slot, 0);
}
}
LOG_D(EMU, "Leaving EMU transport UL, is primary master %d\n",
oai_emulation.info.is_primary_master);
} }
void emu_transport_release(void){ void emu_transport_release(void)
bypass_tx_data(RELEASE_TRANSPORT,0,0); {
LOG_E(EMU," tx RELEASE_TRANSPORT \n"); bypass_tx_data(RELEASE_TRANSPORT,0,0);
} LOG_E(EMU," tx RELEASE_TRANSPORT \n");
unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,unsigned int* Nbytes,unsigned int *Nb_flows){
unsigned short k,Mod_id;
for(k=0;k<NB_INST;k++){//Nb_out_src[Mode];k++){
Mod_id=k;//Out_list[Mode][k];
}
return *Nbytes;
} }
unsigned int emul_rx_data(void){ unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,
return(0); unsigned int *Nbytes,unsigned int *Nb_flows)
{
return *Nbytes;
} }
unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer, unsigned int Nbytes){ unsigned int emul_rx_data(void)
unsigned short Rx_size=0; {
return (Rx_size+2); return(0);
} }
void clear_eNB_transport_info(u8 nb_eNB) { unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer,
u8 eNB_id; 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_UE_transport_info(u8 nb_UE) { void clear_eNB_transport_info(u8 nb_eNB)
u8 UE_id; {
u8 eNB_id;
for (UE_id=0;UE_id<nb_UE;UE_id++) {
UE_transport_info_TB_index[UE_id]=0; for (eNB_id=0; eNB_id<nb_eNB; eNB_id++) {
memset((void *)&UE_transport_info[UE_id].cntl,0,sizeof(UE_cntl)); eNB_transport_info_TB_index[eNB_id]=0;
} memset((void *)&eNB_transport_info[eNB_id].cntl,0,sizeof(eNB_cntl));
// LOG_T(EMU, "EMUL clear_UE_transport_info\n"); eNB_transport_info[eNB_id].num_common_dci=0;
eNB_transport_info[eNB_id].num_ue_spec_dci=0;
}
// LOG_T(EMU, "EMUL clear_eNB_transport_info\n");
} }
void clear_UE_transport_info(u8 nb_UE)
{
u8 UE_id;
void fill_phy_enb_vars(unsigned int enb_id, unsigned int next_slot) { for (UE_id=0; UE_id<nb_UE; UE_id++) {
UE_transport_info_TB_index[UE_id]=0;
memset((void *)&UE_transport_info[UE_id].cntl,0,sizeof(UE_cntl));
}
// LOG_T(EMU, "EMUL clear_UE_transport_info\n");
}
void fill_phy_enb_vars(unsigned int enb_id, unsigned int next_slot)
{
int n_dci = 0, n_dci_dl;
int payload_offset = 0;
unsigned int harq_pid;
LTE_eNB_DLSCH_t *dlsch_eNB;
unsigned short ue_id;
u8 nb_total_dci;
int n_dci=0, n_dci_dl;
int payload_offset = 0;
unsigned int harq_pid;
LTE_eNB_DLSCH_t *dlsch_eNB;
unsigned short ue_id;
u8 nb_total_dci;
#ifdef DEBUG_EMU #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
// to be added later
//DCI //PHICH
nb_total_dci= eNB_transport_info[enb_id].num_ue_spec_dci+ eNB_transport_info[enb_id].num_common_dci; // to be added later
PHY_vars_eNB_g[enb_id]->num_ue_spec_dci[(next_slot>>1)&1] = eNB_transport_info[enb_id].num_ue_spec_dci;
PHY_vars_eNB_g[enb_id]->num_common_dci[(next_slot>>1)&1] = eNB_transport_info[enb_id].num_common_dci;
if (nb_total_dci >0) { //DCI
nb_total_dci= eNB_transport_info[enb_id].num_ue_spec_dci+
memcpy(PHY_vars_eNB_g[enb_id]->dci_alloc[(next_slot>>1)&1], eNB_transport_info[enb_id].num_common_dci;
&eNB_transport_info[enb_id].dci_alloc, PHY_vars_eNB_g[enb_id]->num_ue_spec_dci[(next_slot>>1)&1] =
(nb_total_dci)* sizeof(DCI_ALLOC_t)); eNB_transport_info[enb_id].num_ue_spec_dci;
PHY_vars_eNB_g[enb_id]->num_common_dci[(next_slot>>1)&1] =
eNB_transport_info[enb_id].num_common_dci;
n_dci_dl=0;
// fill dlsch_eNB structure from DCI if (nb_total_dci >0) {
for (n_dci =0 ;
n_dci < nb_total_dci; memcpy(PHY_vars_eNB_g[enb_id]->dci_alloc[(next_slot>>1)&1],
n_dci++) { &eNB_transport_info[enb_id].dci_alloc,
(nb_total_dci)* sizeof(DCI_ALLOC_t));
if (eNB_transport_info[enb_id].dci_alloc[n_dci_dl].format > 0){ //exclude ul dci
#ifdef DEBUG_EMU n_dci_dl=0;
LOG_D(EMU, "dci spec %d common %d tbs is %d payload offset %d\n", // fill dlsch_eNB structure from DCI
eNB_transport_info[enb_id].num_ue_spec_dci, for (n_dci = 0; n_dci < nb_total_dci; n_dci++) {
eNB_transport_info[enb_id].num_common_dci,
eNB_transport_info[enb_id].tbs[n_dci_dl], //exclude ul dci
payload_offset); if (eNB_transport_info[enb_id].dci_alloc[n_dci_dl].format > 0) {
#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
LOG_D(EMU, "Fill phy eNB vars done next slot %d !\n", next_slot);
#endif
}
}
void fill_phy_ue_vars(unsigned int ue_id, unsigned int last_slot)
{
int n_enb;//index
int enb_id;
// int harq_id;
// int payload_offset = 0;
unsigned short rnti;
unsigned int harq_pid;
LTE_UE_ULSCH_t *ulsch;
PUCCH_FMT_t pucch_format;
// u8 ue_transport_info_index[NUMBER_OF_eNB_MAX];
u8 subframe = (last_slot+1)>>1;
memcpy (&ue_cntl_delay[ue_id][(last_slot+1)%2],
&UE_transport_info[ue_id].cntl,
sizeof(UE_cntl));
#ifdef DEBUG_EMU
LOG_D(EMU,
"Last slot %d subframe %d Fill phy UE %d vars PRACH is (%d,%d) preamble (%d,%d) SR (%d,%d), pucch_sel (%d, %d)\n",
last_slot,subframe,ue_id,
UE_transport_info[ue_id].cntl.prach_flag,
ue_cntl_delay[ue_id][last_slot%2].prach_flag,
UE_transport_info[ue_id].cntl.prach_id,
ue_cntl_delay[ue_id][last_slot%2].prach_id,
UE_transport_info[ue_id].cntl.sr,
ue_cntl_delay[ue_id][last_slot%2].sr,
UE_transport_info[ue_id].cntl.pucch_sel,
ue_cntl_delay[ue_id][last_slot%2].pucch_sel );
#endif
//ue_cntl_delay[subframe%2].prach_flag ;
PHY_vars_UE_g[ue_id]->generate_prach =
ue_cntl_delay[ue_id][last_slot%2].prach_flag;//UE_transport_info[ue_id].cntl.prach_flag;
if (PHY_vars_UE_g[ue_id]->generate_prach == 1) {
// if (PHY_vars_UE_g[ue_id]->prach_resources[enb_id] == NULL)
// PHY_vars_UE_g[ue_id]->prach_resources[enb_id] = malloc(sizeof(PRACH_RESOURCES_t));
//ue_cntl_delay[subframe%2].prach_id;
PHY_vars_UE_g[ue_id]->prach_PreambleIndex =
ue_cntl_delay[ue_id][last_slot%2].prach_id;
}
pucch_format=
ue_cntl_delay[ue_id][last_slot%2].pucch_flag;// UE_transport_info[ue_id].cntl.pucch_flag;
if ((last_slot+1) % 2 == 0 ) {
if (pucch_format == pucch_format1) { // UE_transport_info[ue_id].cntl.sr;
PHY_vars_UE_g[ue_id]->sr[subframe] = ue_cntl_delay[ue_id][last_slot%2].sr;
} else if ((pucch_format == pucch_format1a)
|| (pucch_format == pucch_format1b )) {
PHY_vars_UE_g[ue_id]->pucch_payload[0] =
ue_cntl_delay[ue_id][last_slot%2].pucch_payload;//UE_transport_info[ue_id].cntl.pucch_payload;
}
PHY_vars_UE_g[ue_id]->pucch_sel[subframe] =
ue_cntl_delay[ue_id][last_slot%2].pucch_sel;
} }
#ifdef DEBUG_EMU #ifdef DEBUG_EMU
LOG_D(EMU, "Fill phy eNB vars done next slot %d !\n", next_slot); LOG_D(EMU,"subframe %d trying to copy the payload from num eNB %d to UE %d \n",
#endif 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++) {
void fill_phy_ue_vars(unsigned int ue_id, unsigned int last_slot) {
int n_enb;//index
int enb_id;
// int harq_id;
// int payload_offset = 0;
unsigned short rnti;
unsigned int harq_pid;
LTE_UE_ULSCH_t *ulsch;
PUCCH_FMT_t pucch_format;
// u8 ue_transport_info_index[NUMBER_OF_eNB_MAX];
u8 subframe = (last_slot+1)>>1;
memcpy (&ue_cntl_delay[ue_id][(last_slot+1)%2],
&UE_transport_info[ue_id].cntl,
sizeof(UE_cntl));
#ifdef DEBUG_EMU #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,"Setting ulsch vars for ue %d rnti %x harq pid is %d \n",
last_slot,subframe,ue_id, ue_id, UE_transport_info[ue_id].rnti[n_enb],
UE_transport_info[ue_id].cntl.prach_flag, PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]);
ue_cntl_delay[ue_id][last_slot%2].prach_flag, */
UE_transport_info[ue_id].cntl.prach_id,
ue_cntl_delay[ue_id][last_slot%2].prach_id,
UE_transport_info[ue_id].cntl.sr,
ue_cntl_delay[ue_id][last_slot%2].sr,
UE_transport_info[ue_id].cntl.pucch_sel,
ue_cntl_delay[ue_id][last_slot%2].pucch_sel );
#endif
//ue_cntl_delay[subframe%2].prach_flag ;
PHY_vars_UE_g[ue_id]->generate_prach = ue_cntl_delay[ue_id][last_slot%2].prach_flag;//UE_transport_info[ue_id].cntl.prach_flag;
if (PHY_vars_UE_g[ue_id]->generate_prach == 1) {
// if (PHY_vars_UE_g[ue_id]->prach_resources[enb_id] == NULL)
// PHY_vars_UE_g[ue_id]->prach_resources[enb_id] = malloc(sizeof(PRACH_RESOURCES_t));
//ue_cntl_delay[subframe%2].prach_id;
PHY_vars_UE_g[ue_id]->prach_PreambleIndex = ue_cntl_delay[ue_id][last_slot%2].prach_id;
}
pucch_format= ue_cntl_delay[ue_id][last_slot%2].pucch_flag;// UE_transport_info[ue_id].cntl.pucch_flag;
if ((last_slot+1) % 2 == 0 ) {
if (pucch_format == pucch_format1) // UE_transport_info[ue_id].cntl.sr;
PHY_vars_UE_g[ue_id]->sr[subframe] = ue_cntl_delay[ue_id][last_slot%2].sr;
else if ((pucch_format == pucch_format1a) || (pucch_format == pucch_format1b )){
PHY_vars_UE_g[ue_id]->pucch_payload[0] = ue_cntl_delay[ue_id][last_slot%2].pucch_payload;//UE_transport_info[ue_id].cntl.pucch_payload;
}
PHY_vars_UE_g[ue_id]->pucch_sel[subframe] = ue_cntl_delay[ue_id][last_slot%2].pucch_sel;
}
#ifdef DEBUG_EMU
LOG_D(EMU,"subframe %d trying to copy the payload from num eNB %d to UE %d \n",subframe, UE_transport_info[ue_id].num_eNB, ue_id);
#endif #endif
for (n_enb=0; n_enb < UE_transport_info[ue_id].num_eNB; n_enb++){ rnti = UE_transport_info[ue_id].rnti[n_enb];
#ifdef DEBUG_EMU enb_id = UE_transport_info[ue_id].eNB_id[n_enb];
/* LOG_D(EMU,"Setting ulsch vars for ue %d rnti %x harq pid is %d \n",
ue_id, UE_transport_info[ue_id].rnti[n_enb],
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]);
*/
#endif
rnti = UE_transport_info[ue_id].rnti[n_enb];
enb_id = UE_transport_info[ue_id].eNB_id[n_enb];
PHY_vars_UE_g[ue_id]->lte_ue_pdcch_vars[enb_id]->crnti=rnti;
harq_pid = UE_transport_info[ue_id].harq_pid[n_enb];
//ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id];
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[0] = ue_cntl_delay[ue_id][last_slot%2].pusch_ri & 0x1;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[1] = (ue_cntl_delay[ue_id][last_slot%2].pusch_ri>>1) & 0x1;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[0]= ue_cntl_delay[ue_id][last_slot%2].pusch_ack & 0x1;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[1]= (ue_cntl_delay[ue_id][last_slot%2].pusch_ack>>1) & 0x1;
//*(u32 *)ulsch->o = ue_cntl_delay[ue_id][last_slot%2].pusch_uci;
if (last_slot%2 == 1 ) { PHY_vars_UE_g[ue_id]->lte_ue_pdcch_vars[enb_id]->crnti=rnti;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O = ue_cntl_delay[ue_id][last_slot%2].length_uci;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->uci_format = ue_cntl_delay[ue_id][last_slot%2].uci_format; harq_pid = UE_transport_info[ue_id].harq_pid[n_enb];
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o, //ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id];
ue_cntl_delay[ue_id][last_slot%2].pusch_uci,
MAX_CQI_BYTES); PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[0] =
ue_cntl_delay[ue_id][last_slot%2].pusch_ri & 0x1;
ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]; PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_RI[1] =
// if (((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1) (ue_cntl_delay[ue_id][last_slot%2].pusch_ri>>1) & 0x1;
LOG_D(EMU,"[UE %d] subframe %d last slot %d copy the payload from eNB %d to UE %d with harq id %d cqi (val %d, length %d) \n",
ue_id, subframe, last_slot, enb_id, ue_id, harq_pid, PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->o_ACK[0]=
((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1, ue_cntl_delay[ue_id][last_slot%2].pusch_ack & 0x1;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O); 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;
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->harq_processes[harq_pid]->b, //*(u32 *)ulsch->o = ue_cntl_delay[ue_id][last_slot%2].pusch_uci;
UE_transport_info[ue_id].transport_blocks,
UE_transport_info[ue_id].tbs[enb_id]); if (last_slot%2 == 1 ) {
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O =
//ue_transport_info_index[enb_id]+=UE_transport_info[ue_id].tbs[enb_id]; ue_cntl_delay[ue_id][last_slot%2].length_uci;
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->uci_format =
//UE_transport_info[ue_id].transport_blocks+=ue_transport_info_index[enb_id]; ue_cntl_delay[ue_id][last_slot%2].uci_format;
//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]->o,
ue_cntl_delay[ue_id][last_slot%2].pusch_uci,
MAX_CQI_BYTES);
ulsch = PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id];
// if (((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1)
LOG_D(EMU,
"[UE %d] subframe %d last slot %d copy the payload from eNB %d to UE %d with harq id %d cqi (val %d, length %d) \n",
ue_id, subframe, last_slot, enb_id, ue_id, harq_pid,
((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1,
PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->O);
}
memcpy(PHY_vars_UE_g[ue_id]->ulsch_ue[enb_id]->harq_processes[harq_pid]->b,
UE_transport_info[ue_id].transport_blocks,
UE_transport_info[ue_id].tbs[enb_id]);
//ue_transport_info_index[enb_id]+=UE_transport_info[ue_id].tbs[enb_id];
//UE_transport_info[ue_id].transport_blocks+=ue_transport_info_index[enb_id];
//LOG_T(EMU,"ulsch tbs is %d\n", UE_transport_info[ue_id].tbs[enb_id]);
}
} }
+11 -10
View File
@@ -1,11 +1,11 @@
/*! \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;
//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];
+211 -205
View File
@@ -1,11 +1,11 @@
/*! \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 @@
#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);
command.imr_interface.s_addr = htonl (INADDR_ANY);
if (command.imr_multiaddr.s_addr == -1) {
msg ("[MULTICAST] ERROR: %s line %d NO MULTICAST", __FILE__, __LINE__);
exit (EXIT_FAILURE);
}
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof (command)) < 0) {
msg ("[MULTICAST] ERROR: %s line %d IP_ADD_MEMBERSHIP %m", __FILE__, __LINE__);
exit (EXIT_FAILURE);
}
LOG_D(EMU, "multicast_link_init(): Created socket %d for group %d, port %d\n",
group_list[group].socket,group,group_list[group].port);
memset (&group_list[group].sock_remote_addr, 0, sizeof (struct sockaddr_in)); /* Used so we can re-bind to our port while a previous connection is still
group_list[group].sock_remote_addr.sin_family = AF_INET; * in TIME_WAIT state.
group_list[group].sock_remote_addr.sin_addr.s_addr = inet_addr (multicast_group_list[group]); */
group_list[group].sock_remote_addr.sin_port = htons (group_list[group].port); if (setsockopt(group_list[group].socket, SOL_SOCKET, SO_REUSEADDR,
} &reuse_addr, sizeof (reuse_addr)) < 0) {
LOG_E(EMU, "[MULTICAST] ERROR : setsockopt:SO_REUSEADDR, exiting ...");
exit (EXIT_FAILURE);
}
if (multicast_if != NULL) {
if (setsockopt(group_list[group].socket, SOL_SOCKET,SO_BINDTODEVICE,
multicast_if, 4) < 0) {
LOG_E(EMU,
"[MULTICAST] ERROR : setsockopt:SO_BINDTODEVICE on interface %s, exiting ...\n",
multicast_if);
LOG_E(EMU,
"[MULTICAST] make sure that you have a root privilage or run with sudo -E \n");
exit (EXIT_FAILURE);
}
}
#if !defined(ENABLE_TCP_MULTICAST)
/* Make the socket blocking */
socket_setnonblocking(group_list[group].socket);
#endif
multicast_loop = 0;
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_MULTICAST_LOOP,
&multicast_loop, sizeof (multicast_loop)) < 0) {
LOG_E(EMU,
"[MULTICAST] ERROR: %s line %d multicast_link_main_loop() IP_MULTICAST_LOOP %m",
__FILE__, __LINE__);
exit (EXIT_FAILURE);
}
// Join the broadcast group:
command.imr_multiaddr.s_addr = inet_addr (group_list[group].host_addr);
command.imr_interface.s_addr = htonl (INADDR_ANY);
if (command.imr_multiaddr.s_addr == -1) {
LOG_E(EMU, "[MULTICAST] ERROR: %s line %d NO MULTICAST", __FILE__, __LINE__);
exit (EXIT_FAILURE);
}
if (setsockopt (group_list[group].socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&command, sizeof (command)) < 0) {
LOG_E(EMU, "[MULTICAST] ERROR: %s line %d IP_ADD_MEMBERSHIP %m", __FILE__,
__LINE__);
exit (EXIT_FAILURE);
}
memset (&group_list[group].sock_remote_addr, 0, sizeof (struct sockaddr_in));
group_list[group].sock_remote_addr.sin_family = AF_INET;
group_list[group].sock_remote_addr.sin_addr.s_addr = inet_addr (
multicast_group_list[group]);
group_list[group].sock_remote_addr.sin_port = htons (group_list[group].port);
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -137,86 +144,69 @@ void
multicast_link_build_select_list () 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
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__);
//------------------------------------------------------------------------------
void *
multicast_link_main_loop (void *param)
{
//------------------------------------------------------------------------------
struct timeval timeout; /* Timeout for select */
int readsocks; /* Number of sockets ready for reading */
#ifdef USER_MODE
#endif //USER_MODE
highsock = -1;
while (1) {
multicast_link_build_select_list ();
/* [24/06/13] SR: Set the timeout to one second ->
* avoid infinite loop if no data to read.
*/
timeout.tv_sec = 1;
timeout.tv_usec = 0;
readsocks = select (highsock + 1, &socks, (fd_set *) 0, (fd_set *) 0, &timeout);
if (readsocks < 0) {
LOG_E(EMU, "Multicast select failed (%d:%s)\n", errno, strerror(errno));
// exit();
} else if (readsocks > 0) {
//msg("calling multicast link read\n");
multicast_link_read ();
// usleep(1);
} else {
/* Timeout */
LOG_I(EMU, "Multicast select time-out\n");
} }
} return num;
#ifdef USER_MODE
#endif //USER_MODE
} }
//----------------------------------------------------------------------------- int multicast_link_read_data_from_sock(uint8_t is_master)
void
multicast_link_start ( void (*rx_handlerP) (unsigned int, char*), unsigned char multicast_group, char * multicast_ifname)
{ {
//----------------------------------------------------------------------------- struct timeval timeout, *timeout_p;
rx_handler = rx_handlerP; int readsocks; /* Number of sockets ready for reading */
multicast_group = multicast_group;
multicast_if = multicast_ifname; timeout.tv_sec = 0;
msg("[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n", timeout.tv_usec = 3000;
(multicast_if == NULL) ? "not specified" : multicast_if, multicast_group, rx_handler);
#ifdef BYPASS_PHY if (is_master == 0) {
// pthread_mutex_init(&Bypass_phy_wr_mutex,NULL); /* UE will block indefinetely if no data is sent from eNB
//pthread_cond_init(&Bypass_phy_wr_cond,NULL); * NOTE: a NULL timeout for select will block indefinetely
//Bypass_phy_wr=0; */
#endif //BYPASS_PHY timeout_p = NULL;
multicast_link_init (); } else {
msg("[MULTICAST] multicast link start thread\n"); /* In case of eNB set the timeout to 500 usecs after which we consider
if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop, NULL) != 0) { * the packets as dropped.
msg ("[MULTICAST LINK] Thread started\n"); */
exit (-2); timeout_p = &timeout;
} else { }
pthread_detach (main_loop_thread); // disassociate from parent
msg ("[MULTICAST LINK] Thread detached\n"); highsock = -1;
} multicast_link_build_select_list ();
LOG_D(EMU, "Stuck on select with timeout %s\n",
timeout_p == NULL ? "infinite" : "1000 usecs");
readsocks = select(highsock + 1, &socks, (fd_set *) 0, (fd_set *) 0, timeout_p);
if (readsocks < 0) {
LOG_E(EMU, "Multicast select failed (%d:%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
} else if (readsocks > 0) {
LOG_D(EMU, "Multicast Normal read\n");
multicast_link_read();
} else {
/* Timeout */
LOG_I(EMU, "Multicast select time-out\n");
return 1;
}
return 0;
}
void* multicast_link_main_loop (void *param)
{
while (1) {
multicast_link_read_data_from_sock(0);
}
return NULL;
}
void multicast_link_start(void (*rx_handlerP) (unsigned int, char *),
unsigned char multicast_group, char *multicast_ifname)
{
rx_handler = rx_handlerP;
multicast_group = multicast_group;
multicast_if = multicast_ifname;
LOG_I(EMU, "[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n",
(multicast_if == NULL) ? "not specified" : multicast_if, multicast_group,
rx_handler);
multicast_link_init ();
#if ! defined(ENABLE_NEW_MULTICAST)
LOG_D(EMU, "[MULTICAST] multicast link start thread\n");
if (pthread_create (&main_loop_thread, NULL, multicast_link_main_loop,
NULL) != 0) {
LOG_E(EMU, "[MULTICAST LINK] Error in pthread_create (%d:%s)\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
} else {
pthread_detach(main_loop_thread); // disassociate from parent
LOG_I(EMU, "[MULTICAST LINK] Thread detached\n");
}
#endif
} }
@@ -1,11 +1,11 @@
/*! \file multicast.h /*! \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 @@
# 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
@@ -1,11 +1,11 @@
/*! \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;
#define GRAAL_NETLINK_ID 31 #define GRAAL_NETLINK_ID 31
int netlink_init(void) { int netlink_init(void)
{
int ret;
nas_sock_fd = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID);
if (nas_sock_fd == -1) {
printf("[NETLINK] Error opening socket %d\n",nas_sock_fd);
return(-1);
}
printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd);
int ret; ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK);
printf("[NETLINK] fcntl returns %d\n",ret);
memset(&nas_src_addr, 0, sizeof(nas_src_addr));
nas_sock_fd = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID); nas_src_addr.nl_family = AF_NETLINK;
if (nas_sock_fd==-1) { nas_src_addr.nl_pid = 1;//getpid(); /* self pid */
printf("[NETLINK] Error opening socket %d\n",nas_sock_fd); nas_src_addr.nl_groups = 0; /* not in mcast groups */
return(-1); ret = bind(nas_sock_fd, (struct sockaddr *)&nas_src_addr,
} sizeof(nas_src_addr));
printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd);
ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK); printf("[NETLINK] bind returns %d\n",ret);
printf("[NETLINK] fcntl returns %d\n",ret);
memset(&nas_src_addr, 0, sizeof(nas_src_addr)); memset(&nas_dest_addr, 0, sizeof(nas_dest_addr));
nas_src_addr.nl_family = AF_NETLINK; nas_dest_addr.nl_family = AF_NETLINK;
nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ nas_dest_addr.nl_pid = 0; /* For Linux Kernel */
nas_src_addr.nl_groups = 0; /* not in mcast groups */ nas_dest_addr.nl_groups = 0; /* unicast */
ret = bind(nas_sock_fd, (struct sockaddr*)&nas_src_addr,
sizeof(nas_src_addr));
printf("[NETLINK] bind returns %d\n",ret); nas_nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
/* Fill the netlink message header */
nas_nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nas_nlh->nlmsg_pid = 1;//getpid(); /* self pid */
nas_nlh->nlmsg_flags = 0;
memset(&nas_dest_addr, 0, sizeof(nas_dest_addr)); nas_iov.iov_base = (void *)nas_nlh;
nas_dest_addr.nl_family = AF_NETLINK; nas_iov.iov_len = nas_nlh->nlmsg_len;
nas_dest_addr.nl_pid = 0; /* For Linux Kernel */ memset(&nas_msg,0,sizeof(nas_msg));
nas_dest_addr.nl_groups = 0; /* unicast */ nas_msg.msg_name = (void *)&nas_dest_addr;
nas_msg.msg_namelen = sizeof(nas_dest_addr);
nas_nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); nas_msg.msg_iov = &nas_iov;
/* Fill the netlink message header */ nas_msg.msg_iovlen = 1;
nas_nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nas_nlh->nlmsg_pid = 1;//getpid(); /* self pid */
nas_nlh->nlmsg_flags = 0;
nas_iov.iov_base = (void *)nas_nlh;
nas_iov.iov_len = nas_nlh->nlmsg_len;
memset(&nas_msg,0,sizeof(nas_msg));
nas_msg.msg_name = (void *)&nas_dest_addr;
nas_msg.msg_namelen = sizeof(nas_dest_addr);
nas_msg.msg_iov = &nas_iov;
nas_msg.msg_iovlen = 1;
/* Read message from kernel */
memset(nas_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
return(nas_sock_fd); /* Read message from kernel */
memset(nas_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
return(nas_sock_fd);
} }
+13 -4
View File
@@ -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);
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
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_ */
+5 -2
View File
@@ -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];
+77
View File
@@ -0,0 +1,77 @@
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2012 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include <stdio.h>
#ifndef ASSERTIONS_H_
#define ASSERTIONS_H_
#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \
do { \
if (!(cOND)) { \
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
__FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, #vALUE1": %d\n"#vALUE2": %d\n"#vALUE3": %d\n", \
(int)vALUE1, (int)vALUE2, (int)vALUE3); \
abort(); \
} \
} while(0)
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
do { \
if (!(cOND)) { \
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
__FILE__, __LINE__, __FUNCTION__); \
fprintf(stderr, #vALUE1": %d\n"#vALUE2": %d\n"#vALUE3": %d\n" \
#vALUE4": %d\n", \
(int)vALUE1, (int)vALUE2, (int)vALUE3, (int)vALUE4); \
exit(EXIT_FAILURE); \
} \
} while(0)
#define DevParam(vALUE1, vALUE2, vALUE3) \
DevCheck(0 == 1, vALUE1, vALUE2, vALUE3)
#define DevAssert(cOND) \
do { \
if (!(cOND)) { \
fprintf(stderr, "%s:%d:%s Assertion `"#cOND"` failed.\n", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} \
} while(0)
#define DevMessage(mESSAGE) \
do { \
fprintf(stderr, "%s:%d:%s Execution interrupted: `"#mESSAGE"`.\n", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} while(0)
#endif /* ASSERTIONS_H_ */
+1
View File
@@ -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)