// // Author: Luca Anchora, // Date: 14 December 2010 // #include "ns3/core-module.h" #include "ns3/common-module.h" #include "ns3/node-module.h" #include "ns3/helper-module.h" #include "ns3/mobility-module.h" #include "ns3/contrib-module.h" #include "ns3/lte-module.h" #include #include "ns3/global-route-manager.h" #include #include "ns3/random-variable.h" #include "ns3/central-authority.h" #include #include #include #include #include #include NS_LOG_COMPONENT_DEFINE ("multi_op"); using namespace ns3; typedef std::vector chann_vect; /** * Here we create a simple simulation scenario for an LTE network with some base * stations and several UEs connected to them. Here we set all the main configuration * parameters. * We do not install any application since a packet generator is created directly * at the MAC layer, thus by-passing all the other layers of the protocol stack. */ int main (int argc, char *argv[]) { if(argc!=7) { std::cout << "Error in the command line. The program needs 6 input parameters:" << std::endl; std::cout << "\t1) number of the current run" << std::endl; std::cout << "\t2) number of BSs" << std::endl; std::cout << "\t3) number of UEs per BS" << std::endl; std::cout << "\t4) percentage of sharing in [0,100]" << std::endl; std::cout << "\t5) duration of the simulation" << std::endl; std::cout << "\t6) seed" << std::endl; exit(1); } struct timeval *tv_initial, *tv_final; tv_initial = (struct timeval*)malloc(sizeof(struct timeval)); tv_final = (struct timeval*)malloc(sizeof(struct timeval)); gettimeofday(tv_initial, 0); int nbEnb; //number of eNBs in the scenario int ue_bs; //number of UEs for each eNB int nbUE; //total number of UEs float shar_percent; //sharing percentage double sim_len; //duration of the simulation (in seconds) double x_bs = 0.0, y_bs = 0.0, z_bs = 0.0; SeedManager::SetSeed(atoi(argv[6]));//seed for the simulations SeedManager::SetRun(atof(argv[1]));//set the number of the current run nbEnb = atoi(argv[2]); //number of BSs in the scenario ue_bs = atoi(argv[3]); //number of UEs per BS nbUE = 40 + ue_bs;// * nbEnb; //total number of UEs in the scenario shar_percent = atof(argv[4])/100.0;//percentage of spectrum shared by each BS (operator) sim_len = atof(argv[5]); //Create all the eNBs and a central authority that manages all of them LteHelper lte_helper[nbEnb];//one for each cell CentralAuthority* authority = new CentralAuthority(); NodeContainer ueNodes[nbEnb]; NodeContainer enbNodes[nbEnb]; NetDeviceContainer ueDevs[nbEnb]; NetDeviceContainer enbDevs[nbEnb]; // CREATE NODE CONTAINER AND CREATE LTE NODES UniformVariable* u = new UniformVariable(); Ipv4AddressHelper address; address.SetBase ("10.1.1.0", "255.255.255.0"); double cellLoaded = u->GetValue(0.0, 1.0); int up0 = 0, up1 = 0; if(cellLoaded > 0.5) { up0 = 40; up1 = ue_bs; }else{ up0 = ue_bs; up1 = 40; } for(int i=0; i enb[nbEnb]; Ptr ue[nbUE]; int subchann_dl = 100; //total number of subchannels for the downlink int subchann_ul = 100; //total number of subchannels for the uplink int first_dlsubc = 0; int first_ulsubc = 0; int portion_dlsubc = subchann_dl/nbEnb; //number of downlink subchannels for each BS int portion_ulsubc = subchann_ul/nbEnb; //number of uplink subchannels for each BS int shared_portion = (int)(portion_dlsubc * shar_percent); chann_vect dlSubChannels[nbEnb]; chann_vect ulSubChannels[nbEnb]; std::vector dlSubPrio[nbEnb]; prioSubChannel temp; //We take into consideration spectrum sharing among base stations. Each eNB is assigned //a larger part of the spectrum, including both the frequencies explicitly assigned to //it and those shared by other eNBs, but on the latters it has a lower access priority. double ue_Xpos[nbEnb][40];//ue_bs]; double ue_Ypos[nbEnb][40];//ue_bs]; double radius = 1500.0; if(cellLoaded > 0.5) { (DynamicCast(enbDevs[0].Get (0)->GetObject ()->GetPhy ()))->setDeviceId(0); (DynamicCast(enbDevs[1].Get (0)->GetObject ()->GetPhy ()))->setDeviceId(1); }else { (DynamicCast(enbDevs[0].Get (0)->GetObject ()->GetPhy ()))->setDeviceId(1); (DynamicCast(enbDevs[1].Get (0)->GetObject ()->GetPhy ()))->setDeviceId(0); } if(u->GetValue(0.0, 1.0) > 0.5) { for(int i=0; iGetValue(-radius, radius); ue_Ypos[0][i] = u->GetValue(-radius, radius); }while( (ue_Xpos[0][i]*ue_Xpos[0][i] + ue_Ypos[0][i]*ue_Ypos[0][i] - radius*radius) > 0 ); } for(int i=0; iGetValue(-radius, radius); ue_Ypos[1][i] = u->GetValue(-radius, radius); }while( (ue_Xpos[1][i]*ue_Xpos[1][i] + ue_Ypos[1][i]*ue_Ypos[1][i] - radius*radius) > 0 ); } }else{ for(int i=0; iGetValue(-radius, radius); ue_Ypos[1][i] = u->GetValue(-radius, radius); }while( (ue_Xpos[1][i]*ue_Xpos[1][i] + ue_Ypos[1][i]*ue_Ypos[1][i] - radius*radius) > 0 ); } for(int i=0; iGetValue(-radius, radius); ue_Ypos[0][i] = u->GetValue(-radius, radius); }while( (ue_Xpos[0][i]*ue_Xpos[0][i] + ue_Ypos[0][i]*ue_Ypos[0][i] - radius*radius) > 0 ); } } for(int bs = 0; bs < nbEnb; bs++) { enb[bs] = enbDevs[bs].Get (0)->GetObject (); authority->RegistereNB(enb[bs]->GetPhy ()); (DynamicCast(enb[bs]->GetPhy()))->SetCA(authority); //Register the downlink and uplink subchannels for the BS. The whole spectrum //is divided among the BSs. int inf, sup; //We consider the scenario with only two eNBs. if(bs==0) { inf = first_dlsubc; sup = first_dlsubc + portion_dlsubc + shared_portion; }else{ inf = first_dlsubc - shared_portion; sup = first_dlsubc + portion_dlsubc; } for(int i = inf; i < sup; i++) { dlSubChannels[bs].push_back (i); temp.subChannel = i; if(bs==0) { if(i < (first_dlsubc + portion_dlsubc)) temp.priority = 1; else temp.priority = 0; }else{ //count==1 if(i >= first_dlsubc) temp.priority = 1; else temp.priority = 0; } dlSubPrio[bs].push_back(temp); } for(int i = first_ulsubc; i < (first_ulsubc + portion_ulsubc); i++) ulSubChannels[bs].push_back (i); first_dlsubc += portion_dlsubc; first_ulsubc += portion_ulsubc; enb[bs]->GetPhy ()->SetDownlinkSubChannels (dlSubChannels[bs]); enb[bs]->GetPhy ()->SetUplinkSubChannels (ulSubChannels[bs]); enb[bs]->GetPhy ()->SetDownlinkPrioSubChannels (dlSubPrio[bs]); // Configure mobility for the BS char fname[50]; memset(fname, 0, 50); sprintf(fname, "BS%d_pos.txt", bs); FILE* fp_bspos = fopen(fname, "w"); Ptr enbMobility = new ConstantPositionMobilityModel (); x_bs = 50.0*bs;//meters enbMobility->SetPosition (Vector (x_bs, y_bs, z_bs)); lte_helper[bs].AddMobility (enb[bs]->GetPhy (), enbMobility); fprintf(fp_bspos, "%.6f\t%.6f\n", x_bs, y_bs); fflush(fp_bspos); fclose(fp_bspos); sprintf(fname, "BS%d_UEpos.txt", bs); FILE* fp_uepos = fopen(fname, "w"); //Configure each UE for the current BS int up = (bs==0)?up0:up1; for(int ue_count=0; ue_count < up; ue_count++) { char fname[50]; memset(fname, 0, 50); ue[ue_count] = ueDevs[bs].Get (ue_count)->GetObject (); lte_helper[bs].RegisterUeToTheEnb (ue[ue_count], enb[bs]); ue[ue_count]->GetPhy ()->SetDownlinkSubChannels (dlSubChannels[bs]); ue[ue_count]->GetPhy ()->SetUplinkSubChannels (ulSubChannels[bs]); //Mobility for the UE // double radius = 1500.0; // double x_ue = 0, y_ue= 0; // do // { // x_ue = u->GetValue(-radius, radius); // y_ue = u->GetValue(-radius, radius); // }while( (x_ue*x_ue + y_ue*y_ue - radius*radius) > 0 ); // x_ue += x_bs; // y_ue += y_bs; // double dist = sqrt((x_ue - x_bs)*(x_ue - x_bs) + (y_ue - y_bs)*(y_ue - y_bs)); ue_Xpos[bs][ue_count] += x_bs; ue_Ypos[bs][ue_count] += y_bs; fprintf(fp_uepos, "%.6f\t%.6f\n", ue_Xpos[bs][ue_count], ue_Ypos[bs][ue_count]); Ptr ueMobility = new ConstantVelocityMobilityModel (); // ueMobility->SetPosition (Vector (x_ue, y_ue, 0.0)); ueMobility->SetPosition (Vector (ue_Xpos[bs][ue_count], ue_Ypos[bs][ue_count], 0.0)); //We set to 0 the UE speed, but the Doppler shift has been set so that //a certain movement is simulated. double x_speed = 0; double y_speed = 0; ueMobility->SetVelocity (Vector (x_speed, y_speed, 0.0)); lte_helper[bs].AddMobility (ue[ue_count]->GetPhy (), ueMobility); lte_helper[bs].AddDownlinkChannelRealization (enbMobility, ueMobility, ue[ue_count]->GetPhy ()); } fflush(fp_uepos); fclose(fp_uepos); }//end for(int count = 0; count < nbEnb; count++) /* Register the inter-cell interference */ for(int i=0; i downlink = lte_helper[i].GetDownlinkChannel(); //All the UEs of cell j are registered to cell i for the interference //in the downlink. for(NetDeviceContainer::Iterator dev = ueDevs[j].Begin(); dev != ueDevs[j].End(); dev++) { downlink->AddRxInterf( (DynamicCast(*dev))->GetPhy()->GetDownlinkSpectrumPhy () ); } } } if(u) delete u; std::cout << "Starting simulation....." << std::endl; Simulator::Stop (Seconds (sim_len)); Simulator::Run (); Simulator::Destroy (); std::cout << "\nSimulation terminated successfully.\n" << std::endl; gettimeofday(tv_final, 0); double usec = (tv_final->tv_sec - tv_initial->tv_sec)*1000000 + (tv_final->tv_usec - tv_initial->tv_usec); FILE* fp_time = fopen("time.txt", "w"); fprintf(fp_time, "%f\n", usec); fflush(0); fclose(fp_time); return 0; }