ch_desc_proto.c 13.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22 23 24 25 26 27 28 29 30 31 32 33
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "defs.h"
#define PI 3.1416
#define Am 20
#define MCS_COUNT 24
#define MCL 70 /*minimum coupling loss (MCL) in dB*/
#define theta_3dB (65*PI/180)
enum sector {SEC1, SEC2, SEC3};
scenario_desc_t scenario;

34 35 36
void get_chan_desc(node_desc_t* node_tx, node_desc_t* node_rx, channel_desc_t *ch_desc, scenario_desc_t* scenario)
{
  double dist;
37
  dist = sqrt(pow((node_tx->x - node_rx->x), 2) + pow((node_tx->y - node_rx->y), 2));
38

39
  /* conversion of distance into KM 3gpp (36-942)*/
40
  ch_desc->path_loss_dB = (128.1 + 37.6 * log10(dist/1000));
41 42
}

43 44
int main()
{
45 46
  int enb_count = 16;
  int ue_count = 50;
47
  double sect_angle[3]= {0,2*PI/3,4*PI/3};
48 49 50 51
  double gain_max;
  double theta;
  double min_path_loss = 0;
  int att_enb_index;
52
  node_desc_t *enb_data[enb_count];
53
  node_desc_t *ue_data[ue_count];
54
  channel_desc_t *ul_channel[ue_count][enb_count];
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
  channel_desc_t *dl_channel[ue_count][enb_count];
  int count;
  int mcs;
  int ue_index, enb_index;
  int return_value;
  int nb_rb = 25; //No. of resource blocks
  double sinr[enb_count][2*nb_rb];
  double sinr_eff[ue_count][MCS_COUNT];
  double bler[ue_count][MCS_COUNT];
  double gain_sec[3];
  double thermal_noise;
  double interference;
  double coupling;
  FILE *fp;
  char buffer[100];
  char *sinr_bler;
  double tlu_sinr;
  double tlu_bler;
  int line_num;
  char *file_name[]= {"bler_1.csv", "bler_2.csv", "bler_3.csv", "bler_4.csv", "bler_5.csv", "bler_6.csv", "bler_7.csv", "bler_8.csv",
75 76 77
                      "bler_9.csv", "bler_10.csv", "bler_11.csv", "bler_12.csv", "bler_13.csv", "bler_14.csv", "bler_15.csv", "bler_16.csv",
                      "bler_17.csv", "bler_18.csv", "bler_19.csv", "bler_20.csv", "bler_21.csv", "bler_22.csv"
                     };
78

79
  double beta[MCS_COUNT] = {0, 0, 0, 0, 0.9459960937499999, 1.2912109374999994, 1.0133789062499998, 1.000390625,
80 81
                            1.02392578125, 1.8595703124999998, 2.424389648437498, 2.3946533203124982, 2.5790039062499988,
                            2.4084960937499984, 2.782617187499999, 2.7868652343749996, 3.92099609375, 4.0392578125,
82 83 84
                            4.56109619140625, 5.03338623046875, 5.810888671875, 6.449108886718749
                           };

85
  double enb_position[][2] = {{1100,1100},{1100,2100},{1100,3100},{1100,4100},
86 87 88 89
    {2100,1100},{2100,2100},{2100,3100},{2100,4100},
    {3100,1100},{3100,2100},{3100,3100},{3100,4100},
    {4100,1100},{4100,2100},{4100,3100},{4100,4100}
  };
90 91

  double ue_position[][2] = {{3340,4740},{1500,620},{1780,4220},{1300,3540},{780,3100},
92 93 94 95 96 97 98 99 100 101 102
    {1140,540},{1340,3660},{860,1220},{2700,2140},{3860,3060},
    {3740,1060},{1700,3060},{2180,1620},{4420,1060},{1300,3340},
    {3700,3180},{3780,540},{1700,4380},{4140,4740},{820,4380},
    {3300,1540},{2100,1780},{1780,2260},{1940,2620},{1580,1700},
    {1460,1940},{940,1340},{2100,3540},{1260,4340},{2940,4060},
    {3980,940},{540,2220},{3060,2140},{4620,3940},{4260,2820},
    {3860,3500},{4140,4140},{3900,3500},{1500,2140},{2620,3820},
    {3420,2820},{1580,3940},{660,2100},{2740,1180},{2500,2500},
    {3580,3580},{3740,3140},{3020,3020},{4340,4140},{980,4300}
  };

103 104 105 106 107 108 109 110 111
  randominit(0);

  /////////////////////////////////////////////////////////////////////////////////////////////////
  int tabl_len=0;
  double local_table[MCS_COUNT][9][9];

  for (mcs = 5; mcs <= MCS_COUNT; mcs++) {

    fp = fopen(file_name[mcs - 1],"r");
112

113 114
    if (fp == NULL) {
      printf("ERROR: Unable to open the file\n");
115
    } else {
116 117
      fgets(buffer, 100, fp);
      tabl_len=0;
118

119
      while (!feof(fp)) {
120 121 122 123 124 125 126

        sinr_bler = strtok(buffer, ";");
        local_table[mcs-1][0][tabl_len] = atof(sinr_bler);
        sinr_bler = strtok(NULL,";");
        local_table[mcs-1][1][tabl_len] = atof(sinr_bler);
        tabl_len++;
        fgets(buffer, 100, fp);
127
      }
128

129 130
      fclose(fp);
    }
131

132
    printf("\n table for mcs %d\n",mcs);
133 134

    for (tabl_len=0; tabl_len<9; tabl_len++)
135 136 137 138 139 140 141 142 143
      printf("%lf  %lf \n ",local_table[mcs-1][0][tabl_len],local_table[mcs-1][1][tabl_len]);


  }



  ////////////////////////////////////////////////////////////////////////////////////////////////////

144
  for (enb_index = 0; enb_index < enb_count; enb_index++)
145 146
    enb_data[enb_index] = (node_desc_t *)(malloc(sizeof(node_desc_t)));

147 148 149 150
  for (ue_index = 0; ue_index < ue_count; ue_index++)
    ue_data[ue_index] = (node_desc_t *)(malloc(sizeof(node_desc_t)));

  for (enb_index = 0; enb_index < enb_count; enb_index++)  {
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    enb_data[enb_index]->x = enb_position[enb_index][0];
    enb_data[enb_index]->y = enb_position[enb_index][1];
    enb_data[enb_index]->tx_power_dBm = 40;
    enb_data[enb_index]->ant_gain_dBi = 15;
    enb_data[enb_index]->rx_noise_level = 5; //value in db
    enb_data[enb_index]->n_sectors = 3;
  }

  for (ue_index = 0; ue_index < ue_count; ue_index++)  {
    ue_data[ue_index]->x = ue_position[ue_index][0];
    ue_data[ue_index]->y = ue_position[ue_index][1];
    ue_data[ue_index]->phi_rad = 2 * PI;
    ue_data[ue_index]->tx_power_dBm = 20;
    ue_data[ue_index]->ant_gain_dBi = 0;
    ue_data[ue_index]->rx_noise_level = 9; //value in db
  }
167

168 169
  for (ue_index = 0; ue_index < ue_count; ue_index++) {
    min_path_loss = 10000;
170

171 172 173
    for (enb_index = 0; enb_index < enb_count; enb_index++) {
      ul_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0);
      dl_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0);
174 175
      //printf("ue %d enb %d\n", ue_index, enb_index);

176 177 178 179
      /* Calculating the angle in the range -pi to pi from the slope */
      //(ue_data[ue_index])->alpha_rad[enb_index] = (double)(atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y)));
      ue_data[ue_index]->alpha_rad[enb_index] = atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y));
      //printf("angle is tan %lf\n", ue_data[ue_index]->alpha_rad[enb_index]);
180

181
      if ((ue_data[ue_index]->alpha_rad[enb_index]) < 0) {
182
        ue_data[ue_index]->alpha_rad[enb_index] = 2*PI + ue_data[ue_index]->alpha_rad[enb_index];
183 184
        //printf("angle in radians is %lf\n", ue_data[ue_index]->alpha_rad[enb_index]);
      }
185

186
      for(count = 0; count < enb_data[enb_index]->n_sectors; count++) {
187 188
        theta = sect_angle[count] - ue_data[ue_index]->alpha_rad[enb_index];
        gain_sec[count] = -(Am < (12 * pow((theta/theta_3dB),2)) ? Am : (12 * pow((theta/theta_3dB),2)));
189
      }
190

191
      /* gain = -min(Am , 12 * (theta/theta_3dB)^2) */
192 193
      gain_max = (gain_sec[SEC1] > gain_sec[SEC2]) ? ((gain_sec[SEC1] > gain_sec[SEC3]) ? gain_sec[SEC1]:gain_sec[SEC3]) :
                   ((gain_sec[SEC2] > gain_sec[SEC3]) ? gain_sec[SEC2]:gain_sec[SEC3]);
194 195 196

      get_chan_desc(enb_data[enb_index], ue_data[ue_index], ul_channel[ue_index][enb_index], &scenario);
      get_chan_desc(enb_data[enb_index], ue_data[ue_index], dl_channel[ue_index][enb_index], &scenario);
197 198 199

      //printf("Path loss for link between ue %d and enb %d is %lf and gain is %lf \n", ue_index, enb_index, dl_channel[ue_index][enb_index]->path_loss_dB, gain_max);

200 201 202 203
      if (dl_channel[ue_index][enb_index]->path_loss_dB < min_path_loss) {
        min_path_loss = dl_channel[ue_index][enb_index]->path_loss_dB;
        att_enb_index = enb_index;
      }
204

205 206
      //return_value = random_channel(ul_channel[ue_index][enb_index]);
      return_value = random_channel(dl_channel[ue_index][enb_index]);
207

208 209
      /* Thermal noise is calculated using 10log10(K*T*B) K = Boltzmanns constant T = room temperature B = bandwidth */
      /* Taken as constant for the time being since the BW is not changing */
210 211
      thermal_noise = -105; //value in dBm

212 213 214 215
      if (0 == return_value) {
        //freq_channel(ul_channel[ue_index][enb_index], nb_rb);
        freq_channel(dl_channel[ue_index][enb_index], nb_rb);
        coupling = MCL > (dl_channel[ue_index][enb_index]->path_loss_dB-(enb_data[enb_index]->ant_gain_dBi + gain_max)) ?
216 217 218
                   MCL : (dl_channel[ue_index][enb_index]->path_loss_dB-(enb_data[enb_index]->ant_gain_dBi + gain_max));

        //printf ("coupling factor is %lf\n", coupling);
219
        for (count = 0; count < (2 * nb_rb); count++) {
220 221 222 223 224 225
          sinr[enb_index][count] = enb_data[enb_index]->tx_power_dBm
                                   - coupling
                                   - (thermal_noise + ue_data[ue_index]->rx_noise_level)
                                   + 10 * log10 (pow(dl_channel[ue_index][enb_index]->chF[0][count].r, 2)
                                                 + pow(dl_channel[ue_index][enb_index]->chF[0][count].i, 2));

226 227
          //printf("Dl_link SNR for res. block %d is %lf\n", count, sinr[enb_index][count]);
        }
228
      }
229
    }
230

231 232
    for (count = 0; count < 2 * nb_rb; count++) {
      interference = 0;
233

234 235 236 237 238
      for (enb_index = 0; enb_index < enb_count; enb_index++) {
        if (att_enb_index != enb_index) {
          interference += pow(10, 0.1 * sinr[enb_index][count]);
        }
      }
239

240
      sinr[att_enb_index][count] -= 10*log10(1 + interference);
241

242
      //printf("***Dl_link SINR for res. block %d is %lf\n", count, sinr[att_enb_index][count]);
243

244 245
      for (mcs = 5; mcs <= MCS_COUNT; mcs++) {
        sinr_eff[ue_index][mcs-1] += exp(-(pow(10, (sinr[att_enb_index][count])/10))/beta[mcs-1]);
246
        //printf("Effective snr   %lf\n",sinr_eff[ue_index][mcs-1]);
247
        //sinr_eff[ue_index][mcs] += exp(-(sinr[att_enb_index][count])/beta[mcs]);
248
      }
249
    }
250

251 252 253 254 255 256 257 258 259 260
    for (mcs = 5; mcs <= MCS_COUNT; mcs++) {
      //printf("mcs value  %d \n",mcs);
      //printf("beta value  %lf \n",-beta[mcs-1]);
      //printf("snr_eff value  %lf \n",log(sinr_eff[ue_index][mcs-1]));

      sinr_eff[ue_index][mcs-1] =  -beta[mcs-1] *log((sinr_eff[ue_index][mcs-1])/(2*nb_rb));//
      //printf("snr_eff value  %lf \n",sinr_eff[ue_index][mcs-1]);
      sinr_eff[ue_index][mcs-1] = 10 * log10(sinr_eff[ue_index][mcs-1]);
      sinr_eff[ue_index][mcs-1] *= 10;
      sinr_eff[ue_index][mcs-1] = floor(sinr_eff[ue_index][mcs-1]);
261

262 263 264
      if ((int)sinr_eff[ue_index][mcs-1]%2) {
        sinr_eff[ue_index][mcs-1] += 1;
      }
265

266 267 268 269 270
      sinr_eff[ue_index][mcs-1] /= 10;

      //printf("Effective snr   %lf  \n",sinr_eff[ue_index][mcs-1]);

      bler[ue_index][mcs-1] = 0;
271

272
      /*line_num = 0;
273 274
      fp = fopen(file_name[mcs - 1],"r");
      if (fp == NULL) {
275
        printf("ERROR: Unable to open the file\n");
276 277
      }
      else {
278 279
        fgets(buffer, 100, fp);
        while (!feof(fp)) {
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
      line_num++;
      sinr_bler = strtok(buffer, ";");
      tlu_sinr = atof(sinr_bler);
      sinr_bler = strtok(NULL,";");
      tlu_bler = atof(sinr_bler);
      if (1 == line_num) {
      if (sinr_eff[ue_index][mcs-1] < tlu_sinr) {
      bler[ue_index][mcs-1] = 1;
      break;
      }
      }
      if (sinr_eff[ue_index][mcs-1] == tlu_sinr) {
      bler[ue_index][mcs-1] = tlu_bler;
      }
      fgets(buffer, 100, fp);
295 296
        }
        fclose(fp);*/
297
      for (tabl_len=0; tabl_len<9; tabl_len++) {
298

299 300 301 302 303
        if(tabl_len==0)
          if (sinr_eff[ue_index][mcs-1] < local_table[mcs-1][0][tabl_len]) {
            bler[ue_index][mcs-1] = 1;
            break;
          }
304 305


306 307 308
        if (sinr_eff[ue_index][mcs-1] == local_table[mcs-1][0][tabl_len]) {
          bler[ue_index][mcs-1] = local_table[mcs-1][1][tabl_len];
        }
309 310 311 312

      }

      //printf("\n###Dl_link UE %d attached to eNB %d \n MCS %d effective SNR %lf BLER %lf", ue_index, att_enb_index, mcs,sinr_eff[ue_index][mcs-1],bler[ue_index][mcs-1]);
313 314
    }

315 316 317
    //printf("\n\n");

    printf("\n     Ue_ix enb_ix  mcs5    mcs6    mcs7    mcs8    mcs9   mcs10   mcs11   mcs12   mcs13\
318
   mcs14   mcs15   mcs16   mcs17   mcs18   mcs19   mcs20   mcs21   mcs22\n");
319 320 321

    printf("SINR %4d   %4d  %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f\
   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f\n",
322 323 324 325
           ue_index, att_enb_index, sinr_eff[ue_index][4], sinr_eff[ue_index][5], sinr_eff[ue_index][6], sinr_eff[ue_index][7],
           sinr_eff[ue_index][8], sinr_eff[ue_index][9], sinr_eff[ue_index][10], sinr_eff[ue_index][11], sinr_eff[ue_index][12],
           sinr_eff[ue_index][13], sinr_eff[ue_index][14], sinr_eff[ue_index][15], sinr_eff[ue_index][16], sinr_eff[ue_index][17],
           sinr_eff[ue_index][18], sinr_eff[ue_index][19], sinr_eff[ue_index][20], sinr_eff[ue_index][21], sinr_eff[ue_index][22]);
326 327 328

    printf("BLER %4d   %4d  %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f\
   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f   %+4.2f\n",
329 330 331 332
           ue_index, att_enb_index, bler[ue_index][4], bler[ue_index][5], bler[ue_index][6], bler[ue_index][7],
           bler[ue_index][8], bler[ue_index][9], bler[ue_index][10], bler[ue_index][11], bler[ue_index][12],
           bler[ue_index][13], bler[ue_index][14], bler[ue_index][15], bler[ue_index][16], bler[ue_index][17],
           bler[ue_index][18], bler[ue_index][19], bler[ue_index][20], bler[ue_index][21], bler[ue_index][22]);
333 334 335
  }
}