eNB_scheduler_bch.c 13.7 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

5 6 7 8
    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.
9 10


11 12 13 14
    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.
15

16 17 18 19
    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/>.
20 21

  Contact Information
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27 28 29 30 31

*******************************************************************************/

/*! \file eNB_scheduler_bch.c
 * \brief procedures related to eNB for the BCH transport channel
32
 * \author  Navid Nikaein and Raymond Knopp
33
 * \date 2010 - 2014
34
 * \email: navid.nikaein@eurecom.fr
35
 * \version 1.0
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
 * @ingroup _mac

 */

#include "assertions.h"
#include "PHY/defs.h"
#include "PHY/extern.h"

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/proto.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"

#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"

//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1


70 71 72 73 74
//------------------------------------------------------------------------------
void
schedule_SI(
  module_id_t   module_idP,
  frame_t       frameP,
75 76 77
  sub_frame_t   subframeP,
  unsigned int* nprbP)

78
//------------------------------------------------------------------------------
79
{
knopp's avatar
knopp committed
80

81 82


83
  int8_t bcch_sdu_length;
84
  int mcs = -1;
knopp's avatar
knopp committed
85 86 87
  void *BCCH_alloc_pdu;
  int CC_id;
  eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP];
88 89 90 91 92
  uint8_t *vrb_map;
  int first_rb;
  int rballoc[MAX_NUM_CCs];
  int sizeof1A_bytes,sizeof1A_bits;
  DCI_PDU *DCI_pdu;
knopp's avatar
knopp committed
93 94 95

  start_meas(&eNB->schedule_si);

96
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
97 98 99 100
    
    BCCH_alloc_pdu  = (void*)&eNB->common_channels[CC_id].BCCH_alloc_pdu;
    DCI_pdu         = (void*)&eNB->common_channels[CC_id].DCI_pdu;
    vrb_map         = (void*)&eNB->common_channels[CC_id].vrb_map;
knopp's avatar
knopp committed
101 102

    bcch_sdu_length = mac_rrc_data_req(module_idP,
103
                                       CC_id,
104 105 106 107 108 109 110
                                       frameP,
                                       BCCH,1,
                                       &eNB->common_channels[CC_id].BCCH_pdu.payload[0],
                                       1,
                                       module_idP,
                                       0); // not used in this case

knopp's avatar
knopp committed
111
    if (bcch_sdu_length > 0) {
Cedric Roux's avatar
Cedric Roux committed
112
      LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,CC_id,bcch_sdu_length);
113

114 115 116 117 118 119 120 121 122 123 124 125 126
      // Allocate 4 PRBs in a random location
      while (1) {
	first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL-4));
	if ((vrb_map[first_rb] != 1) && 
	    (vrb_map[first_rb+1] != 1) && 
	    (vrb_map[first_rb+2] != 1) && 
	    (vrb_map[first_rb+3] != 1))
	  break;
      }
      vrb_map[first_rb] = 1;
      vrb_map[first_rb+1] = 1;
      vrb_map[first_rb+2] = 1;
      vrb_map[first_rb+3] = 1;
127

128
      // Get MCS for length of SI
129
      if (bcch_sdu_length <= (mac_xface->get_TBS_DL(0,3))) {
130
        mcs=0;
131
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(1,3))) {
132
        mcs=1;
133
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(2,3))) {
134
        mcs=2;
135
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(3,3))) {
136
        mcs=3;
137
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(4,3))) {
138
        mcs=4;
139
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(5,3))) {
140
        mcs=5;
141
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(6,3))) {
142
        mcs=6;
143
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(7,3))) {
144
        mcs=7;
145
      } else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(8,3))) {
146
        mcs=8;
147
      }
148

149 150


knopp's avatar
knopp committed
151
      if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) {
152 153 154
        switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
        case 6:
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
155 156 157 158 159 160 161 162 163 164 165
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
	  sizeof1A_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
	  sizeof1A_bits = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
166 167 168 169
          break;

        case 25:
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
170 171 172 173 174 175 176 177 178 179 180 181
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
	  sizeof1A_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
	  sizeof1A_bits = sizeof_DCI1A_5MHz_TDD_1_6_t;
	  break;
182 183 184

        case 50:
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
185 186 187 188 189 190 191 192 193 194 195
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
	  sizeof1A_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
	  sizeof1A_bits = sizeof_DCI1A_10MHz_TDD_1_6_t;
196 197 198 199
          break;

        case 100:
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
200 201 202 203 204 205 206 207 208 209 210 211
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
	  sizeof1A_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
	  sizeof1A_bits = sizeof_DCI1A_20MHz_TDD_1_6_t; 
         break;
212
        }
213

214 215 216 217
      } else {
        switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
        case 6:
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
218 219 220 221 222 223 224 225 226 227 228 229
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
	  sizeof1A_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
	  sizeof1A_bits = sizeof_DCI1A_1_5MHz_FDD_t;
230 231 232 233
          break;

        case 25:
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
234 235 236 237 238 239 240 241 242 243 244 245
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
	  sizeof1A_bytes = sizeof(DCI1A_5MHz_FDD_t);
	  sizeof1A_bits = sizeof_DCI1A_5MHz_FDD_t;
246 247 248 249
          break;

        case 50:
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
250 251 252 253 254 255 256 257 258 259 260 261
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
	  sizeof1A_bytes = sizeof(DCI1A_10MHz_FDD_t);
	  sizeof1A_bits = sizeof_DCI1A_10MHz_FDD_t;
262 263 264 265
          break;

        case 100:
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
266 267 268 269 270 271 272 273 274 275 276 277 278
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4);
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
          ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

          rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
 	  sizeof1A_bytes = sizeof(DCI1A_20MHz_FDD_t);
	  sizeof1A_bits = sizeof_DCI1A_20MHz_FDD_t;
	  break;
279 280

        }
281 282
      }

283 284 285 286 287 288 289 290 291 292 293 294 295
      if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,2,SI_RNTI)) {
	add_common_dci(DCI_pdu,
		       BCCH_alloc_pdu,
		       SI_RNTI,
		       sizeof1A_bytes,
		       2,
		       sizeof1A_bits,
		       format1A,0);
      }
      else {
	LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI\n",module_idP, CC_id,frameP,subframeP);
      }

296
      if (opt_enabled == 1) {
297
        trace_pdu(1,
knopp's avatar
knopp committed
298
                  &eNB->common_channels[CC_id].BCCH_pdu.payload[0],
299 300 301 302
                  bcch_sdu_length,
                  0xffff,
                  4,
                  0xffff,
knopp's avatar
knopp committed
303
                  eNB->subframe,
304 305
                  0,
                  0);
306 307
	LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
	    module_idP, frameP, CC_id, 0xffff, bcch_sdu_length);
308
      }
knopp's avatar
knopp committed
309
      if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) {
310
        LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3, TBS %d)\n",
311
              frameP,
312
              CC_id,
313 314 315
              bcch_sdu_length,
              mcs,
              mac_xface->get_TBS_DL(mcs,3));
316
      } else {
317
        LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3, TBS %d)\n",
318
              frameP,
319
              CC_id,
320 321 322 323
              bcch_sdu_length,
              mcs,
              mac_xface->get_TBS_DL(mcs,3));
      }
324

325

knopp's avatar
knopp committed
326
      nprbP[CC_id]=3;
327 328 329 330
      eNB->eNB_stats[CC_id].total_num_bcch_pdu+=1;
      eNB->eNB_stats[CC_id].bcch_buffer=bcch_sdu_length;
      eNB->eNB_stats[CC_id].total_bcch_buffer+=bcch_sdu_length;
      eNB->eNB_stats[CC_id].bcch_mcs=mcs;
331
    } else {
332

knopp's avatar
knopp committed
333 334 335
      nprbP[CC_id]=0;
      //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame);
    }
336
  }
337

338
  // this might be misleading when bcch is inactive
knopp's avatar
knopp committed
339
  stop_meas(&eNB->schedule_si);
340 341
  return;
}