ra_procedures.c 20.9 KB
Newer Older
1
/*******************************************************************************
nikaeinn's avatar
nikaeinn committed
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

nikaeinn's avatar
nikaeinn committed
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


nikaeinn's avatar
nikaeinn committed
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

nikaeinn's avatar
nikaeinn committed
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
nikaeinn's avatar
nikaeinn committed
22 23 24 25
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

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

nikaeinn's avatar
nikaeinn committed
28
*******************************************************************************/
29

nikaeinn's avatar
nikaeinn committed
30
/*! \file ra_procedures.c
gauthier's avatar
gauthier committed
31
 * \brief Routines for UE MAC-layer Random-access procedures (36.321) V8.6 2009-03
nikaeinn's avatar
nikaeinn committed
32
 * \author R. Knopp and Navid Nikaein
gauthier's avatar
gauthier committed
33 34 35
 * \date 2011
 * \version 0.1
 * \company Eurecom
nikaeinn's avatar
nikaeinn committed
36
 * \email: knopp@eurecom.fr navid.nikaein@eurecom.fr
gauthier's avatar
gauthier committed
37 38 39
 * \note
 * \warning
 */
40 41 42

#include "extern.h"
#include "defs.h"
43 44
#include "proto.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
45 46 47 48
#include "PHY_INTERFACE/defs.h"
#include "PHY_INTERFACE/extern.h"
#include "COMMON/mac_rrc_primitives.h"
#include "RRC/LITE/extern.h"
winckel's avatar
winckel committed
49
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
50
#include "UTIL/LOG/log.h"
winckel's avatar
winckel committed
51
#include "UTIL/OPT/opt.h"
52 53 54 55 56 57 58 59
#include "OCG.h"
#include "OCG_extern.h"
#ifdef PHY_EMUL
#include "SIMULATION/simulation_defs.h"
#endif

extern inline unsigned int taus(void);

knopp's avatar
 
knopp committed
60 61 62 63 64 65 66
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id) {

  if (CC_id>0) {
    LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
    mac_xface->macphy_exit("MAC FATAL  CC_id>0");
    return;
  }
67

gauthier's avatar
gauthier committed
68 69
  uint8_t prachConfigIndex = UE_mac_inst[module_idP].radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
  uint8_t preambleformat;
70

gauthier's avatar
gauthier committed
71 72 73 74 75 76 77 78 79 80 81
  if (UE_mac_inst[module_idP].tdd_Config) { // TDD
      if (prachConfigIndex < 20)
        preambleformat = 0;
      else if (prachConfigIndex < 30)
        preambleformat = 1;
      else if (prachConfigIndex < 40)
        preambleformat = 2;
      else if (prachConfigIndex < 48)
        preambleformat = 3;
      else
        preambleformat = 4;
82 83
  }
  else { // FDD
gauthier's avatar
gauthier committed
84
      preambleformat = prachConfigIndex>>2;
85 86 87 88 89 90 91 92 93 94 95 96
  }
  switch (preambleformat) {
  case 0:
  case 1:
    return(0);
  case 2:
  case 3:
    return(-3);
  case 4:
    return(8);
  default:
    LOG_E(MAC,"[UE %d] ue_procedures.c: FATAL, Illegal preambleformat %d, prachConfigIndex %d\n",
gauthier's avatar
gauthier committed
97 98
        module_idP,
        preambleformat,prachConfigIndex);
gauthier's avatar
gauthier committed
99
    mac_xface->macphy_exit("MAC get_DELTA_PREAMBLE Illegal preamble format");
100 101 102 103 104
    return(0);
  }

}

knopp's avatar
 
knopp committed
105
/// This routine implements Section 5.1.2 (UE Random Access Resource Selection) from 36.321
gauthier's avatar
gauthier committed
106
void get_prach_resources(module_id_t module_idP,
knopp's avatar
 
knopp committed
107 108 109 110 111
			 int CC_id,
			 uint8_t eNB_index,
			 uint8_t t_id,
			 uint8_t first_Msg3,
			 RACH_ConfigDedicated_t *rach_ConfigDedicated) {
gauthier's avatar
gauthier committed
112

gauthier's avatar
gauthier committed
113
  uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size;
gauthier's avatar
gauthier committed
114
  PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources;
115
  RACH_ConfigCommon_t *rach_ConfigCommon = NULL;
gauthier's avatar
gauthier committed
116 117
  uint8_t noGroupB = 0;
  uint8_t f_id = 0,num_prach=0;
118

knopp's avatar
 
knopp committed
119 120 121 122 123 124
  if (CC_id>0) {
    LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
    mac_xface->macphy_exit("MAC FATAL  CC_id>0");
    return;
  }
    
gauthier's avatar
gauthier committed
125 126
  if (UE_mac_inst[module_idP].radioResourceConfigCommon)
    rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
127
  else {
gauthier's avatar
gauthier committed
128
      LOG_E(MAC,"[UE %d] FATAL  radioResourceConfigCommon is NULL !!!\n",module_idP);
gauthier's avatar
gauthier committed
129
      mac_xface->macphy_exit("MAC FATAL  radioResourceConfigCommon is NULL");
130 131 132
  }

  if (rach_ConfigDedicated) {   // This is for network controlled Mobility, later
gauthier's avatar
gauthier committed
133 134 135 136 137
      if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) {
          prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
          prach_resources->ra_RACH_MaskIndex = rach_ConfigDedicated->ra_PRACH_MaskIndex;
          return;
      }
138 139 140
  }

  if (!rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) {
gauthier's avatar
gauthier committed
141
      noGroupB = 1;
142 143 144

  }
  else {
gauthier's avatar
gauthier committed
145 146 147
      if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA ==
          rach_ConfigCommon->preambleInfo.numberOfRA_Preambles)
        noGroupB = 1;
148 149 150
  }

  if (first_Msg3 == 1) {
gauthier's avatar
gauthier committed
151 152 153 154 155 156 157
      if (noGroupB == 1) {
          // use Group A procedure
          UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  = (taus())&0x3f;
          UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
          UE_mac_inst[module_idP].RA_usedGroupA = 1;
      }
      else if ((Msg3_size < rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->messageSizeGroupA) ||
158
          (mac_xface->get_PL(module_idP,0,eNB_index) > UE_mac_inst[module_idP].RA_maxPL)) {
gauthier's avatar
gauthier committed
159 160 161 162 163 164 165 166 167 168 169 170 171
          // use Group A procedure
          UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  = (taus())%rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA;
          UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
          UE_mac_inst[module_idP].RA_usedGroupA = 1;
      }
      else {  // use Group B
          UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  =
              rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA +
              (taus())%(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles -
                  rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA);
          UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
          UE_mac_inst[module_idP].RA_usedGroupA = 0;
      }
knopp's avatar
 
knopp committed
172
      UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
173 174
  }
  else {  // Msg3 is being retransmitted
gauthier's avatar
gauthier committed
175 176 177 178 179 180 181 182 183 184 185 186 187 188
      if (UE_mac_inst[module_idP].RA_usedGroupA == 1) {
          if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig)
            UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  = (taus())%rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA;
          else
            UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  = (taus())&0x3f;
          UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
      }
      else {
          UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex  =
              rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA +
              (taus())%(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles -
                  rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA);
          UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
      }
189 190
  }
  // choose random PRACH resource in TDD
gauthier's avatar
gauthier committed
191 192 193 194 195 196
  if (UE_mac_inst[module_idP].tdd_Config) {
      num_prach = mac_xface->get_num_prach_tdd(mac_xface->lte_frame_parms);
      if ((num_prach>0) && (num_prach<6))
        UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index = (taus()%num_prach);
      f_id = mac_xface->get_fid_prach_tdd(mac_xface->lte_frame_parms,
          UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index);
197 198 199
  }

  // choose RA-RNTI
gauthier's avatar
gauthier committed
200
  UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = 1 + t_id + 10*f_id;
201 202
}

203
void Msg1_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id) {
knopp's avatar
 
knopp committed
204 205 206 207 208 209

  if (CC_id>0) {
    LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
    mac_xface->macphy_exit("MAC FATAL  CC_id>0");
    return;
  }
210 211

  // start contention resolution timer
gauthier's avatar
gauthier committed
212
  UE_mac_inst[module_idP].RA_attempt_number++;
213 214
#if defined(USER_MODE) && defined(OAI_EMU)
  if (oai_emulation.info.opt_enabled) {
gauthier's avatar
gauthier committed
215 216 217 218
      trace_pdu(0, NULL, 0, module_idP, 3, UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex,
          UE_mac_inst[module_idP].subframe, 0, UE_mac_inst[module_idP].RA_attempt_number);
      LOG_D(OPT,"[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x  with size %d\n",
          module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size);
219 220 221 222 223
  }
#endif
}


224
void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id) {
knopp's avatar
 
knopp committed
225 226 227 228 229 230

  if (CC_id>0) {
    LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
    mac_xface->macphy_exit("MAC FATAL  CC_id>0");
    return;
  }
231 232

  // start contention resolution timer
gauthier's avatar
gauthier committed
233 234 235
  LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",module_idP,frameP);
  UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0;
  UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1;
236 237 238

#if defined(USER_MODE) && defined(OAI_EMU)
  if (oai_emulation.info.opt_enabled) { // msg3
gauthier's avatar
gauthier committed
239 240 241 242
      trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], UE_mac_inst[module_idP].RA_Msg3_size,
          module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].subframe, 0, 0);
      LOG_D(OPT,"[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d   with size %d\n",
          module_idP, frameP, UE_mac_inst[module_idP].crnti /*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex*/, UE_mac_inst[module_idP].RA_Msg3_size);
243 244 245 246 247
  }
#endif
}


knopp's avatar
 
knopp committed
248
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP){
249 250


gauthier's avatar
gauthier committed
251
  uint8_t                        Size=0;
knopp's avatar
 
knopp committed
252
  UE_MODE_t                 UE_mode = mac_xface->get_ue_mode(module_idP,0,eNB_indexP);
gauthier's avatar
gauthier committed
253 254
  uint8_t                        lcid = CCCH;
  uint16_t                       Size16;
255
  struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL;
gauthier's avatar
gauthier committed
256
  int32_t                       frame_diff=0;
gauthier's avatar
gauthier committed
257
  mac_rlc_status_resp_t     rlc_status;
gauthier's avatar
gauthier committed
258 259 260
  uint8_t                        dcch_header_len=0;
  uint16_t                       sdu_lengths[8];
  uint8_t                        ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
261

knopp's avatar
 
knopp committed
262 263 264 265 266 267
  if (CC_id>0) {
    LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
    mac_xface->macphy_exit("MAC FATAL  CC_id>0");
    return;
  }

268
  if (UE_mode == PRACH) {
gauthier's avatar
gauthier committed
269 270 271 272
      if (UE_mac_inst[module_idP].radioResourceConfigCommon)
        rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
      else {
          return(NULL);
273
      }
gauthier's avatar
gauthier committed
274 275 276
      if (Is_rrc_registered == 1) {

          if (UE_mac_inst[module_idP].RA_active == 0) {
knopp's avatar
 
knopp committed
277
	    printf("RA not active\n");
gauthier's avatar
gauthier committed
278 279 280 281 282 283 284
              // check if RRC is ready to initiate the RA procedure
              Size = mac_rrc_data_req(module_idP,
                  frameP,
                  CCCH,1,
                  &UE_mac_inst[module_idP].CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT)+1],0,
                  eNB_indexP,
                  0);
gauthier's avatar
gauthier committed
285
              Size16 = (uint16_t)Size;
gauthier's avatar
gauthier committed
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306

              //	LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
              LOG_D(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n",
                  frameP, module_idP, eNB_indexP, module_idP);
              LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);

              if (Size>0) {

                  UE_mac_inst[module_idP].RA_active                        = 1;
                  UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
                  UE_mac_inst[module_idP].RA_Msg3_size                     = Size+sizeof(SCH_SUBHEADER_SHORT)+sizeof(SCH_SUBHEADER_SHORT);
                  UE_mac_inst[module_idP].RA_prachMaskIndex                = 0;
                  UE_mac_inst[module_idP].RA_prach_resources.Msg3          = UE_mac_inst[module_idP].CCCH_pdu.payload;
                  UE_mac_inst[module_idP].RA_backoff_cnt                   = 0;  // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
                  if (rach_ConfigCommon) {
                      UE_mac_inst[module_idP].RA_window_cnt                    = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
                      if (UE_mac_inst[module_idP].RA_window_cnt == 9)
                        UE_mac_inst[module_idP].RA_window_cnt = 10;  // Note: 9 subframe window doesn't exist, after 8 is 10!
                  }
                  else {
                      LOG_D(MAC,"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP);
gauthier's avatar
gauthier committed
307
                      mac_xface->macphy_exit("MAC rach_ConfigCommon is NULL");
gauthier's avatar
gauthier committed
308 309 310 311 312 313
                  }
                  UE_mac_inst[module_idP].RA_tx_frame         = frameP;
                  UE_mac_inst[module_idP].RA_tx_subframe      = subframeP;
                  UE_mac_inst[module_idP].RA_backoff_frame    = frameP;
                  UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
                  // Fill in preamble and PRACH resource
knopp's avatar
 
knopp committed
314
                  get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
gauthier's avatar
gauthier committed
315

gauthier's avatar
gauthier committed
316
                  generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0],  // mac header
gauthier's avatar
gauthier committed
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
                      1,      // num sdus
                      0,            // short pading
                      &Size16,  // sdu length
                      &lcid,    // sdu lcid
                      NULL,  // power headroom
                      NULL,  // crnti
                      NULL,  // truncated bsr
                      NULL, // short bsr
                      NULL, // long_bsr
                      1); //post_padding

                  return(&UE_mac_inst[module_idP].RA_prach_resources);
              }
              else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DCCH] > 0) {
                  // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
                  dcch_header_len = 2 + 2;  /// SHORT Subheader + C-RNTI control element
gauthier's avatar
gauthier committed
333
                  rlc_status = mac_rlc_status_ind(0, module_idP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
gauthier's avatar
gauthier committed
334 335 336 337 338 339 340 341 342
                      DCCH,
                      6);
                  if (UE_mac_inst[module_idP].crnti_before_ho)
                    LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n",
                        module_idP,frameP, UE_mac_inst[module_idP].crnti,UE_mac_inst[module_idP].crnti_before_ho, rlc_status.bytes_in_buffer,dcch_header_len);
                  else
                    LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
                        module_idP,frameP, rlc_status.bytes_in_buffer,dcch_header_len);

gauthier's avatar
gauthier committed
343
                  sdu_lengths[0] = mac_rlc_data_req(eNB_indexP, module_idP,frameP,ENB_FLAG_NO, MBMS_FLAG_NO,
gauthier's avatar
gauthier committed
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
                      DCCH,
                      (char *)&ulsch_buff[0]);

                  LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
                  update_bsr(module_idP, frameP, DCCH,UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]);
                  //header_len +=2;
                  UE_mac_inst[module_idP].RA_active                        = 1;
                  UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
                  UE_mac_inst[module_idP].RA_Msg3_size                     = Size+dcch_header_len;
                  UE_mac_inst[module_idP].RA_prachMaskIndex                = 0;
                  UE_mac_inst[module_idP].RA_prach_resources.Msg3          = ulsch_buff;
                  UE_mac_inst[module_idP].RA_backoff_cnt                   = 0;  // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
                  if (rach_ConfigCommon) {
                      UE_mac_inst[module_idP].RA_window_cnt                    = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
                      if (UE_mac_inst[module_idP].RA_window_cnt == 9)
                        UE_mac_inst[module_idP].RA_window_cnt = 10;  // Note: 9 subframe window doesn't exist, after 8 is 10!
                  }
                  else {
                      LOG_D(MAC,"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP);
gauthier's avatar
gauthier committed
363
                      mac_xface->macphy_exit("MAC rach_ConfigCommon is NULL");
gauthier's avatar
gauthier committed
364 365 366 367 368 369
                  }
                  UE_mac_inst[module_idP].RA_tx_frame         = frameP;
                  UE_mac_inst[module_idP].RA_tx_subframe      = subframeP;
                  UE_mac_inst[module_idP].RA_backoff_frame    = frameP;
                  UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
                  // Fill in preamble and PRACH resource
knopp's avatar
 
knopp committed
370
                  get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
gauthier's avatar
gauthier committed
371
                  generate_ulsch_header((uint8_t*)ulsch_buff,  // mac header
gauthier's avatar
gauthier committed
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
                      1,      // num sdus
                      0,            // short pading
                      &Size16,  // sdu length
                      &lcid,    // sdu lcid
                      NULL,  // power headroom
                      &UE_mac_inst[module_idP].crnti,  // crnti
                      NULL,  // truncated bsr
                      NULL, // short bsr
                      NULL, // long_bsr
                      0); //post_padding

                  return(&UE_mac_inst[module_idP].RA_prach_resources);
              }
          }
          else {  // RACH is active
              LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",module_idP,
                  frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt,
                  UE_mac_inst[module_idP].RA_tx_frame,UE_mac_inst[module_idP].RA_tx_subframe);
              // compute backoff parameters
              if (UE_mac_inst[module_idP].RA_backoff_cnt>0) {
gauthier's avatar
gauthier committed
392
                  frame_diff = (sframe_t)frameP - UE_mac_inst[module_idP].RA_backoff_frame;
gauthier's avatar
gauthier committed
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
                  if (frame_diff < 0)
                    frame_diff = -frame_diff;
                  UE_mac_inst[module_idP].RA_backoff_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_backoff_subframe));

                  UE_mac_inst[module_idP].RA_backoff_frame    = frameP;
                  UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
              }
              // compute RA window parameters
              if (UE_mac_inst[module_idP].RA_window_cnt>0) {
                  frame_diff = (frame_t)frameP - UE_mac_inst[module_idP].RA_tx_frame;
                  if (frame_diff < 0)
                    frame_diff = -frame_diff;
                  UE_mac_inst[module_idP].RA_window_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_tx_subframe));
                  LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n",module_idP,
                      frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt);
              }
              if ((UE_mac_inst[module_idP].RA_window_cnt<=0) &&
                  (UE_mac_inst[module_idP].RA_backoff_cnt<=0)) {

                  UE_mac_inst[module_idP].RA_tx_frame    = frameP;
                  UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
                  UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++;
                  UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += (rach_ConfigCommon->powerRampingParameters.powerRampingStep<<1);  // 2dB increments in ASN.1 definition
                  if (UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER == rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax) {
                      LOG_D(MAC,"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",module_idP,frameP,rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax);
                      // send message to RRC
                      UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1;
knopp's avatar
 
knopp committed
420
                      UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
gauthier's avatar
gauthier committed
421 422 423 424 425
                  }
                  UE_mac_inst[module_idP].RA_window_cnt                    = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
                  UE_mac_inst[module_idP].RA_backoff_cnt                   = 0;

                  // Fill in preamble and PRACH resource
knopp's avatar
 
knopp committed
426
                  get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,0,NULL);
gauthier's avatar
gauthier committed
427 428 429
                  return(&UE_mac_inst[module_idP].RA_prach_resources);
              }
          }
430 431 432
      }
  }
  else if (UE_mode == PUSCH) {
gauthier's avatar
gauthier committed
433
      LOG_D(MAC,"[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...",module_idP);
gauthier's avatar
gauthier committed
434
      mac_xface->macphy_exit("MAC FATAL: Should not have checked for RACH in PUSCH yet");
435 436 437
  }
  return(NULL);
}