Files
openairinterface5g/openair1/EMOS/SIM/emos_sim.c
T
ghaddab 56c3197b09 License Corrected
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5713 818b1a75-f10b-46b9-bf7c-635c3b92a50f
2014-08-13 16:22:56 +00:00

420 lines
10 KiB
C

/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that 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 OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
// EMOS simulator for testing of the routines to be used in the real-time
// acquisition mode.
//
// Leonardo S. Cardoso 20070808 - sampaio@eurecom.fr
//
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/vars.h"
#include "PHY/CONFIG/vars.h"
#include "MAC_INTERFACE/vars.h"
#include "PHY/TOOLS/defs.h"
//#include "dlc_engine.h"
//#include "MAC_defs.h"
#include <stdio.h>
//#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include <sys/shm.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <time.h>
// Leosam 08/08: What are these?
#define BW 5.0
#define Td 1.0
void help ();
void error ();
// Leosam 08/08: What are the arguments?
int
main (int argc, char **argv)
{
// Command line parsing
int input_val = 1000; // Value serving as an input relatad to the SNR
int max_num_ofdm_sym = 64; // Index of the last frame for the channel estimation
int be_verbose = 0; // Operate in verbose mode
int index;
int c;
unsigned int rx_energy[NB_ANTENNAS], n0_energy[NB_ANTENNAS];
if (argc == 1)
{
error ();
exit (-1);
}
while ((c = getopt (argc, argv, "hVv:n:")) != -1)
{
switch (c)
{
case 'h':
help ();
exit (1);
case 'V':
be_verbose = 1;
break;
case 'v':
input_val = atoi (optarg);
break;
return 1;
case 'n':
max_num_ofdm_sym = atoi (optarg);
break;
return 1;
default:
error ();
exit (-1);
}
}
//
// Initialization stuff
//
int i, ii, j, ret, delay, l;
short seed[3];
// Leosam 08/08: What is this amps?
double amps[8] = { 1.0, .8, .4, .2, .1, .05, .025, .01 };
struct complex ch[NB_ANTENNAS * NB_ANTENNAS][10 + (int) (1 + 2 * BW * Td)];
struct complex rx_tmp, tx, n, phase;
char *chbch_pdu;
int chbch_size;
int extension;
unsigned char dummy_mac_pdu[120];
#ifdef USER_MODE
char fname[40], vname[40];
#endif // USER_MODE
if (be_verbose)
printf ("Allocating memory for PHY_VARS\n");
// Memory allocation for PHY and MAC structures
PHY_vars = malloc (sizeof (PHY_VARS));
PHY_config = malloc (sizeof (PHY_CONFIG));
mac_xface = malloc (sizeof (MAC_xface));
// Loading of the configuration data
if ((config = fopen ("config.cfg", "r")) == NULL) // this can be configured
{
if (be_verbose)
printf ("[Main USER] The openair configuration file <config.cfg> could not be found!\n");
exit (0);
}
if ((scenario = fopen ("scenario.scn", "r")) == NULL)
{
if (be_verbose)
printf ("[Main USER] The openair scenario file <scenario.scn> could not be found!\n");
exit (0);
}
if (be_verbose)
printf ("Opened configuration files\n");
reconfigure_MACPHY (scenario);
if (be_verbose)
dump_config ();
// Leosam 08/08: This is repeated bellow. Is it necessary?
mac_xface->is_cluster_head = 0;
// Initialize the PHY and MAC variables
phy_init (NB_ANTENNAS_TX);
if (be_verbose)
printf ("Initialized PHY variables\n");
// Fill MAC PDU buffer for CHBCH
seed[0] = (short) time (NULL);
seed[1] = (short) time (NULL);
seed[2] = (short) time (NULL);
seed48 (&seed[0]);
randominit ();
/*
* for (i=0;i<mac_xface->mac_tch->bch_tx[0].size-4;i++) {
* mac_xface->mac_tch->bch_tx[0].data[i] = i;//(u8)lrand48();
* }
*
*
* printf("Filled CHBCH PDU with random data\n");
*
* // Generate one CHBCH
* phy_generate_chbch(0);
*
*/
//
// Preparation for the TX procedure
//
// Creation of the CHBCH
chbch_size = (NUMBER_OF_CARRIERS_PER_GROUP * (NUMBER_OF_CHBCH_SYMBOLS) * 16) >> 3;
if (be_verbose)
printf ("chbch_size = %d\n", chbch_size);
chbch_pdu = malloc (chbch_size);
for (i = 0; i < chbch_size - 4; i++)
{
chbch_pdu[i] = i;
}
if (be_verbose)
printf ("Filled CHBCH PDU (%d bytes) with data\n", chbch_size);
// Leosam 08/08: O.o
delay = 1032;
// delay = 0;
// Generation of the CHBCH
phy_generate_chbch (0, 1, NB_ANTENNAS_TX, chbch_pdu);
// Generation of the pilot symbols
for (i = 16; i < max_num_ofdm_sym; i++)
{
phy_generate_sch (0, i, 0xFFFF, 1, NB_ANTENNAS_TX);
}
mac_xface->is_cluster_head = 0;
if (be_verbose)
{
for (ii=0; ii<NB_ANTENNAS; ii++)
{
sprintf (fname, "txsig%d.m", ii);
sprintf (vname, "txs%d", ii);
write_output (fname, vname,
(s16 *) PHY_vars->tx_vars[ii].TX_DMA_BUFFER,
NUMBER_OF_SYMBOLS_PER_FRAME * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES, 1, 1);
}
}
// generate channels
if (be_verbose)
printf ("Generating MIMO Channels\n");
phase.r = 0;
phase.i = 0;
printf("Phase pointer %0x\n",&phase);
for (i = 0; i < NB_ANTENNAS; i++)
{
for (j = 0; j < NB_ANTENNAS; j++)
{
random_channel (amps, Td, 8, BW, ch[j + (i * NB_ANTENNAS)],0.0,&phase);
}
}
if (be_verbose)
printf ("chbch_pdu %x (%d)\n", PHY_vars->chbch_data[0].demod_pdu, chbch_size);
if (be_verbose)
{
for (l = 0; l < (1 + 2 * BW * Td); l++)
{
printf ("(%f,%f)\n", ch[0][l]);
}
}
//
// TX procedure
//
// Transmission
//
//////////////////////////
// Foreach symbol
for (i = 0; i < (max_num_ofdm_sym) * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++)
{
// Foreach RX antenna
for (ii = 0; ii < NB_ANTENNAS; ii++)
{
rx_tmp.r = 0;
rx_tmp.i = 0;
n.r = gaussdouble (0.0, 10.0);
n.i = gaussdouble (0.0, 10.0);
// Foreach TX antenna
for (j = 0; j < NB_ANTENNAS; j++)
{
// Foreach symbol
for (l = 0; l < (1 + 2 * BW * Td); l++)
{
tx.r = (double) (((s16 *) & PHY_vars->tx_vars[j].
TX_DMA_BUFFER[0 *
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES])
[2 * (i - l)]) / sqrt (1.0 * input_val);
tx.i = (double) (((s16 *) & PHY_vars->tx_vars[j].
TX_DMA_BUFFER[0 *
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES])
[1 +
(2 * (i - l))]) / sqrt (1.0 * input_val);
rx_tmp.r +=
(tx.r * ch[j + (ii * NB_ANTENNAS)][l].r) -
(tx.i * ch[j + (ii * NB_ANTENNAS)][l].i);
rx_tmp.i +=
(tx.i * ch[j + (ii * NB_ANTENNAS)][l].r) +
(tx.r * ch[j + (ii * NB_ANTENNAS)][l].i);
}
}
((s16 *) & PHY_vars->rx_vars[ii].
RX_DMA_BUFFER[delay + (0 * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)])[2 * i] =
(short) (rx_tmp.r + n.r);
((s16 *) & PHY_vars->rx_vars[ii].
RX_DMA_BUFFER[delay + (0 * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)])[1 +
(2 * i)] =
(short) (rx_tmp.i + n.i);
}
}
if (be_verbose)
{
for (ii=0; ii<NB_ANTENNAS; ii++)
{
sprintf (fname, "rxsig%d.m", ii);
sprintf (vname, "rxs%d", ii);
write_output (fname, vname,
(s16 *) PHY_vars->rx_vars[ii].RX_DMA_BUFFER,
NUMBER_OF_SYMBOLS_PER_FRAME * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES, 1, 1);
}
}
//
// RX procedure
//
if (be_verbose)
printf ("Starting RX\n");
// Sync
phy_synch_time (PHY_vars->rx_vars[0].RX_DMA_BUFFER,
&sync_pos,
FRAME_LENGTH_COMPLEX_SAMPLES,
768,
CHSCH,
0);
// Forcing sync to 0 since were running offline
if (be_verbose)
msg ("sync_pos = %d\n", sync_pos);
PHY_vars->rx_vars[0].offset = 0; //sync_pos;
// estamte the signal and noise energy
for (ii=0; ii < NB_ANTENNAS; ii++)
{
rx_energy[ii] = signal_energy((int *)&PHY_vars->rx_vars[ii].RX_DMA_BUFFER[PHY_vars->rx_vars[0].offset+CYCLIC_PREFIX_LENGTH],
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
n0_energy[ii] = signal_energy((int *)&PHY_vars->rx_vars[ii].RX_DMA_BUFFER[PHY_vars->rx_vars[0].offset+CYCLIC_PREFIX_LENGTH +
(NUMBER_OF_CHSCH_SYMBOLS+NUMBER_OF_CHBCH_SYMBOLS+1) * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
//msg("CYCLIC_PREFIX_LENGTH=%d, NUMBER_OF_CHSCH_SYMBOLS=%d, NUMBER_OF_CHBCH_SYMBOLS=%d, OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n", CYCLIC_PREFIX_LENGTH, NUMBER_OF_CHSCH_SYMBOLS, NUMBER_OF_CHBCH_SYMBOLS, OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
msg("symbol = %d\n", PHY_vars->rx_vars[ii].RX_DMA_BUFFER[PHY_vars->rx_vars[0].offset+CYCLIC_PREFIX_LENGTH +
(NUMBER_OF_CHSCH_SYMBOLS+NUMBER_OF_CHBCH_SYMBOLS) * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES]);
msg("SNR Ant %d = %d / %d \n", ii, rx_energy[ii], n0_energy[ii]);
}
// CHBCH channel estimation
phy_channel_estimation_top(PHY_vars->rx_vars[0].offset,0,0,0,NB_ANTENNAS,0);
//phy_channel_estimation_top (PHY_vars->rx_vars[0].offset, 0, 0, 0);
phy_decode_chbch (0, &dummy_mac_pdu[0], NB_ANTENNAS, NB_ANTENNAS_TX, 120);
if (be_verbose)
{
for (i = 0; i < chbch_size; i++)
{
msg ("Data %x : %x\n", i, PHY_vars->chbch_data[0].demod_pdu[i]);
}
}
printf("PERROR_SHIFT: %d\n", PERROR_SHIFT);
//
// Channel estimation procedure
//
// for (i = 0; i < max_num_ofdm_sym; i++)
// {
// phy_channel_estimation_top(PHY_vars->rx_vars[0].offset,i,0,0,1);
// }
phy_channel_est_emos(16, 16, max_num_ofdm_sym-1, TRUE, 0);
phy_cleanup ();
if (be_verbose)
printf ("Exiting\n");
}
void
help ()
{
printf ("Usage: emos_sim [OPTIONS] [ARGUMENTS]\n");
printf ("Simulates the transmission of frames using the EMOS system\n\n");
printf ("-h shows this help\n");
printf ("-V be verbose\n");
printf ("-v value related to SNR\n");
printf ("-n number of OFDM symbols to average (1~48)\n");
printf ("\nLeonardo S. Cardoso <sampaio@eurecom.fr>\n");
}
void
error ()
{
printf ("Wrong option or argument. Try -h to see the valid options.\n");
}