L2_interface.c 12.1 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
#if defined(ENABLE_ITTI)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
41
  #include "intertask_interface.h"
42 43
#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
  const frame_t     frameP,
  const rb_id_t     Srb_id,
  const uint8_t     Nb_tb,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
57
  uint8_t    *const buffer_pP,
58 59 60
  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
  if (LOG_DEBUGFLAG(DEBUG_RRC)) {
    LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id);
  }
70

71 72
  eNB_RRC_INST *rrc;
  rrc_eNB_carrier_data_t *carrier;
73
  LTE_BCCH_BCH_Message_t *mib;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
74 75 76
  rrc     = RC.rrc[Mod_idP];
  carrier = &rrc->carrier[0];
  mib     = &carrier->mib;
77

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
78 79 80 81
  if((Srb_id & RAB_OFFSET) == BCCH) {
    if(RC.rrc[Mod_idP]->carrier[CC_id].SI.Active==0) {
      return 0;
    }
82

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
83 84 85
    // All even frames transmit SIB in SF 5
    AssertFatal(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1 != 255,
                "[eNB %d] MAC Request for SIB1 and SIB1 not initialized\n",Mod_idP);
86

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
87 88 89 90
    if ((frameP%2) == 0) {
      memcpy(&buffer_pP[0],
             RC.rrc[Mod_idP]->carrier[CC_id].SIB1,
             RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1);
91

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
92 93
      if (LOG_DEBUGFLAG(DEBUG_RRC)) {
        LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1\n",Mod_idP,frameP);
94

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
95 96 97
        for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1; i++) {
          LOG_T(RRC,"%x.",buffer_pP[i]);
        }
98

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
99 100
        LOG_T(RRC,"\n");
      } /* LOG_DEBUGFLAG(DEBUG_RRC) */
101

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
102 103 104 105 106 107
      return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1);
    } // All RFN mod 8 transmit SIB2-3 in SF 5
    else if ((frameP%8) == 1) {
      memcpy(&buffer_pP[0],
             RC.rrc[Mod_idP]->carrier[CC_id].SIB23,
             RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23);
108

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
109 110
      if (LOG_DEBUGFLAG(DEBUG_RRC)) {
        LOG_T(RRC,"[eNB %d] Frame %d BCCH request => SIB 2-3\n",Mod_idP,frameP);
111

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
112 113 114
        for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23; i++) {
          LOG_T(RRC,"%x.",buffer_pP[i]);
        }
115

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
116 117
        LOG_T(RRC,"\n");
      } /* LOG_DEBUGFLAG(DEBUG_RRC) */
118

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
119 120 121
      return(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23);
    } else {
      return(0);
122
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
123
  }
124

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
  if( (Srb_id & RAB_OFFSET ) == MIBCH) {
    mib->message.systemFrameNumber.buf = &sfn;
    enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message,
                                     NULL,
                                     (void *)mib,
                                     carrier->MIB,
                                     24);
    LOG_D(RRC,"Encoded MIB for frame %d (%p), bits %lu\n",sfn,carrier->MIB,enc_rval.encoded);
    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);
  }
140

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
141 142
  if( (Srb_id & RAB_OFFSET ) == CCCH) {
    LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);
143

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
144 145 146 147
    if(RC.rrc[Mod_idP]->carrier[CC_id].Srb0.Active==0) {
      LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP);
      return -1;
    }
148

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
149
    Srb_info=&RC.rrc[Mod_idP]->carrier[CC_id].Srb0;
150

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
151 152 153 154 155 156
    // check if data is there for MAC
    if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer
      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);
      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;
157
    }
158

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
159 160
    return (Sdu_size);
  }
161

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
162 163
  if( (Srb_id & RAB_OFFSET ) == PCCH) {
    LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);
164

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
165 166 167 168 169 170 171
    // 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;
172 173
    }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
174 175 176
    return (Sdu_size);
  }

177
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
178

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
179 180 181 182
  if((Srb_id & RAB_OFFSET) == MCCH) {
    if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) {
      return 0;  // this parameter is set in function init_mcch in rrc_eNB.c
    }
183

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
184 185 186
    memcpy(&buffer_pP[0],
           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
187

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
188 189
    if (LOG_DEBUGFLAG(DEBUG_RRC)) {
      LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP);
190

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
191 192 193
      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]);
      }
194

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
195 196
      LOG_T(RRC,"\n");
    } /* LOG_DEBUGFLAG(DEBUG_RRC) */
Lionel Gauthier's avatar
 
Lionel Gauthier committed
197

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
198 199
    return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
  }
200

201 202
#endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
203

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
204 205 206 207 208 209
  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);
  }
210

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
211 212 213 214 215 216
  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);
  }
217

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
218
#endif
219
  return(0);
220 221
}

222 223
//------------------------------------------------------------------------------
int8_t
224
mac_rrc_data_ind(
225
  const module_id_t     module_idP,
226
  const int             CC_id,
227
  const frame_t         frameP,
228
  const sub_frame_t     sub_frameP,
229 230
  const rnti_t          rntiP,
  const rb_id_t         srb_idP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
231
  const uint8_t        *sduP,
232 233 234 235
  const sdu_size_t      sdu_lenP,
  const uint8_t         mbsfn_sync_areaP
)
//--------------------------------------------------------------------------
236 237
{
  SRB_INFO *Srb_info;
238
  protocol_ctxt_t ctxt;
239
  sdu_size_t      sdu_size = 0;
Cedric Roux's avatar
Cedric Roux committed
240 241
  /* for no gcc warnings */
  (void)sdu_size;
242
  /*
243
  int si_window;
244
   */
245
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0);
246

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
247
  if((srb_idP & RAB_OFFSET) == CCCH) {
248
    Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
Raymond Knopp's avatar
Raymond Knopp committed
249
    LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
250

251
    //    msg("\n******INST %d Srb_info %p, Srb_id=%d****\n\n",Mod_id,Srb_info,Srb_info->Srb_id);
252 253 254
    if (sdu_lenP > 0) {
      memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP);
      Srb_info->Rx_buffer.payload_size = sdu_lenP;
255
      rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
256
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
257 258 259 260 261 262 263 264 265 266 267
  }

  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;
Xu Bo's avatar
Xu Bo committed
268
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
269
  }
270 271

  return(0);
272 273
}

274
//------------------------------------------------------------------------------
275 276 277
/*
* Get RRC status (Connected, Idle...) of UE from RNTI
*/
278
int
279
mac_eNB_get_rrc_status(
280 281 282 283
  const module_id_t Mod_idP,
  const rnti_t      rntiP
)
//------------------------------------------------------------------------------
284
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
285
  struct rrc_eNB_ue_context_s *ue_context_p = NULL;
286
  ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP], rntiP);
287 288 289

  if (ue_context_p != NULL) {
    return(ue_context_p->ue_context.Status);
290
  } else {
291
    return RRC_INACTIVE;
292
  }
293 294
}

295
void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
296 297 298 299 300
                            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;
301
  ue_context_p = rrc_eNB_get_ue_context(
302
                   RC.rrc[Mod_instP],
303 304 305
                   rntiP);

  if (ue_context_p != NULL) {
Raymond Knopp's avatar
Raymond Knopp committed
306
    LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
307

308 309
    if(ue_context_p->ue_context.ul_failure_timer == 0)
      ue_context_p->ue_context.ul_failure_timer=1;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
310
  } else {
311
    LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
312
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
313

314 315
  if (rrc_agent_registered[Mod_instP]) {
    agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
316 317
        rntiP,
        PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
318
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
319

320
  rrc_mac_remove_ue(Mod_instP,rntiP);
321 322 323
}

void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
                                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);
  }
341
}
kaltenbe's avatar
kaltenbe committed
342

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
343 344 345 346 347 348
void mac_eNB_rrc_ul_in_sync(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;
349
  ue_context_p = rrc_eNB_get_ue_context(
350
                   RC.rrc[Mod_instP],
351 352 353
                   rntiP);

  if (ue_context_p != NULL) {
354 355 356 357 358 359
    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);
360
  }
kaltenbe's avatar
kaltenbe committed
361
}