L2_interface.c 12 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 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
 */

22
/*! \file l2_interface.c
Lionel Gauthier's avatar
 
Lionel Gauthier committed
23 24 25 26 27 28 29
 * \brief layer 2 interface, used to support different RRC sublayer
 * \author Raymond Knopp and Navid Nikaein
 * \date 2010-2014
 * \version 1.0
 * \company Eurecom
 * \email: raymond.knopp@eurecom.fr
 */
30

Lionel Gauthier's avatar
Lionel Gauthier committed
31
#include "platform_types.h"
32 33
#include "rrc_defs.h"
#include "rrc_extern.h"
34
#include "common/utils/LOG/log.h"
35
#include "rrc_eNB_UE_context.h"
36
#include "pdcp.h"
37
#include "msc.h"
38
#include "common/ran_context.h"
39

40 41 42 43
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

44 45
#include "flexran_agent_extern.h"

46

47 48
extern RAN_CONTEXT_t RC;

49 50
//------------------------------------------------------------------------------
int8_t
51
mac_rrc_data_req(
52
  const module_id_t Mod_idP,
53
  const int         CC_id,
54 55 56 57 58 59 60
  const frame_t     frameP,
  const rb_id_t     Srb_id,
  const uint8_t     Nb_tb,
  uint8_t*    const buffer_pP,
  const uint8_t     mbsfn_sync_area
)
//--------------------------------------------------------------------------
61
{
62
  asn_enc_rval_t enc_rval;
63
  SRB_INFO *Srb_info;
64 65
  uint8_t Sdu_size                = 0;
  uint8_t sfn                     = (uint8_t)((frameP>>2)&0xff);
66 67


68 69 70
  if (LOG_DEBUGFLAG(DEBUG_RRC)) {
    LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id);
  }
71

72 73 74 75
  eNB_RRC_INST *rrc;
  rrc_eNB_carrier_data_t *carrier;
  BCCH_BCH_Message_t *mib;

76

77 78 79 80
    rrc     = RC.rrc[Mod_idP];
    carrier = &rrc->carrier[0];
    mib     = &carrier->mib;

81
    if((Srb_id & RAB_OFFSET) == BCCH) {
82
      if(RC.rrc[Mod_idP]->carrier[CC_id].SI.Active==0) {
83 84
        return 0;
      }
85

86
      // All even frames transmit SIB in SF 5
87 88
      AssertFatal(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1 != 255, 
		  "[eNB %d] MAC Request for SIB1 and SIB1 not initialized\n",Mod_idP);
89 90

      if ((frameP%2) == 0) {
91
        memcpy(&buffer_pP[0],
92 93
               RC.rrc[Mod_idP]->carrier[CC_id].SIB1,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1);
94

95 96
        if (LOG_DEBUGFLAG(DEBUG_RRC)) {
          LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1\n",Mod_idP,frameP);
97

98 99 100
          for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1; i++) {
            LOG_T(RRC,"%x.",buffer_pP[i]);
          }
101

102 103
          LOG_T(RRC,"\n");
        } /* LOG_DEBUGFLAG(DEBUG_RRC) */
104

105
        return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1);
106 107
      } // All RFN mod 8 transmit SIB2-3 in SF 5
      else if ((frameP%8) == 1) {
108
        memcpy(&buffer_pP[0],
109 110
               RC.rrc[Mod_idP]->carrier[CC_id].SIB23,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23);
111

112 113
        if (LOG_DEBUGFLAG(DEBUG_RRC)) {
          LOG_T(RRC,"[eNB %d] Frame %d BCCH request => SIB 2-3\n",Mod_idP,frameP);
114

115 116 117
          for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23; i++) {
               LOG_T(RRC,"%x.",buffer_pP[i]);
          }
118

119 120
          LOG_T(RRC,"\n");
        } /* LOG_DEBUGFLAG(DEBUG_RRC) */
121
        return(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23);
122
      } else {
123
        return(0);
124
      }
125
    }
126 127 128 129
    if( (Srb_id & RAB_OFFSET ) == MIBCH) {

        mib->message.systemFrameNumber.buf = &sfn;
	enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message,
130
					 NULL,
131 132
					 (void*)mib,
					 carrier->MIB,
133
					 24);
134
	LOG_D(RRC,"Encoded MIB for frame %d (%p), bits %lu\n",sfn,carrier->MIB,enc_rval.encoded);
135 136 137 138 139 140 141
	buffer_pP[0]=carrier->MIB[0];
	buffer_pP[1]=carrier->MIB[1];
	buffer_pP[2]=carrier->MIB[2];
	AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
		     enc_rval.failed_type->name, enc_rval.encoded);
	return(3);
    }
142

143
    if( (Srb_id & RAB_OFFSET ) == CCCH) {
144
      LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);
145

146
      if(RC.rrc[Mod_idP]->carrier[CC_id].Srb0.Active==0) {
147 148 149 150
        LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP);
        return -1;
      }

151
      Srb_info=&RC.rrc[Mod_idP]->carrier[CC_id].Srb0;
152

153 154
      // check if data is there for MAC
      if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer
Raymond Knopp's avatar
Raymond Knopp committed
155
        LOG_D(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload);
156

157 158 159 160
        memcpy(buffer_pP,Srb_info->Tx_buffer.Payload,Srb_info->Tx_buffer.payload_size);
        Sdu_size = Srb_info->Tx_buffer.payload_size;
        Srb_info->Tx_buffer.payload_size=0;
      }
161

162 163
      return (Sdu_size);
    }
164

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    if( (Srb_id & RAB_OFFSET ) == PCCH) {
      LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);

      // check if data is there for MAC
      if(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] > 0) { //Fill buffer
        LOG_D(RRC,"[eNB %d] PCCH (%p) has %d bytes\n",Mod_idP,&RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area],
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]);

        memcpy(buffer_pP, RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]);
        Sdu_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area];
        RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] = 0;
      }

      return (Sdu_size);
    }

181
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
182 183

    if((Srb_id & RAB_OFFSET) == MCCH) {
184
      if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) {
185 186
        return 0;  // this parameter is set in function init_mcch in rrc_eNB.c
      }
187 188

      memcpy(&buffer_pP[0],
189 190
             RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area],
             RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
191

192 193
     if (LOG_DEBUGFLAG(DEBUG_RRC)) {
       LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP);
194

195 196 197
       for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) {
            LOG_T(RRC,"%x.",buffer_pP[i]);
       }
198

199 200
       LOG_T(RRC,"\n");
     } /* LOG_DEBUGFLAG(DEBUG_RRC) */
Lionel Gauthier's avatar
 
Lionel Gauthier committed
201

202
     return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
203 204
    }

205
#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
206

207
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR){
        memcpy(&buffer_pP[0],
               RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR);
        return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR);
    }

    if ((Srb_id & RAB_OFFSET) == BCCH_SI_BR){ // First SI message with SIB2/3
        memcpy(&buffer_pP[0],
               RC.rrc[Mod_idP]->carrier[CC_id].SIB23_BR,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR);
        return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR);
    }

#endif

224 225

  return(0);
226 227
}

228 229
//------------------------------------------------------------------------------
int8_t
230
mac_rrc_data_ind(
231
  const module_id_t     module_idP,
232
  const int             CC_id,
233
  const frame_t         frameP,
234
  const sub_frame_t     sub_frameP,
235 236 237 238 239 240 241
  const rnti_t          rntiP,
  const rb_id_t         srb_idP,
  const uint8_t*        sduP,
  const sdu_size_t      sdu_lenP,
  const uint8_t         mbsfn_sync_areaP
)
//--------------------------------------------------------------------------
242 243
{
  SRB_INFO *Srb_info;
244
  protocol_ctxt_t ctxt;
245
  sdu_size_t      sdu_size = 0;
Cedric Roux's avatar
Cedric Roux committed
246 247 248 249

  /* for no gcc warnings */
  (void)sdu_size;

250
  /*
251
  int si_window;
252
   */
253
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0);
254

Xu Bo's avatar
Xu Bo committed
255
    if((srb_idP & RAB_OFFSET) == CCCH) {
256
    Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
Raymond Knopp's avatar
Raymond Knopp committed
257
    LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
258
    
259
    //    msg("\n******INST %d Srb_info %p, Srb_id=%d****\n\n",Mod_id,Srb_info,Srb_info->Srb_id);
260 261 262
    if (sdu_lenP > 0) {
      memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP);
      Srb_info->Rx_buffer.payload_size = sdu_lenP;
263
      rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
264
    }
Xu Bo's avatar
Xu Bo committed
265 266 267 268 269 270 271 272 273 274 275
    }
    if((srb_idP & RAB_OFFSET) == DCCH) {
      struct rrc_eNB_ue_context_s*    ue_context_p = NULL;
      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP);
      if(ue_context_p){
        rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,
            ue_context_p,
            0);
        ue_context_p->ue_context.Status = RRC_RECONFIGURED;
      }
    }
276 277

  return(0);
278 279 280

}

281 282
//------------------------------------------------------------------------------
int
283
mac_eNB_get_rrc_status(
284 285 286 287
  const module_id_t Mod_idP,
  const rnti_t      rntiP
)
//------------------------------------------------------------------------------
288
{
289 290
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
291
                   RC.rrc[Mod_idP],
292 293 294 295
                   rntiP);

  if (ue_context_p != NULL) {
    return(ue_context_p->ue_context.Status);
296
  } else {
297
    return RRC_INACTIVE;
298
  }
299 300
}

301 302
void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
			    const int CC_idP,
303 304
			    const frame_t frameP,
			    const sub_frame_t subframeP,
305 306
			    const rnti_t rntiP)
{
307 308
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
309
                   RC.rrc[Mod_instP],
310 311 312
                   rntiP);

  if (ue_context_p != NULL) {
Raymond Knopp's avatar
Raymond Knopp committed
313
    LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
314 315
    if(ue_context_p->ue_context.ul_failure_timer == 0)
      ue_context_p->ue_context.ul_failure_timer=1;
316 317
  }
  else {
318
    LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
319
  }
320 321 322 323 324
  if (rrc_agent_registered[Mod_instP]) {
    agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP,
								     rntiP,
								     PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
  }
325
  rrc_mac_remove_ue(Mod_instP,rntiP);
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
}

void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
                const int CC_idP,
                const frame_t frameP,
                const sub_frame_t subframeP,
                const rnti_t rntiP)
{
    struct rrc_eNB_ue_context_s* ue_context_p = NULL;
    ue_context_p = rrc_eNB_get_ue_context(
                     RC.rrc[Mod_instP],
                     rntiP);
    if (ue_context_p != NULL) {
      LOG_I(RRC,"Frame %d, Subframe %d: UE %x U-Plane failure, activating timer\n",frameP,subframeP,rntiP);

      if(ue_context_p->ue_context.ul_failure_timer == 0)
          ue_context_p->ue_context.ul_failure_timer=19999;
    }
    else {
      LOG_W(RRC,"Frame %d, Subframe %d: U-Plane failure: UE %x unknown \n",frameP,subframeP,rntiP);
    }
347
}
kaltenbe's avatar
kaltenbe committed
348 349

void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, 
350
			    const int CC_idP, 
kaltenbe's avatar
kaltenbe committed
351 352
			    const frame_t frameP,
			    const sub_frame_t subframeP,
353 354
			    const rnti_t rntiP)
{
355 356
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
357
                   RC.rrc[Mod_instP],
358 359 360
                   rntiP);

  if (ue_context_p != NULL) {
361 362 363 364 365 366
    LOG_I(RRC,"Frame %d, Subframe %d: UE %x to UL in synch\n",
          frameP, subframeP, rntiP);
    ue_context_p->ue_context.ul_failure_timer = 0;
  } else {
    LOG_E(RRC,"Frame %d, Subframe %d: UE %x unknown \n",
          frameP, subframeP, rntiP);
367
  }
kaltenbe's avatar
kaltenbe committed
368
}