lte_ue_measurements.c 35.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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
 */
ghaddab's avatar
ghaddab committed
21

22 23 24 25 26 27
// this function fills the PHY_vars->PHY_measurement structure

#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
28
#include "log.h"
29
#include "PHY/sse_intrin.h"
30 31 32 33 34

//#define k1 1000
#define k1 ((long long int) 1000)
#define k2 ((long long int) (1024-k1))

35 36
//#define DEBUG_MEAS_RRC
//#define DEBUG_MEAS_UE
37 38

#ifdef USER_MODE
39
void print_shorts(char *s,short *x)
40
{
41 42 43


  printf("%s  : %d,%d,%d,%d,%d,%d,%d,%d\n",s,
44
         x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7]
45
        );
46 47

}
48
void print_ints(char *s,int *x)
49
{
50 51 52


  printf("%s  : %d,%d,%d,%d\n",s,
53
         x[0],x[1],x[2],x[3]
54
        );
55 56 57 58 59

}
#endif


60 61
int16_t get_PL(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
62

63
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
64
  /*
65
  int RSoffset;
66 67


68
  if (ue->frame_parms.mode1_flag == 1)
69 70 71
    RSoffset = 6;
  else
    RSoffset = 3;
72
  */
73

74
  LOG_D(PHY,"get_PL : Frame %d : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n", ue->proc.proc_rxtx[0].frame_rx,
75 76 77
        (1.0*dB_fixed_times10(ue->measurements.rsrp[eNB_index])-(10.0*ue->rx_total_gain_dB))/10.0,
        10*log10((double)ue->measurements.rsrp[eNB_index]),
        ue->frame_parms.pdsch_config_common.referenceSignalPower);
78

79 80 81 82
  return((int16_t)(((10*ue->rx_total_gain_dB) -
                    dB_fixed_times10(ue->measurements.rsrp[eNB_index])+
                    //        dB_fixed_times10(RSoffset*12*ue_g[Mod_id][CC_id]->frame_parms.N_RB_DL) +
                    (ue->frame_parms.pdsch_config_common.referenceSignalPower*10))/10));
83 84
}

85

86 87
uint8_t get_n_adj_cells (uint8_t Mod_id,uint8_t CC_id)
{
88

89
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
90

91 92
  if (ue)
    return ue->measurements.n_adj_cells;
93
  else
94 95 96
    return 0;
}

97 98
uint32_t get_rx_total_gain_dB (uint8_t Mod_id,uint8_t CC_id)
{
99

100
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
101

102 103
  if (ue)
    return ue->rx_total_gain_dB;
104

105
  return 0xFFFFFFFF;
106
}
107 108
uint32_t get_RSSI (uint8_t Mod_id,uint8_t CC_id)
{
109

110
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
111

112 113
  if (ue)
    return ue->measurements.rssi;
114

115
  return 0xFFFFFFFF;
116
}
117 118 119
uint32_t get_RSRP(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{

120
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
121

122 123
  if (ue)
    return ue->measurements.rsrp[eNB_index];
124

125
  return 0xFFFFFFFF;
126 127
}

128 129
uint32_t get_RSRQ(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
130

131
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
132

133 134
  if (ue)
    return ue->measurements.rsrq[eNB_index];
135

136
  return 0xFFFFFFFF;
137 138
}

139 140 141
int8_t set_RSRP_filtered(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrp)
{

142
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
143

144 145
  if (ue) {
    ue->measurements.rsrp_filtered[eNB_index]=rsrp;
146 147
    return 0;
  }
148

149 150 151 152
  LOG_W(PHY,"[UE%d] could not set the rsrp\n",Mod_id);
  return -1;
}

153 154
int8_t set_RSRQ_filtered(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrq)
{
155

156
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
157

158 159
  if (ue) {
    ue->measurements.rsrq_filtered[eNB_index]=rsrq;
160
    return 0;
161
  }
162

163 164
  LOG_W(PHY,"[UE%d] could not set the rsrq\n",Mod_id);
  return -1;
165

166
}
167

168
void ue_rrc_measurements(PHY_VARS_UE *ue,
169 170
    uint8_t slot,
    uint8_t abstraction_flag)
171
{
172

173 174
  uint8_t subframe = slot>>1;
  int aarx,rb,n;
175
  int16_t *rxF,*rxF_pss,*rxF_sss;
176

177
  uint16_t Nid_cell = ue->frame_parms.Nid_cell;
gauthier's avatar
gauthier committed
178 179
  uint8_t eNB_offset,nu,l,nushift,k;
  uint16_t off;
180

181 182 183 184 185 186
  uint8_t isPss; // indicate if this is a slot for extracting PSS
  uint8_t isSss; // indicate if this is a slot for extracting SSS
  int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS
  int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS
  int32_t (*xss_ext)[72]; // point to either pss_ext or sss_ext for common calculation
  int16_t *re,*im; // real and imag part of each 32-bit xss_ext[][] value
187

188
  for (eNB_offset = 0; eNB_offset<1+ue->measurements.n_adj_cells; eNB_offset++) {
189

190
    if (eNB_offset==0) {
191
      ue->measurements.rssi = 0;
192
      //ue->measurements.n0_power_tot = 0;
193

knopp's avatar
 
knopp committed
194
      if (abstraction_flag == 0) {
195
        if ((ue->frame_parms.frame_type == FDD) &&
196
            ((subframe == 0) || (subframe == 5))) {  // FDD PSS/SSS, compute noise in DTX REs
197

198 199
          if (ue->frame_parms.Ncp==NORMAL) {
            for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
200

201 202
	      rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
	      rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
203 204

              //-ve spectrum from SSS
205 206
	      //	      printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]);

207 208 209 210 211 212 213
	      //              ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
	      //	      printf("sssn36 %d\n",ue->measurements.n0_power[aarx]);
              ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
	      //	      printf("sssm32 %d\n",ue->measurements.n0_power[aarx]);
214
              //+ve spectrum from SSS
215 216 217 218 219
	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
	      //	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
	      //	      printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
220
              //+ve spectrum from PSS
221 222 223 224 225
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
	      //	      printf("pss32 %d\n",ue->measurements.n0_power[aarx]);              //-ve spectrum from PSS
226
              rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
227 228 229 230 231 232 233 234
	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
	      //	      printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
	      //	      printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
              ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
235
              ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
236 237
            }

238 239
	    ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
	    ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
240 241 242
          } else {
            LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n");
          }
243
        }
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
        else if ((ue->frame_parms.frame_type == TDD) &&
            ((slot == 2) || (slot == 12) || (slot == 1) || (slot == 11))) {  // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation

#if 1 // fixing REs extraction in noise power calculation

          // check if this slot has a PSS or SSS sequence
          if ((slot == 2) || (slot == 12)) {
            isPss = 1;
          } else {
            isPss = 0;
          }
          if ((slot == 1) || (slot == 11)) {
            isSss = 1;
          } else {
            isSss = 0;
          }

          if (isPss) {
            pss_only_extract(ue, pss_ext);
            xss_ext = pss_ext;
          }
265

266 267 268 269 270 271 272 273
          if (isSss) {
            sss_only_extract(ue, sss_ext);
            xss_ext = sss_ext;
          }

          // calculate noise power
          int num_tot=0; // number of REs totally used in calculating noise power
          for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
274

275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
            int num_per_rx=0; // number of REs used in caluclaing noise power for this RX antenna
            ue->measurements.n0_power[aarx] = 0;
            for (n=2; n<70; n++) { // skip the 2 REs next to PDSCH, i.e. n={0,1,70,71}
              if (n==5) {n=67;}

              re = (int16_t*)(&(xss_ext[aarx][n]));
              im = re+1;
              ue->measurements.n0_power[aarx] += (*re)*(*re) + (*im)*(*im);
              num_per_rx++;
              num_tot++;
            }

            ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(num_per_rx));
            ue->measurements.n0_power_tot /*+=*/ =  ue->measurements.n0_power[aarx];
          }

          ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(num_tot));
          ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);

#else
295 296
          if (ue->frame_parms.Ncp==NORMAL) {
            for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
297

298
	      rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
299 300
	      // note this is a dummy pointer, the pss is not really there!
	      // in FDD the pss is in the symbol after the sss, but not in TDD
301

302
	      rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
303

knopp's avatar
 
knopp committed
304
	      //-ve spectrum from SSS
305 306 307 308 309
	      //              ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
              ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
knopp's avatar
 
knopp committed
310
	      //+ve spectrum from SSS
311 312 313 314 315
	      //	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+72]*rxF_sss[2+72])+((int32_t)rxF_sss[2+71]*rxF_sss[2+71]));
	      ue->measurements.n0_power[aarx] = (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
	      //	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
316

317
	      ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(6));
318 319
	      ue->measurements.n0_power_tot +=  ue->measurements.n0_power[aarx];
	    }
320 321
	    ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(6*aarx));
	    ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
322 323


324 325 326
          }
#endif
        }
327 328
      }
    }
329
    // recompute nushift with eNB_offset corresponding to adjacent eNB on which to perform channel estimation
330
    //    printf("[PHY][UE %d] Frame %d slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, Nid2 %d, nushift %d, eNB_offset %d)\n",ue->Mod_id,ue->frame,slot,Nid_cell,Nid2,nushift,eNB_offset);
331
    if (eNB_offset > 0)
332
      Nid_cell = ue->measurements.adj_cell_id[eNB_offset-1];
333 334 335 336 337 338


    nushift =  Nid_cell%6;



339
    ue->measurements.rsrp[eNB_offset] = 0;
340 341 342


    if (abstraction_flag == 0) {
343

344 345
      // compute RSRP using symbols 0 and 4-frame_parms->Ncp

346
      for (l=0,nu=0; l<=(4-ue->frame_parms.Ncp); l+=(4-ue->frame_parms.Ncp),nu=3) {
347
        k = (nu + nushift)%6;
348
#ifdef DEBUG_MEAS_RRC
349
        LOG_I(PHY,"[UE %d] Frame %d subframe %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",ue->Mod_id,ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,Nid_cell,nushift,
350
              eNB_offset,k,l);
351 352
#endif

353
        for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
354
          rxF = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(l*ue->frame_parms.ofdm_symbol_size)];
355
          off  = (ue->frame_parms.first_carrier_offset+k)<<1;
356

357 358
          if (l==(4-ue->frame_parms.Ncp)) {
            for (rb=0; rb<ue->frame_parms.N_RB_DL; rb++) {
359 360 361

              //    printf("rb %d, off %d, off2 %d\n",rb,off,off2);

362
              ue->measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]));
363
              //        printf("rb %d, off %d : %d\n",rb,off,((((int32_t)rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])));
364
	      //	      if ((ue->frame_rx&0x3ff) == 0)
365
	      //                printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
366

367

368 369
              off+=12;

370
              if (off>=(ue->frame_parms.ofdm_symbol_size<<1))
371 372
                off = (1+k)<<1;

373
              ue->measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]));
374 375
              //    printf("rb %d, off %d : %d\n",rb,off,(((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])));
              /*
376
                if ((ue->frame_rx&0x3ff) == 0)
377 378 379 380
                printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
              */
              off+=12;

381
              if (off>=(ue->frame_parms.ofdm_symbol_size<<1))
382 383 384 385 386 387 388
                off = (1+k)<<1;

            }

            /*
            if ((eNB_offset==0)&&(l==0)) {
            for (i=0;i<6;i++,off2+=4)
389 390
            ue->measurements.rssi += ((rxF[off2]*rxF[off2])+(rxF[off2+1]*rxF[off2+1]));
            if (off2==(ue->frame_parms.ofdm_symbol_size<<2))
391 392
            off2=4;
            for (i=0;i<6;i++,off2+=4)
393
            ue->measurements.rssi += ((rxF[off2]*rxF[off2])+(rxF[off2+1]*rxF[off2+1]));
394 395
            }
            */
396
            //    printf("slot %d, rb %d => rsrp %d, rssi %d\n",slot,rb,ue->measurements.rsrp[eNB_offset],ue->measurements.rssi);
397 398
          }
        }
399
      }
400

401
      // 2 RE per PRB
402 403 404
      //      ue->measurements.rsrp[eNB_offset]/=(24*ue->frame_parms.N_RB_DL);
      ue->measurements.rsrp[eNB_offset]/=(2*ue->frame_parms.N_RB_DL*ue->frame_parms.ofdm_symbol_size);
      //      LOG_I(PHY,"eNB: %d, RSRP: %d \n",eNB_offset,ue->measurements.rsrp[eNB_offset]);
405
      if (eNB_offset == 0) {
406 407 408 409
        //  ue->measurements.rssi/=(24*ue->frame_parms.N_RB_DL);
        //  ue->measurements.rssi*=rx_power_correction;
        //  ue->measurements.rssi=ue->measurements.rsrp[0]*24/2;
        ue->measurements.rssi=ue->measurements.rsrp[0]*(12*ue->frame_parms.N_RB_DL);
410
      }
411

412 413
      if (ue->measurements.rssi>0)
        ue->measurements.rsrq[eNB_offset] = 100*ue->measurements.rsrp[eNB_offset]*ue->frame_parms.N_RB_DL/ue->measurements.rssi;
414
      else
415
        ue->measurements.rsrq[eNB_offset] = -12000;
416

417
      //((200*ue->measurements.rsrq[eNB_offset]) + ((1024-200)*100*ue->measurements.rsrp[eNB_offset]*ue->frame_parms.N_RB_DL/ue->measurements.rssi))>>10;
418
    } else { // Do abstraction of RSRP and RSRQ
419
      ue->measurements.rssi = ue->measurements.rx_power_avg[0];
420
      // dummay value for the moment
421 422
      ue->measurements.rsrp[eNB_offset] = -93 ;
      ue->measurements.rsrq[eNB_offset] = 3;
423 424

    }
425

426
#ifdef DEBUG_MEAS_RRC
427

428
    //    if (slot == 0) {
429

430
      if (eNB_offset == 0)
431 432
        LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",ue->Mod_id,
              ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
433 434 435
              10*log10(ue->measurements.rssi),
              ue->rx_total_gain_dB,
              ue->measurements.n0_power_tot_dBm);
436

437
      LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d), rsrq: %3.1f dB\n",
438
            ue->Mod_id,
439
            ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,eNB_offset,
440 441 442 443 444 445 446 447 448
            (eNB_offset>0) ? ue->measurements.adj_cell_id[eNB_offset-1] : ue->frame_parms.Nid_cell,
            10*log10(ue->measurements.rsrp[eNB_offset])-ue->rx_total_gain_dB,
            ue->measurements.rsrp[eNB_offset],
            (10*log10(ue->measurements.rsrq[eNB_offset])));
      //LOG_D(PHY,"RSRP_total_dB: %3.2f \n",(dB_fixed_times10(ue->measurements.rsrp[eNB_offset])/10.0)-ue->rx_total_gain_dB-dB_fixed(ue->frame_parms.N_RB_DL*12));

      //LOG_D(PHY,"RSRP_dB: %3.2f \n",(dB_fixed_times10(ue->measurements.rsrp[eNB_offset])/10.0));
      //LOG_D(PHY,"gain_loss_dB: %d \n",ue->rx_total_gain_dB);
      //LOG_D(PHY,"gain_fixed_dB: %d \n",dB_fixed(ue->frame_parms.N_RB_DL*12));
449

450
      //    }
451

452 453 454
#endif
  }

455 456
}

457
void lte_ue_measurements(PHY_VARS_UE *ue,
458 459
                         unsigned int subframe_offset,
                         unsigned char N0_symbol,
460 461
                         unsigned char abstraction_flag,
						 uint8_t subframe)
462 463 464
{


465
  int aarx,aatx,eNB_id=0; //,gain_offset=0;
466 467 468
  //int rx_power[NUMBER_OF_CONNECTED_eNB_MAX];
  int i;
  unsigned int limit,subband;
469
#if defined(__x86_64__) || defined(__i386__)
470
  __m128i *dl_ch0_128,*dl_ch1_128;
471 472
#elif defined(__arm__)
  int16x8_t *dl_ch0_128, *dl_ch1_128;
473
#endif
474
  int *dl_ch0,*dl_ch1;
475
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
476 477
  int nb_subbands,subband_size,last_subband_size;
  int N_RB_DL = frame_parms->N_RB_DL;
478
  ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
479

480 481
    if (ue->transmission_mode[eNB_id]!=4)
     ue->measurements.rank[eNB_id] = 0;
482
    else
483 484 485
    ue->measurements.rank[eNB_id] = 1;
  //  printf ("tx mode %d\n", ue->transmission_mode[eNB_id]);
  //  printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]);
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512

  switch (N_RB_DL) {
  case 6:
    nb_subbands = 6;
    subband_size = 12;
    last_subband_size = 0;
    break;

  default:
  case 25:
    nb_subbands = 7;
    subband_size = 4*12;
    last_subband_size = 12;
    break;

  case 50:
    nb_subbands = 9;
    subband_size = 6*12;
    last_subband_size = 2*12;
    break;

  case 100:
    nb_subbands = 13;
    subband_size = 8*12;
    last_subband_size = 4*12;
    break;
  }
513

514
  // signal measurements
515
  for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
516
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
Xiwen JIANG's avatar
Xiwen JIANG committed
517
      for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
518
        ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] =
519
          (signal_energy_nodc(&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0],
520
                              (N_RB_DL*12)));
521
        //- ue->measurements.n0_power[aarx];
522

523 524
        if (ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]<0)
          ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = 0; //ue->measurements.n0_power[aarx];
525

526
        ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]);
527 528

        if (aatx==0)
529
          ue->measurements.rx_power[eNB_id][aarx] = ue->measurements.rx_spatial_power[eNB_id][aatx][aarx];
530
        else
531
          ue->measurements.rx_power[eNB_id][aarx] += ue->measurements.rx_spatial_power[eNB_id][aatx][aarx];
532 533
      } //aatx

534
      ue->measurements.rx_power_dB[eNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[eNB_id][aarx]);
535 536

      if (aarx==0)
537
        ue->measurements.rx_power_tot[eNB_id] = ue->measurements.rx_power[eNB_id][aarx];
538
      else
539
        ue->measurements.rx_power_tot[eNB_id] += ue->measurements.rx_power[eNB_id][aarx];
540 541
    } //aarx

542
    ue->measurements.rx_power_tot_dB[eNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[eNB_id]);
543 544 545 546

  } //eNB_id

  // filter to remove jitter
547 548 549 550 551 552 553 554 555
  if (ue->init_averaging == 0) {
    for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++)
      ue->measurements.rx_power_avg[eNB_id] = (int)
          (((k1*((long long int)(ue->measurements.rx_power_avg[eNB_id]))) +
            (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10);

    ue->measurements.n0_power_avg = (int)
        (((k1*((long long int) (ue->measurements.n0_power_avg))) +
          (k2*((long long int) (ue->measurements.n0_power_tot))))>>10);
556
  } else {
557 558
    for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++)
      ue->measurements.rx_power_avg[eNB_id] = ue->measurements.rx_power_tot[eNB_id];
559

560 561
    ue->measurements.n0_power_avg = ue->measurements.n0_power_tot;
    ue->init_averaging = 0;
562 563
  }

564 565 566 567 568
  for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) {
    ue->measurements.rx_power_avg_dB[eNB_id] = dB_fixed( ue->measurements.rx_power_avg[eNB_id]);
    ue->measurements.wideband_cqi_tot[eNB_id] = dB_fixed2(ue->measurements.rx_power_tot[eNB_id],ue->measurements.n0_power_tot);
    ue->measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(ue->measurements.rx_power_avg[eNB_id],ue->measurements.n0_power_avg);
    ue->measurements.rx_rssi_dBm[eNB_id] = ue->measurements.rx_power_avg_dB[eNB_id] - ue->rx_total_gain_dB;
569 570 571 572 573 574 575 576
#ifdef DEBUG_MEAS_UE
      LOG_D(PHY,"[eNB %d] RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
            eNB_id,
            ue->measurements.rx_rssi_dBm[eNB_id],
            ue->measurements.rx_power_avg_dB[eNB_id],
            ue->measurements.wideband_cqi_avg[eNB_id],
            ue->measurements.rx_power_avg[eNB_id],
            ue->measurements.n0_power_avg);
knopp's avatar
 
knopp committed
577
#endif
578 579
  }

580
  ue->measurements.n0_power_avg_dB = dB_fixed( ue->measurements.n0_power_avg);
581

582
  for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) {
583 584 585 586
    if (frame_parms->mode1_flag==0) {
      // cqi/pmi information

      for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
587 588
        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
        dl_ch1    = &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
589 590 591 592 593

        for (subband=0; subband<nb_subbands; subband++) {

          // cqi
          if (aarx==0)
594
            ue->measurements.subband_cqi_tot[eNB_id][subband]=0;
595 596 597 598 599

          if ((subband<(nb_subbands-1))||(N_RB_DL==6)) {
            /*for (i=0;i<48;i++)
            msg("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]);
            */
600
            ue->measurements.subband_cqi[eNB_id][aarx][subband] =
601 602
              (signal_energy_nodc(dl_ch0,subband_size) + signal_energy_nodc(dl_ch1,subband_size));

603 604
            if ( ue->measurements.subband_cqi[eNB_id][aarx][subband] < 0)
              ue->measurements.subband_cqi[eNB_id][aarx][subband]=0;
605 606 607

            /*
            else
608
            ue->measurements.subband_cqi[eNB_id][aarx][subband]-=ue->measurements.n0_power[aarx];
609 610
            */

611 612 613
            ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband];
            ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband],
                ue->measurements.n0_power[aarx]);
614 615 616
          } else { // this is for the last subband which is smaller in size
            //      for (i=0;i<12;i++)
            //        printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]);
617 618 619 620 621
            ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,last_subband_size) +
                signal_energy_nodc(dl_ch1,last_subband_size)); // - ue->measurements.n0_power[aarx];
            ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband];
            ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband],
                ue->measurements.n0_power[aarx]);
622 623 624 625
          }

          dl_ch1+=subband_size;
          dl_ch0+=subband_size;
626
          //    msg("subband_cqi[%d][%d][%d] => %d (%d dB)\n",eNB_id,aarx,subband,ue->measurements.subband_cqi[eNB_id][aarx][subband],ue->measurements.subband_cqi_dB[eNB_id][aarx][subband]);
627 628 629 630 631
        }

      }

      for (subband=0; subband<nb_subbands; subband++) {
632 633
        ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot);
        //    msg("subband_cqi_tot[%d][%d] => %d dB (n0 %d)\n",eNB_id,subband,ue->measurements.subband_cqi_tot_dB[eNB_id][subband],ue->measurements.n0_power_tot);
634 635 636
      }

      for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
637
	//printf("aarx=%d", aarx);
638
        // skip the first 4 RE due to interpolation filter length of 5 (not possible to skip 5 due to 128i alignment, must be multiple of 128bit)
639 640

#if defined(__x86_64__) || defined(__i386__)
641
       __m128i pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1 /* ,mmtmpPMI2,mmtmpPMI3 */ ;
642

643 644
        dl_ch0_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
        dl_ch1_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
645 646
#elif defined(__arm__)
        int32x4_t pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1,mmtmpPMI0b,mmtmpPMI1b;
647

648 649
        dl_ch0_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
        dl_ch1_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
650 651

#endif
652 653 654 655
        for (subband=0; subband<nb_subbands; subband++) {


          // pmi
656
#if defined(__x86_64__) || defined(__i386__)
657

Elena Lukashova's avatar
Elena Lukashova committed
658 659
	  pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re);
          pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im);
660
#elif defined(__arm__)
Elena Lukashova's avatar
Elena Lukashova committed
661

662 663 664
          pmi128_re = vdupq_n_s32(0);
	  pmi128_im = vdupq_n_s32(0);
#endif
665 666 667 668 669 670 671 672
          // limit is the number of groups of 4 REs in a subband (12 = 4 RBs, 3 = 1 RB)
          // for 5 MHz channelization, there are 7 subbands, 6 of size 4 RBs and 1 of size 1 RB
          if ((N_RB_DL==6) || (subband<(nb_subbands-1)))
            limit = subband_size>>2;
          else
            limit = last_subband_size>>2;

          for (i=0; i<limit; i++) {
673 674

#if defined(__x86_64__) || defined(__i386__)
Elena Lukashova's avatar
Elena Lukashova committed
675 676
	      mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
              mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1);
677 678 679

            // For each RE in subband perform ch0 * conj(ch1)
            // multiply by conjugated channel
Elena Lukashova's avatar
Elena Lukashova committed
680 681 682
		//  print_ints("ch0",&dl_ch0_128[0]);
		//  print_ints("ch1",&dl_ch1_128[0]);

683
	    mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
Elena Lukashova's avatar
Elena Lukashova committed
684 685 686
	         //  print_ints("re",&mmtmpPMI0);
            mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1));
              //  print_ints("_mm_shufflelo_epi16",&mmtmpPMI1);
687
            mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1));
Elena Lukashova's avatar
Elena Lukashova committed
688
	        //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
689
            mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate[0]);
Elena Lukashova's avatar
Elena Lukashova committed
690
	       //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
691
            mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[0]);
Elena Lukashova's avatar
Elena Lukashova committed
692
	       //   print_ints("mm_madd_epi16",&mmtmpPMI1);
693 694
            // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit)
            pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0);
695
	     //   print_ints(" pmi128_re 0",&pmi128_re);
696
            pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1);
697
	       //   print_ints(" pmi128_im 0 ",&pmi128_im);
698

699
	  /*  mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
700
            mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1);
701

702 703 704 705 706 707 708 709 710 711 712 713 714 715
	    mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]);
	         //  print_ints("re",&mmtmpPMI0);
            mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1));
              //  print_ints("_mm_shufflelo_epi16",&mmtmpPMI1);
            mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1));
	        //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
            mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate);
	       //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
            mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[1]);
	       //   print_ints("mm_madd_epi16",&mmtmpPMI1);
            // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit)
            pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0);
	        //  print_ints(" pmi128_re 1",&pmi128_re);
            pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1);
716
	    //print_ints(" pmi128_im 1 ",&pmi128_im);*/
717

718
#elif defined(__arm__)
Elena Lukashova's avatar
Elena Lukashova committed
719

720 721 722 723 724 725 726 727 728
            mmtmpPMI0 = vmull_s16(((int16x4_t*)dl_ch0_128)[0], ((int16x4_t*)dl_ch1_128)[0]);
            mmtmpPMI1 = vmull_s16(((int16x4_t*)dl_ch0_128)[1], ((int16x4_t*)dl_ch1_128)[1]);
            pmi128_re = vqaddq_s32(pmi128_re,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0),vget_high_s32(mmtmpPMI0)),vpadd_s32(vget_low_s32(mmtmpPMI1),vget_high_s32(mmtmpPMI1))));

            mmtmpPMI0b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[0]);
            mmtmpPMI1b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[1]);
            pmi128_im = vqaddq_s32(pmi128_im,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0b),vget_high_s32(mmtmpPMI0b)),vpadd_s32(vget_low_s32(mmtmpPMI1b),vget_high_s32(mmtmpPMI1b))));

#endif
729 730 731 732
            dl_ch0_128++;
            dl_ch1_128++;
          }

733 734 735 736
          ue->measurements.subband_pmi_re[eNB_id][subband][aarx] = (((int *)&pmi128_re)[0] + ((int *)&pmi128_re)[1] + ((int *)&pmi128_re)[2] + ((int *)&pmi128_re)[3])>>2;
          ue->measurements.subband_pmi_im[eNB_id][subband][aarx] = (((int *)&pmi128_im)[0] + ((int *)&pmi128_im)[1] + ((int *)&pmi128_im)[2] + ((int *)&pmi128_im)[3])>>2;
          ue->measurements.wideband_pmi_re[eNB_id][aarx] += ue->measurements.subband_pmi_re[eNB_id][subband][aarx];
          ue->measurements.wideband_pmi_im[eNB_id][aarx] += ue->measurements.subband_pmi_im[eNB_id][subband][aarx];
737 738 739
        } // subband loop
      } // rx antenna loop
    }  // if frame_parms->mode1_flag == 0
740
    else {
741 742
      // cqi information only for mode 1
      for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
743
        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
744 745 746 747 748

        for (subband=0; subband<7; subband++) {

          // cqi
          if (aarx==0)
749
            ue->measurements.subband_cqi_tot[eNB_id][subband]=0;
750 751 752 753

          if (subband<6) {
            //      for (i=0;i<48;i++)
            //        printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]);
754 755
            ue->measurements.subband_cqi[eNB_id][aarx][subband] =
              (signal_energy_nodc(dl_ch0,48) ) - ue->measurements.n0_power[aarx];
756

757 758 759
            ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband];
            ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband],
                ue->measurements.n0_power[aarx]);
760 761 762
          } else {
            //      for (i=0;i<12;i++)
            //        printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]);
763 764 765 766
            ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,12) ) - ue->measurements.n0_power[aarx];
            ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband];
            ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband],
                ue->measurements.n0_power[aarx]);
767 768 769
          }

          dl_ch1+=48;
770
          //    msg("subband_cqi[%d][%d][%d] => %d (%d dB)\n",eNB_id,aarx,subband,ue->measurements.subband_cqi[eNB_id][aarx][subband],ue->measurements.subband_cqi_dB[eNB_id][aarx][subband]);
771
        }
772 773
      }

774
      for (subband=0; subband<nb_subbands; subband++) {
775
        ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot);
776 777 778
      }
    }

779
    //ue->measurements.rank[eNB_id] = 0;
780

781
    for (i=0; i<nb_subbands; i++) {
782
      ue->measurements.selected_rx_antennas[eNB_id][i] = 0;
783

784
      if (frame_parms->nb_antennas_rx>1) {
785 786
        if (ue->measurements.subband_cqi_dB[eNB_id][0][i] >= ue->measurements.subband_cqi_dB[eNB_id][1][i])
          ue->measurements.selected_rx_antennas[eNB_id][i] = 0;
787
        else
788
          ue->measurements.selected_rx_antennas[eNB_id][i] = 1;
789
      } else
790
        ue->measurements.selected_rx_antennas[eNB_id][i] = 0;
791 792
    }