#include <stdio.h>
#include <string>
#include <iostream>
#include <cstring>
#ifdef _OPENMP
#include <omp.h>
#endif
#include "network_planning_parallel.h"
#ifndef API_DATA_FOLDER
#define API_DATA_FOLDER "../../api/winprop/data/"
#endif // !API_DATA_FOLDER
#define SERVICES_LTE 13
#define MAX_TRX 3
#define MAX_THREADS 4
int main(int argc, char** argv)
{
const char* TransmissionMode_Name[SERVICES_LTE] = {
"QPSK - R=1_8",
"QPSK - R=1_5",
"QPSK - R=1_4",
"QPSK - R=1_3",
"QPSK - R=1_2",
"QPSK - R=2_3",
"QPSK - R=4_5",
"16 QAM - R=1_2",
"16 QAM - R=2_3",
"16 QAM - R=4_5",
"64 QAM - R=2_3",
"64 QAM - R=3_4",
"64 QAM - R=4_5" };
double TransmissionMode_Bitrate[SERVICES_LTE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
double TransmissionMode_SNIR[SERVICES_LTE] = { -5.4, -3.1, -2.2, -0.4, 1.6, 3.5, 5.6, 7.0, 10.7, 11.8, 14.3, 16.1, 17.2 };
int TransmissionMode_Coderate_K[SERVICES_LTE] = { 1, 1, 1, 1, 1, 2, 4, 1, 2, 4, 2, 3, 4 };
int TransmissionMode_Coderate_N[SERVICES_LTE] = { 8, 5, 4, 3, 2, 3, 5, 2, 3, 5, 3, 4, 5 };
int TransmissionMode_MCS[SERVICES_LTE] = { 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 6, 6, 6 };
double TransmissionMode_Backoff[SERVICES_LTE] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0 };
double AntennaX[MAX_TRX] = { 5.920, 63.860, 63.400 };
double AntennaY[MAX_TRX] = { 6.240, -22.870, 12.610 };
int AntennaCarrier[MAX_TRX] = { 1, 2, 2 };
char AntennaName[MAX_TRX][500] = { "Site 1", "Site 2", "Site 3" };
int MapIndex[MAX_TRX];
WinProp_Result *MaxThroughput = NULL;
WinProp_Result *MaxSNIR = NULL;
WinProp_Result PropResults[MAX_TRX];
WinProp_Antenna Antenna[MAX_TRX];
for (int Count = 0; Count < MAX_TRX; Count++)
{
WinProp_Structure_Init_Antenna(&Antenna[Count]);
WinProp_Structure_Init_Result(&PropResults[Count]);
}
WinProp_Callback Callback;
WinProp_Structure_Init_Callback(&Callback);
WinProp_Carrier Carrier;
WinProp_Structure_Init_Carrier(&Carrier);
int Signal_for_MIMO = -1, Stream_for_MIMO = -1;
char ProjectName[200];
double Frequency = 1800.0;
int NrPredictionHeights = 1;
double PredictionHeightsMulti[2] = { 1.5, 5.2};
int Error = 0;
int ProjectHandle = 0;
NrPredictionHeights = sizeof(PredictionHeightsMulti)/sizeof(PredictionHeightsMulti[0]);
if (Error == 0)
{
Error = WinProp_Net_Project_Open(&ProjectHandle, NET_AIRINTERFACE_LTE_GENERIC, NULL);
}
if (Error == 0)
{
int IntValue = MAX_THREADS;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_SETTINGS_NUMBER_THREADS, NULL, &IntValue, NULL);
}
if (Error == 0)
{
int IntValue = 1;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_DUPLEX_SUBMODE, NULL, &IntValue, NULL);
}
if (Error == 0) {
sprintf(ProjectName, "%s", "LTE Project");
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_PROJECTNAME, NULL, NULL, ProjectName);
}
double CarrierSeparation = 0.;
if (Error == 0)
{
Error = WinProp_Net_Project_Para_Get(ProjectHandle, NET_PARA_CARRIER_SEPARATION, &CarrierSeparation, NULL, NULL);
}
if (Error == 0)
{
CarrierSeparation *= 0.000001;
for (int CurrentCarrier = 0; CurrentCarrier < 3; CurrentCarrier++)
{
double FrequencyUL = 1930.0 + (CurrentCarrier * CarrierSeparation);
double FrequencyDL = 2120.0 + (CurrentCarrier * CarrierSeparation);
Error = WinProp_Net_Carrier_Add(ProjectHandle, CurrentCarrier + 1);
Error = WinProp_Net_Carrier_Para_Set(
ProjectHandle, CurrentCarrier + 1, NET_PARA_CARRIER_FREQ_DL, &FrequencyUL, NULL, NULL);
Error = WinProp_Net_Carrier_Para_Set(
ProjectHandle, CurrentCarrier + 1, NET_PARA_CARRIER_FREQ_UL, &FrequencyDL, NULL, NULL);
}
}
if (Error == 0)
{
int NrCarriers = 0;
Error = WinProp_Net_Project_Para_Get(ProjectHandle, NET_PARA_CARRIERS, NULL, &NrCarriers, NULL);
if (Error == 0)
{
if (NrCarriers != 3)
Error = 1;
}
}
if (Error == 0)
{
for (int CurrentService = 0; CurrentService < SERVICES_LTE; CurrentService++)
{
char ServiceName[500];
sprintf(ServiceName, "%s", TransmissionMode_Name[CurrentService]);
Error = WinProp_Net_TransmissionMode_Add(ProjectHandle, ServiceName, CurrentService);
int IntValue = SERVICES_LTE - CurrentService;
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_POSITION, NULL, &IntValue, NULL);
double ParaValue = TransmissionMode_Bitrate[CurrentService];
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_BITRATE_DL, &ParaValue, NULL, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_BITRATE_UL, &ParaValue, NULL, NULL);
IntValue = TransmissionMode_Coderate_K[CurrentService];
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_CODERATE_K_DL, NULL, &IntValue, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_CODERATE_K_UL, NULL, &IntValue, NULL);
IntValue = TransmissionMode_Coderate_N[CurrentService];
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_CODERATE_N_DL, NULL, &IntValue, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_CODERATE_N_UL, NULL, &IntValue, NULL);
IntValue = 1;
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_RESOURCE_BLOCKS_DL, NULL, &IntValue, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_RESOURCE_BLOCKS_UL, NULL, &IntValue, NULL);
ParaValue = 11.1;
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_OVERHEAD_RATIO_UL, &ParaValue, NULL, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_OVERHEAD_RATIO_DL, &ParaValue, NULL, NULL);
ParaValue = TransmissionMode_SNIR[CurrentService];
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_SNIR_DL, &ParaValue, NULL, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_SNIR_UL, &ParaValue, NULL, NULL);
IntValue = TransmissionMode_MCS[CurrentService];
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_MODULATION_UL, NULL, &IntValue, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_MODULATION_DL, NULL, &IntValue, NULL);
ParaValue = TransmissionMode_Backoff[CurrentService];
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_POWER_BACKOFF_UL, &ParaValue, NULL, NULL);
Error = WinProp_Net_TransmissionMode_Para_Set(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_POWER_BACKOFF_DL, &ParaValue, NULL, NULL);
Error = WinProp_Net_TransmissionMode_Para_Get(
ProjectHandle, CurrentService, NET_PARA_TRANS_MODE_BITRATE_DL, &ParaValue, NULL, NULL);
TransmissionMode_Bitrate[CurrentService] = ParaValue;
}
}
if (Error == 0)
{
int NrServices = 0;
Error = WinProp_Net_Project_Para_Get(ProjectHandle, NET_PARA_SERVICES, NULL, &NrServices, NULL);
if (Error == 0)
{
if (NrServices != SERVICES_LTE)
Error = 1;
}
}
if (Error == 0)
{
double ParaValue = -5.4;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_CELL_ASSIGNMENT_MIN_REQ_SNIR, &ParaValue, NULL, NULL);
}
if (Error == 0)
{
int IntValue = 0;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_CELL_ASSIGNMENT_MIN_REQ_POWER_USED, NULL, &IntValue, NULL);
}
if (Error == 0)
{
int IntValue = 0;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_CELL_ASSIGNMENT_MODE, NULL, &IntValue, NULL);
}
if (Error == 0)
{
int IntValue = 0;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_CELL_ASSIGNMENT_SIGNALS, NULL, &IntValue, NULL);
}
if (Error == 0)
{
double ParaValue = 1.0;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_RESOLUTION, &ParaValue, NULL, NULL);
}
if (Error == 0)
{
int IntValue = 0;
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_AREA_MODE, NULL, &IntValue, NULL);
}
if (Error == 0)
{
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_OUTPUT_WINPROP, NULL, NULL, API_DATA_FOLDER "output/network_planning_parallel/network");
}
for (int Count = 0; Count < MAX_TRX && Error == 0; Count++)
{
Frequency = 2120.0 + ((AntennaCarrier[Count] - 1) * CarrierSeparation);
AntennaPropertiesSet(&Antenna[Count], AntennaX[Count], AntennaY[Count], 2.5, Frequency, AntennaName[Count], Count + 1);
WinProp_Structure_Init_Carrier(&Carrier);
Carrier.CarrierID = AntennaCarrier[Count];
Carrier.SystemID = Signal_for_MIMO;
Carrier.MimoID = Stream_for_MIMO;
CarrierPropertiesSet(&Antenna[Count], &Carrier);
}
if (Error == 0)
{
WavePropagation(
MAX_TRX,
Antenna,
PropResults,
NrPredictionHeights,
PredictionHeightsMulti,
API_DATA_FOLDER "indoor/IndoorVectordatabase.idb");
}
if (Error == 0)
{
for (int Count = 0; Count<MAX_TRX; Count++)
{
if (Error == 0)
{
Error = WinProp_Net_PropagationMap_Add(ProjectHandle, &MapIndex[Count], &Antenna[Count], &PropResults[Count]);
}
}
}
if (Error == 0)
{
char HeightString[500];
sprintf(HeightString, "%s", "");
for (int Height = 0; Height<NrPredictionHeights; Height++)
{
char thisHeightStr[50];
sprintf(thisHeightStr, "%.2f ", PredictionHeightsMulti[Height]);
strcat(HeightString, thisHeightStr);
}
Error = WinProp_Net_Project_Para_Set(ProjectHandle, NET_PARA_HEIGHT_MULTIPLE, NULL, NULL, HeightString);
if (Error == 0)
{
Callback.Percentage = CallbackProgress;
Callback.Message = CallbackMessage;
Callback.Error = CallbackError;
Error = WinProp_Net_Project_Compute(ProjectHandle, &Callback);
}
}
if (Error == 0)
{
Error = WinProp_Net_NetworkMap_Get(ProjectHandle, -1, NET_RESULT_MAX_THROUGHPUT, &MaxThroughput);
}
if (Error == 0)
{
char NameForOutput[200];
sprintf(NameForOutput, API_DATA_FOLDER "output/network_planning_parallel/network/%s Max Throughput.txt", ProjectName);
write_ascii(MaxThroughput, NameForOutput);
}
if (Error == 0)
{
Error = WinProp_Net_NetworkMap_Get(ProjectHandle, -1, NET_RESULT_SNIR, &MaxSNIR);
}
if (Error == 0)
{
char NameForOutput[200];
sprintf(NameForOutput, API_DATA_FOLDER "output/network_planning_parallel/network/%s Max SNIR.txt", ProjectName);
write_ascii(MaxSNIR, NameForOutput);
}
for (int Count = 0; Count<MAX_TRX; Count++)
WinProp_FreeResult(&PropResults[Count]);
Error = WinProp_Net_Project_Close(ProjectHandle);
return 0;
}
int _STD_CALL CallbackMessage(const char * Text)
{
if (Text == nullptr)
return 0;
std::cout << "\n" << Text;
return(0);
}
int _STD_CALL CallbackError(const char * Text, int Error)
{
if (Text == nullptr)
return 0;
std::cout << "\n";
#ifdef __LINUX
std::cout << "\033[31m" << "Error (" << Error << "): ";
#else
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_RED);
std::cout << "Error (" << Error << "): ";
#endif // __LINUX
std::cout << Text;
#ifdef __LINUX
std::cout << "\033[0m";
#else
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN);
#endif // __LINUX
return 0;
}
int _STD_CALL CallbackProgress(int value, const char* text)
{
char Line[200];
sprintf(Line, "\n%d%% %s", value, text);
std::cout << Line;
return(0);
}
void write_ascii(const WinProp_Result* Resultmatrix, const char* Filename) {
FILE* OutputFile = fopen(Filename,"w");
if (OutputFile)
{
for (int z = 0; z < Resultmatrix->NrHeights; z++)
{
double Coordinate_Z = Resultmatrix->Heights[z];
for (int x = 0; x < Resultmatrix->Columns; x++)
{
for (int y = 0; y < Resultmatrix->Lines; y++)
{
double Coordinate_X = Resultmatrix->LowerLeftX + ((double)x + 0.5) * Resultmatrix->Resolution;
double Coordinate_Y = Resultmatrix->LowerLeftY + ((double)y + 0.5) * Resultmatrix->Resolution;
if (Resultmatrix->Matrix[z][x][y] > -1000)
fprintf(OutputFile, "%.2f\t%.2f\t%.2f\t%.2f\n", Coordinate_X, Coordinate_Y, Coordinate_Z, Resultmatrix->Matrix[z][x][y]);
}
}
}
fclose(OutputFile);
}
else
printf("\nCould not open the File: %s for writing.\n",Filename);
}
void AntennaPropertiesSet(
WinProp_Antenna *Antenna,
double CoordinateX,
double CoordinateY,
double Height,
double Frequency,
const char *Name,
int Id)
{
Antenna->Longitude_X = CoordinateX;
Antenna->Latitude_Y = CoordinateY;
Antenna->Height = Height;
Antenna->Power = 20.0;
Antenna->PowerMode = WINPROP_POWER_OUTPUT;
Antenna->Frequency = Frequency;
sprintf(Antenna->Name, "%s", Name);
Antenna->Model = WINPROP_MODEL_COST231;
Antenna->Id = Id;
}
void CarrierPropertiesSet(WinProp_Antenna *Antenna, const WinProp_Carrier *Carrier)
{
Antenna->Carriers.CarrierID = Carrier->CarrierID;
Antenna->Carriers.SystemID = Carrier->SystemID;
Antenna->Carriers.MimoID = Carrier->MimoID;
}
void WavePropagation(
int NumberAntennas,
const WinProp_Antenna *Antenna,
WinProp_Result *Result,
int NrHeights,
const double *Heights,
const char* database)
{
int Error = 0;
WinProp_Area Area;
WinProp_Structure_Init_Area(&Area);
WinProp_Scenario Scenario;
WinProp_Structure_Init_Scenario(&Scenario);
Scenario.Scenario = WINPROP_SCENARIO_INDOOR;
sprintf(Scenario.VectorDatabase, "%s", database);
WinProp_Propagation_Results OutputResults;
WinProp_Structure_Init_Propagation_Results(&OutputResults);
sprintf(OutputResults.ResultPath, "%s", API_DATA_FOLDER "output/network_planning_parallel/propagation");
OutputResults.FieldStrength = 1;
OutputResults.PathLoss = 1;
WinProp_Additional WinPropMore;
WinProp_Structure_Init_Additional(&WinPropMore);
WinPropMore.OutputResults = &OutputResults;
WinProp_Callback Callback;
WinProp_Structure_Init_Callback(&Callback);
Callback.Percentage = CallbackProgress;
Callback.Message = CallbackMessage;
Callback.Error = CallbackError;
if (Error == 0)
{
Area.Heights = (double*)malloc(sizeof(double) * NrHeights);
if (Area.Heights != nullptr)
{
Area.NrHeights = NrHeights;
for (int C = 0; C < NrHeights; C++)
Area.Heights[C] = Heights[C];
}
Area.LowerLeftX = -4.680001;
Area.LowerLeftY = -44.200001;
Area.UpperRightX = 101.399999;
Area.UpperRightY = 42.799999;
Area.Resolution = 1.0;
}
#ifdef _OPENMP
omp_set_num_threads(MAX_THREADS);
#endif
#pragma omp parallel for schedule(dynamic,1) shared(Area, Antenna, Scenario, Callback, Result)
for (int Count = 0; Count < NumberAntennas; Count++)
{
int PredictionHandle = 0;
if (Error == 0)
{
Error = WinProp_Open(&PredictionHandle, &Scenario, &Callback);
}
if (Error == 0)
{
WinProp_Result* DummyResult = nullptr;
Error = WinProp_Predict(PredictionHandle, &Antenna[Count], &Area, NULL, 0, NULL, &WinPropMore, &DummyResult, NULL, NULL, NULL, NULL, NULL, NULL);
if (Error == 0) {
WinProp_CopyResult(&Result[Count], DummyResult);
}
else {
printf("\n\nSimulation returned with Error %d\n\n",Error);
}
}
WinProp_Close(PredictionHandle);
}
for (int Count = 0; Count < NumberAntennas; Count++)
{
char PropOutputFile[500];
sprintf(PropOutputFile, API_DATA_FOLDER "output/network_planning_parallel/propagation/%s Power.txt",Antenna[Count].Name);
write_ascii(&Result[Count], PropOutputFile);
}
if (Area.Heights)
free(Area.Heights);
}