gNB_scheduler_bch.c 29.2 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.1  (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
 */

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
22
/*! \file gNB_scheduler_bch.c
23
 * \brief procedures related to eNB for the BCH transport channel
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
24 25 26
 * \author  Navid Nikaein and Raymond Knopp, WEI-TAI CHEN
 * \date 2010 - 2014, 2018
 * \email: navid.nikaein@eurecom.fr, kroempa@gmail.com
27
 * \version 1.0
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
28
 * \company Eurecom, NTUST
29 30 31 32
 * @ingroup _mac

 */

33
#include "GNB_APP/RRC_nr_paramsvalues.h"
34
#include "assertions.h"
35 36 37
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
Raymond Knopp's avatar
Raymond Knopp committed
38 39
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
40 41 42
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "RRC/NR/nr_rrc_extern.h"
43
#include "common/utils/nr/nr_common.h"
44 45 46 47 48 49 50 51 52


#include "pdcp.h"

#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1

#include "common/ran_context.h"

53 54
#include "executables/softmodem-common.h"

55 56 57
extern RAN_CONTEXT_t RC;


58 59 60 61
uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) {

  int ratio;
  switch (*scc->ssbSubcarrierSpacing) {
62
    case NR_SubcarrierSpacing_kHz15:
Robert Schmidt's avatar
Robert Schmidt committed
63 64 65 66 67
      AssertFatal(band <= 79,
                  "Band %ld is not possible for SSB with 15 kHz SCS\n",
                  band);
      if (band < 77)  // below 3GHz
        ratio = 3;    // NRARFCN step is 5 kHz
68
      else
Robert Schmidt's avatar
Robert Schmidt committed
69
        ratio = 1;  // NRARFCN step is 15 kHz
70 71
      break;
    case NR_SubcarrierSpacing_kHz30:
Robert Schmidt's avatar
Robert Schmidt committed
72 73 74 75 76
      AssertFatal(band <= 79,
                  "Band %ld is not possible for SSB with 15 kHz SCS\n",
                  band);
      if (band < 77)  // below 3GHz
        ratio = 6;    // NRARFCN step is 5 kHz
77
      else
Robert Schmidt's avatar
Robert Schmidt committed
78
        ratio = 2;  // NRARFCN step is 15 kHz
79 80
      break;
    case NR_SubcarrierSpacing_kHz120:
Robert Schmidt's avatar
Robert Schmidt committed
81 82 83 84
      AssertFatal(band >= 257,
                  "Band %ld is not possible for SSB with 120 kHz SCS\n",
                  band);
      ratio = 2;  // NRARFCN step is 15 kHz
85 86
      break;
    case NR_SubcarrierSpacing_kHz240:
Robert Schmidt's avatar
Robert Schmidt committed
87 88 89 90
      AssertFatal(band >= 257,
                  "Band %ld is not possible for SSB with 240 kHz SCS\n",
                  band);
      ratio = 4;  // NRARFCN step is 15 kHz
91 92
      break;
    default:
Robert Schmidt's avatar
Robert Schmidt committed
93
      AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",
94 95 96 97 98 99 100 101 102 103
                  *scc->ssbSubcarrierSpacing);
  }

  const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;

  return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB

}


francescomani's avatar
francescomani committed
104 105 106 107
void schedule_ssb(frame_t frame, sub_frame_t slot,
                  NR_ServingCellConfigCommon_t *scc,
                  nfapi_nr_dl_tti_request_body_t *dl_req,
                  int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) {
108

109
  uint8_t beam_index = 0;
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
  nfapi_nr_dl_tti_request_pdu_t  *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
  memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
  dl_config_pdu->PDUType      = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
  dl_config_pdu->PDUSize      =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);

  AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n");
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId          = *scc->physCellId;
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss             = 0;
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex       = i_ssb;
  AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
              scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
  AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
  AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");

  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = scoffset; //kSSB
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA     = offset_pointa;
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag      = 1;
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload          = payload;
131 132 133 134 135
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
  dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
136 137
  dl_req->nPDUs++;

francescomani's avatar
francescomani committed
138 139
  LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot);

140
}
141

142
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
143 144 145 146 147
  gNB_MAC_INST *gNB = RC.nrmac[module_idP];
  NR_COMMON_channels_t *cc;
  nfapi_nr_dl_tti_request_t      *dl_tti_request;
  nfapi_nr_dl_tti_request_body_t *dl_req;
  NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
148
  uint8_t num_tdd_period,num_ssb;
149 150 151 152 153 154
  int mib_sdu_length;
  int CC_id;

  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
    cc = &gNB->common_channels[CC_id];
    NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
155
    const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
156 157 158 159
    dl_tti_request = &gNB->DL_req[CC_id];
    dl_req = &dl_tti_request->dl_tti_request_body;

    // get MIB every 8 frames
160 161
    if(((slotP == 0) && (frameP & 7) == 0) ||
       gNB->first_MIB) {
162

rmagueta's avatar
rmagueta committed
163
      mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 0, 1, &cc->MIB_pdu.payload[0]);
164

165 166 167
      // flag to avoid sending an empty MIB in the first frames of execution since gNB doesn't get at the beginning in frame 0 slot 0
      gNB->first_MIB = false;

168
      LOG_D(MAC,
169 170 171 172 173 174
            "[gNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes\n",
            module_idP,
            frameP,
            CC_id,
            mib_sdu_length);
    }
175

176 177
    int8_t ssb_period = *scc->ssb_periodicityServingCell;
    uint8_t ssb_frame_periodicity = 1;  // every how many frames SSB are generated
178

179 180
    if (ssb_period > 1) // 0 is every half frame
      ssb_frame_periodicity = 1 << (ssb_period -1);
181

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
    if (!(frameP%ssb_frame_periodicity) &&
        ((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) {
      // schedule SSB only for given frames according to SSB periodicity
      // and in first half frame unless periodicity of 5ms
      int rel_slot;
      if (ssb_period == 0) // scheduling every half frame
        rel_slot = slotP%(slots_per_frame>>1);
      else
        rel_slot = slotP;

      NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
      const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
      uint16_t offset_pointa = get_ssboffset_pointa(scc,band);
      uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;

      const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
      const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
      const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;

      uint16_t ssb_start_symbol;

      switch (scc->ssb_PositionsInBurst->present) {
        case 1:
          // short bitmap (<3GHz) max 4 SSBs
          for (int i_ssb=0; i_ssb<4; i_ssb++) {
            if ((shortBitmap->buf[0]>>(7-i_ssb))&0x01) {
              ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
              // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
              if ((ssb_start_symbol/14) == rel_slot){
francescomani's avatar
francescomani committed
211
                schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
212 213
                fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
                if (get_softmodem_params()->sa == 1) {
214
                  get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
215 216 217 218
                                                        frameP,
                                                        mib,
                                                        slots_per_frame,
                                                        ssbSubcarrierOffset,
219
                                                        ssb_start_symbol,
220 221 222
                                                        scs,
                                                        FR1,
                                                        i_ssb,
223
                                                        ssb_frame_periodicity,
224
                                                        offset_pointa);
225
                  gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
226 227 228 229 230 231 232 233 234 235 236 237
                }
              }
            }
          }
          break;
        case 2:
          // medium bitmap (<6GHz) max 8 SSBs
          for (int i_ssb=0; i_ssb<8; i_ssb++) {
            if ((mediumBitmap->buf[0]>>(7-i_ssb))&0x01) {
              ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
              // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
              if ((ssb_start_symbol/14) == rel_slot){
francescomani's avatar
francescomani committed
238
                schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
239 240
                fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
                if (get_softmodem_params()->sa == 1) {
241
                  get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
242 243 244 245
                                                        frameP,
                                                        mib,
                                                        slots_per_frame,
                                                        ssbSubcarrierOffset,
246
                                                        ssb_start_symbol,
247 248 249
                                                        scs,
                                                        FR1,
                                                        i_ssb,
250
                                                        ssb_frame_periodicity,
251
                                                        offset_pointa);
252
                  gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
253 254 255 256 257 258 259
                }
              }
            }
          }
          break;
        case 3:
          // long bitmap FR2 max 64 SSBs
260
          num_ssb = 0;
261 262
          for (int i_ssb=0; i_ssb<64; i_ssb++) {
            if ((longBitmap->buf[i_ssb/8]>>(7-(i_ssb%8)))&0x01) {
263 264 265
              ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
              // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
              if ((ssb_start_symbol/14) == rel_slot){
francescomani's avatar
francescomani committed
266
                schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
267
                fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
268 269 270 271
                const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
                const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
                const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
                num_tdd_period = rel_slot/nr_slots_period;
272 273 274
                gNB->tdd_beam_association[num_tdd_period]=i_ssb;
                num_ssb++;
                AssertFatal(num_ssb<2,"beamforming currently not supported for more than one SSB per slot\n");
275
                if (get_softmodem_params()->sa == 1) {
276
                  get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
277 278 279 280
                                                        frameP,
                                                        mib,
                                                        slots_per_frame,
                                                        ssbSubcarrierOffset,
281
                                                        ssb_start_symbol,
282 283 284
                                                        scs,
                                                        FR2,
                                                        i_ssb,
285
                                                        ssb_frame_periodicity,
286
                                                        offset_pointa);
287
                  gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
288 289 290 291 292 293 294 295 296
                }
              }
            }
          }
          break;
        default:
          AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
                      scc->ssb_PositionsInBurst->present);
      }
297
    }
298 299
  }
}
300

301

302
void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
rmagueta's avatar
rmagueta committed
303
//----------------------------------------  
304 305
}

306 307 308 309 310 311
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart,  uint16_t symStart, int CC_id) {

  AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing !=
              NR_SubcarrierSpacing_kHz240,
              "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n");

312
  uint16_t *vrb_map = cc[CC_id].vrb_map;
313

314
  for (int rb = 0; rb < 20; rb++)
315 316
    vrb_map[rbStart + rb] = 15<<symStart;

317
}
rmagueta's avatar
rmagueta committed
318

319 320 321 322 323 324
uint32_t schedule_control_sib1(module_id_t module_id,
                               int CC_id,
                               NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
                               int time_domain_allocation,
                               int startSymbolIndex,
                               int nrOfSymbols,
325
                               uint16_t dlDmrsSymbPos,
326 327
                               uint8_t candidate_idx,
                               int num_total_bytes) {
rmagueta's avatar
rmagueta committed
328 329

  gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
rmagueta's avatar
rmagueta committed
330
  uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
331
  int ret;
rmagueta's avatar
rmagueta committed
332 333

  if (gNB_mac->sched_ctrlCommon == NULL){
rmagueta's avatar
rmagueta committed
334
    LOG_D(NR_MAC,"schedule_control_common: Filling nr_mac->sched_ctrlCommon\n");
rmagueta's avatar
rmagueta committed
335 336 337
    gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon));
    gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space));
    gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
338 339 340 341 342
    for (int i=0; i<3; i++){ // loop over possible aggregation levels
      ret = fill_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space,type0_PDCCH_CSS_config,4<<i);
      if (ret == 1) break;
    }
    AssertFatal(ret==1,"No aggregation level for type0_PDCCH_CSS found\n");
343
    fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset,type0_PDCCH_CSS_config);
rmagueta's avatar
rmagueta committed
344 345
  }

346
  gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation;
347 348
  gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx = 0;
  gNB_mac->sched_ctrlCommon->sched_pdsch.mcs = 0; // starting from mcs 0
rmagueta's avatar
rmagueta committed
349 350 351
  gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes;

  uint8_t nr_of_candidates;
Eurecom's avatar
Eurecom committed
352
  find_aggregation_candidates(&gNB_mac->sched_ctrlCommon->aggregation_level, &nr_of_candidates, gNB_mac->sched_ctrlCommon->search_space,4);
Eurecom's avatar
Eurecom committed
353
  AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
rmagueta's avatar
rmagueta committed
354
  gNB_mac->sched_ctrlCommon->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
355
                                                          NULL,
rmagueta's avatar
rmagueta committed
356 357 358
                                                          gNB_mac->sched_ctrlCommon->coreset,
                                                          gNB_mac->sched_ctrlCommon->aggregation_level,
                                                          0,
359
                                                          candidate_idx,
rmagueta's avatar
rmagueta committed
360 361
                                                          nr_of_candidates);

362
  AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
rmagueta's avatar
rmagueta committed
363

364 365
  const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs;
  int rbStart = type0_PDCCH_CSS_config->cset_start_rb;
rmagueta's avatar
rmagueta committed
366

367 368 369
  // TODO: There are exceptions to this in table 5.1.2.1.1-4,5 (Default time domain allocation tables B, C)
  int mappingtype = (startSymbolIndex <= 3)? typeA: typeB;

370
  if (nrOfSymbols == 2) {
371
    gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1;
372
  } else {
373
    gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2;
374 375 376
  }

  // Calculate number of PRB_DMRS
377
  uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6;
378
  uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
rmagueta's avatar
rmagueta committed
379

380
  LOG_D(MAC,"dlDmrsSymbPos %x\n",dlDmrsSymbPos);
rmagueta's avatar
rmagueta committed
381 382 383
  int rbSize = 0;
  uint32_t TBS = 0;
  do {
384 385 386
    if(rbSize < bwpSize && !vrb_map[rbStart + rbSize])
      rbSize++;
    else{
387 388
      if (gNB_mac->sched_ctrlCommon->sched_pdsch.mcs<10)
        gNB_mac->sched_ctrlCommon->sched_pdsch.mcs++;
389 390 391
      else
        break;
    }
392 393
    TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
                         nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx),
394
                         rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3;
395 396 397 398
  } while (TBS < gNB_mac->sched_ctrlCommon->num_total_bytes);

  AssertFatal(TBS>=gNB_mac->sched_ctrlCommon->num_total_bytes,"Couldn't allocate enough resources for %d bytes in SIB1 PDSCH\n",
              gNB_mac->sched_ctrlCommon->num_total_bytes);
399

400 401
  gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize = rbSize;
  gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart = 0;
rmagueta's avatar
rmagueta committed
402

403
  LOG_D(MAC,"mcs = %i\n", gNB_mac->sched_ctrlCommon->sched_pdsch.mcs);
francescomani's avatar
francescomani committed
404 405
  LOG_D(MAC,"startSymbolIndex = %i\n", startSymbolIndex);
  LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols);
406
  LOG_D(MAC, "rbSize = %i\n", gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize);
francescomani's avatar
francescomani committed
407 408 409
  LOG_D(MAC,"TBS = %i\n", TBS);
  LOG_D(MAC,"dmrs_length %d\n",dmrs_length);
  LOG_D(MAC,"N_PRB_DMRS = %d\n",N_PRB_DMRS);
410
  LOG_D(MAC,"mappingtype = %d\n", mappingtype);
411

rmagueta's avatar
rmagueta committed
412
  // Mark the corresponding RBs as used
413
  for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; rb++) {
rmagueta's avatar
rmagueta committed
414 415
    vrb_map[rb + rbStart] = 1;
  }
416
  return TBS;
rmagueta's avatar
rmagueta committed
417 418 419 420
}

void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
                               nfapi_nr_dl_tti_request_body_t *dl_req,
421
                               NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
rmagueta's avatar
rmagueta committed
422 423
                               uint32_t TBS,
                               int StartSymbolIndex,
424 425
                               int NrOfSymbols,
                               uint16_t dlDmrsSymbPos) {
rmagueta's avatar
rmagueta committed
426 427 428 429 430 431 432 433 434

  gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
  NR_COMMON_channels_t *cc = gNB_mac->common_channels;
  NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;

  nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
  memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
  dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
  dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
435 436
  dl_req->nPDUs += 1;
  nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
437
  nr_configure_pdcch(pdcch_pdu_rel15,
438 439 440
                     gNB_mac->sched_ctrlCommon->search_space,
                     gNB_mac->sched_ctrlCommon->coreset,
                     scc,
441 442
                     NULL,
                     type0_PDCCH_CSS_config);
443

444
  nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
rmagueta's avatar
rmagueta committed
445 446 447
  memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
  dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
  dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
448
  dl_req->nPDUs += 1;
rmagueta's avatar
rmagueta committed
449 450 451 452 453 454 455 456
  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;

  pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;

  pdsch_pdu_rel15->pduBitmap = 0;
  pdsch_pdu_rel15->rnti = SI_RNTI;
  pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;

457 458
  pdsch_pdu_rel15->BWPSize  = type0_PDCCH_CSS_config->num_rbs;
  pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
rmagueta's avatar
rmagueta committed
459

460 461
  pdsch_pdu_rel15->SubcarrierSpacing = type0_PDCCH_CSS_config->scs_pdcch;
  pdsch_pdu_rel15->CyclicPrefix = 0;
rmagueta's avatar
rmagueta committed
462 463

  pdsch_pdu_rel15->NrOfCodewords = 1;
464
  pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, 0);
rmagueta's avatar
rmagueta committed
465
  pdsch_pdu_rel15->qamModOrder[0] = 2;
466
  pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
rmagueta's avatar
rmagueta committed
467 468 469 470 471 472
  pdsch_pdu_rel15->mcsTable[0] = 0;
  pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0];
  pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
  pdsch_pdu_rel15->nrOfLayers = 1;
  pdsch_pdu_rel15->transmissionScheme = 0;
  pdsch_pdu_rel15->refPoint = 1;
473
  pdsch_pdu_rel15->dmrsConfigType = 0;
rmagueta's avatar
rmagueta committed
474 475
  pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
  pdsch_pdu_rel15->SCID = 0;
476
  pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData;
rmagueta's avatar
rmagueta committed
477 478
  pdsch_pdu_rel15->dmrsPorts = 1;
  pdsch_pdu_rel15->resourceAlloc = 1;
479 480
  pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart;
  pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize;
rmagueta's avatar
rmagueta committed
481
  pdsch_pdu_rel15->VRBtoPRBMapping = 0;
482 483
  pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs,
                                                 gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx);
rmagueta's avatar
rmagueta committed
484
  pdsch_pdu_rel15->TBSize[0] = TBS;
485
  pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx;
rmagueta's avatar
rmagueta committed
486 487
  pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
  pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
488
  pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos;
489 490
  LOG_D(MAC,"dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos);

491 492 493 494 495 496 497 498 499 500
  /* Fill PDCCH DL DCI PDU */
  nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
  pdcch_pdu_rel15->numDlDci++;
  dci_pdu->RNTI = SI_RNTI;
  dci_pdu->ScramblingId = *scc->physCellId;
  dci_pdu->ScramblingRNTI = 0;
  dci_pdu->AggregationLevel = gNB_mac->sched_ctrlCommon->aggregation_level;
  dci_pdu->CceIndex = gNB_mac->sched_ctrlCommon->cce_index;
  dci_pdu->beta_PDCCH_1_0 = 0;
  dci_pdu->powerControlOffsetSS = 1;
rmagueta's avatar
rmagueta committed
501

502 503 504 505
  /* DCI payload */
  dci_pdu_rel15_t dci_payload;
  memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));

506
  dci_payload.bwp_indicator.val = 0;
rmagueta's avatar
rmagueta committed
507 508

  // frequency domain assignment
509
  dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(
510
      pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, type0_PDCCH_CSS_config->num_rbs);
511

512 513
  dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation;
  dci_payload.mcs = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
514 515 516 517 518 519 520 521 522
  dci_payload.rv = pdsch_pdu_rel15->rvIndex[0];
  dci_payload.harq_pid = 0;
  dci_payload.ndi = 0;
  dci_payload.dai[0].val = 0;
  dci_payload.tpc = 0; // table 7.2.1-1 in 38.213
  dci_payload.pucch_resource_indicator = 0;
  dci_payload.pdsch_to_harq_feedback_timing_indicator.val = 0;
  dci_payload.antenna_ports.val = 0;
  dci_payload.dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID;
rmagueta's avatar
rmagueta committed
523

524 525 526 527
  int dci_format = NR_DL_DCI_FORMAT_1_0;
  int rnti_type = NR_RNTI_SI;

  fill_dci_pdu_rel15(scc,
528
                     NULL,
529
                     &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
530
                     &dci_payload,
531 532 533
                     dci_format,
                     rnti_type,
                     pdsch_pdu_rel15->BWPSize,
534
                     0);
rmagueta's avatar
rmagueta committed
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554

  LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
  LOG_D(MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart);
  LOG_D(MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing);
  LOG_D(MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix);
  LOG_D(MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex);
  LOG_D(MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols);
  for(int n=0;n<6;n++) LOG_D(MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]);
  LOG_D(MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType);
  LOG_D(MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize);
  LOG_D(MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize);
  LOG_D(MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType);
  LOG_D(MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex);
  LOG_D(MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity);
  LOG_D(MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);

}

void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {

555
  // TODO: Get these values from RRC
rmagueta's avatar
rmagueta committed
556
  const int CC_id = 0;
557
  uint8_t candidate_idx = 0;
rmagueta's avatar
rmagueta committed
558 559

  gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
560
  NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
rmagueta's avatar
rmagueta committed
561

francescomani's avatar
francescomani committed
562 563
  int time_domain_allocation = gNB_mac->sib1_tda;

564 565 566 567 568 569 570
  int L_max;
  switch (scc->ssb_PositionsInBurst->present) {
    case 1:
      L_max = 4;
      break;
    case 2:
      L_max = 8;
francescomani's avatar
francescomani committed
571
      break;
572 573
    case 3:
      L_max = 64;
francescomani's avatar
francescomani committed
574
      break;
575 576 577 578 579 580
    default:
      AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
                  scc->ssb_PositionsInBurst->present);
  }

  for (int i=0; i<L_max; i++) {
581 582

    NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[i];
583 584 585 586 587

    if((frameP%2 == type0_PDCCH_CSS_config->sfn_c) &&
       (slotP == type0_PDCCH_CSS_config->n_0) &&
       (type0_PDCCH_CSS_config->num_rbs > 0) &&
       (type0_PDCCH_CSS_config->active == true)) {
rmagueta's avatar
rmagueta committed
588

589
      LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
rmagueta's avatar
rmagueta committed
590

591 592
      // Get SIB1
      uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
593 594 595
      uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload);
      LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
      LOG_D(NR_MAC,"SIB1: \n");
596 597
      for (int k=0;k<sib1_sdu_length;k++)
        LOG_D(NR_MAC,"byte %d : %x\n",k,((uint8_t*)sib1_payload)[k]);
rmagueta's avatar
rmagueta committed
598

599 600
      int startSymbolIndex = 0;
      int nrOfSymbols = 0;
601 602 603 604 605 606

      get_info_from_tda_tables(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern,
                               time_domain_allocation,
                               gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position,
                               1, &startSymbolIndex, &nrOfSymbols);

607
      // TODO: There are exceptions to this in table 5.1.2.1.1-4,5 (Default time domain allocation tables B, C)
608
      int mappingtype = (startSymbolIndex <= 3)? typeA: typeB;
rmagueta's avatar
rmagueta committed
609

610
      uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, mappingtype);
rmagueta's avatar
rmagueta committed
611

612 613 614 615 616 617
      // Configure sched_ctrlCommon for SIB1
      uint32_t TBS = schedule_control_sib1(module_idP, CC_id,
                                           type0_PDCCH_CSS_config,
                                           time_domain_allocation,
                                           startSymbolIndex,
                                           nrOfSymbols,
618
                                           dlDmrsSymbPos,
619 620
                                           candidate_idx, sib1_sdu_length);

621
      nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
622
      nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols, dlDmrsSymbPos);
rmagueta's avatar
rmagueta committed
623

624 625
      const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
      nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
rmagueta's avatar
rmagueta committed
626

627 628 629
      // Data to be transmitted
      bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
      memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
rmagueta's avatar
rmagueta committed
630

631 632 633 634 635 636 637
      tx_req->PDU_length = TBS;
      tx_req->PDU_index  = gNB_mac->pdu_index[0]++;
      tx_req->num_TLV = 1;
      tx_req->TLVs[0].length = TBS + 2;
      gNB_mac->TX_req[CC_id].Number_of_PDUs++;
      gNB_mac->TX_req[CC_id].SFN = frameP;
      gNB_mac->TX_req[CC_id].Slot = slotP;
638 639

      type0_PDCCH_CSS_config->active = false;
640
    }
rmagueta's avatar
rmagueta committed
641
  }
642
}