rar_tools.c 6.57 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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
/*******************************************************************************

  Eurecom OpenAirInterface
  Copyright(c) 1999 - 2010 Eurecom

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope 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.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information
  Openair Admin: openair_admin@eurecom.fr
  Openair Tech : openair_tech@eurecom.fr
  Forums       : http://forums.eurecom.fsr/openairinterface
  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France

*******************************************************************************/
/*! \file rar_tools.c
* \brief random access tools
* \author Raymond Knopp
* \date 2011
* \version 0.5
* @ingroup _mac

*/

#include "defs.h"
#include "extern.h"
#include "MAC_INTERFACE/defs.h"
#include "MAC_INTERFACE/extern.h"
#include "SIMULATION/TOOLS/defs.h"
#include "UTIL/LOG/log.h"
#include "OCG.h"
#include "OCG_extern.h"

#define DEBUG_RAR

extern unsigned int  localRIV2alloc_LUT25[512];
extern unsigned int  distRIV2alloc_LUT25[512];
extern unsigned short RIV2nb_rb_LUT25[512];
extern unsigned short RIV2first_rb_LUT25[512];

extern inline unsigned int taus(void);

unsigned short fill_rar(u8 Mod_id,
			u32 frame,
			u8 *dlsch_buffer,
			u16 N_RB_UL,
			u8 input_buffer_length) {

  RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
  //  RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
  uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
Raymond Knopp's avatar
Raymond Knopp committed
65
  int i,ra_idx;
66
  uint16_t rballoc;
Raymond Knopp's avatar
Raymond Knopp committed
67
  uint8_t mcs,TPC,cqi_req,ULdelay,cqireq;
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

  for (i=0;i<NB_RA_PROC_MAX;i++) {
    if (eNB_mac_inst[Mod_id].RA_template[i].generate_rar == 1) {
      ra_idx=i;
      eNB_mac_inst[Mod_id].RA_template[i].generate_rar = 0;
      break;
    }
  }

  // subheader fixed 
  rarh->E                     = 0; // First and last RAR
  rarh->T                     = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
  rarh->RAPID                 = eNB_mac_inst[Mod_id].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment
  /*
  rar->R                      = 0;
  rar->Timing_Advance_Command = eNB_mac_inst[Mod_id].RA_template[ra_idx].timing_offset/4;
  rar->hopping_flag           = 0;
  rar->rb_alloc               = mac_xface->computeRIV(N_RB_UL,12,2);  // 2 RB
  rar->mcs                    = 2;                                   // mcs 2
  rar->TPC                    = 4;   // 2 dB power adjustment
  rar->UL_delay               = 0;
  rar->cqi_req                = 1;
  rar->t_crnti                = eNB_mac_inst[Mod_id].RA_template[ra_idx].rnti;
  */
  rar[4] = (uint8_t)(eNB_mac_inst[Mod_id].RA_template[ra_idx].rnti>>8); 
  rar[5] = (uint8_t)(eNB_mac_inst[Mod_id].RA_template[ra_idx].rnti&0xff);
Raymond Knopp's avatar
Raymond Knopp committed
94 95
  eNB_mac_inst[Mod_id].RA_template[ra_idx].timing_offset = 0;
  //eNB_mac_inst[Mod_id].RA_template[ra_idx].timing_offset /= 16;
96 97 98 99 100
  rar[0] = (uint8_t)(eNB_mac_inst[Mod_id].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
  rar[1] = (uint8_t)(eNB_mac_inst[Mod_id].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
  rballoc = mac_xface->computeRIV(N_RB_UL,1,1); // first PRB only for UL Grant
  rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
  rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc
Raymond Knopp's avatar
Raymond Knopp committed
101 102
  mcs = 10;
  TPC = 3;
103 104
  ULdelay = 0;
  cqireq = 0;
Raymond Knopp's avatar
Raymond Knopp committed
105 106
  rar[2] |= ((mcs&0x8)>>3);  // mcs 10
  rar[3] = (((mcs&0x7)<<5)) | ((TPC&7)<<2) | ((ULdelay&1)<<1) | (cqireq&1); 
107

Raymond Knopp's avatar
Raymond Knopp committed
108
  LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",Mod_id,frame,
109
	*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
Raymond Knopp's avatar
Raymond Knopp committed
110
	ra_idx,
111
	eNB_mac_inst[Mod_id].RA_template[ra_idx].rnti,
Raymond Knopp's avatar
Raymond Knopp committed
112 113
	rarh->RAPID,eNB_mac_inst[Mod_id].RA_template[0].preamble_index,
	eNB_mac_inst[Mod_id].RA_template[ra_idx].timing_offset);
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

#if defined(USER_MODE) && defined(OAI_EMU)
  if (oai_emulation.info.opt_enabled){
    trace_pdu(1, dlsch_buffer, input_buffer_length, Mod_id, 2, 1,
              eNB_mac_inst[Mod_id].subframe, 0, 0);
    LOG_I(OPT,"[eNB %d][RAPROC] RAR Frame %d trace pdu for rnti %x and  rapid %d size %d\n",
          Mod_id, frame, eNB_mac_inst[Mod_id].RA_template[ra_idx].rnti,
          rarh->RAPID, input_buffer_length);
  } 
#endif 
  return(eNB_mac_inst[Mod_id].RA_template[ra_idx].rnti);
}

uint16_t ue_process_rar(u8 Mod_id, u32 frame, u8 *dlsch_buffer,u16 *t_crnti,u8 preamble_index) {

  RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
  //  RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
  uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
  
  LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",Mod_id,frame,
	*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
	rarh->RAPID,preamble_index);
#ifdef DEBUG_RAR
  LOG_D(MAC,"[UE %d][RAPROC] rarh->E %d\n",Mod_id,rarh->E);
  LOG_D(MAC,"[UE %d][RAPROC] rarh->T %d\n",Mod_id,rarh->T);
  LOG_D(MAC,"[UE %d][RAPROC] rarh->RAPID %d\n",Mod_id,rarh->RAPID);

  //  LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",Mod_id,rar->R);
  LOG_I(MAC,"[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",Mod_id,(((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
  //  LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",Mod_id,rar->hopping_flag);
  //  LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",Mod_id,rar->rb_alloc);
  //  LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",Mod_id,rar->mcs);
  //  LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",Mod_id,rar->TPC);
  //  LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",Mod_id,rar->UL_delay);
  //  LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",Mod_id,rar->cqi_req);
  LOG_I(MAC,"[UE %d][RAPROC] rar->t_crnti %x\n",Mod_id,(uint16_t)rar[5]+(rar[4]<<8)); 
#endif

  
  if (preamble_index == rarh->RAPID) {
    *t_crnti = (uint16_t)rar[5]+(rar[4]<<8);//rar->t_crnti;
    UE_mac_inst[Mod_id].crnti = *t_crnti;//rar->t_crnti;
    //return(rar->Timing_Advance_Command);
    return((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
  }
  else {
    UE_mac_inst[Mod_id].crnti=0;
    return(0xffff);
  }
}