rlc_rrc.c 24.4 KB
Newer Older
gauthier's avatar
Licence    
gauthier committed
1
/*******************************************************************************
gauthier's avatar
gauthier committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom

    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.


    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.

    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/>.

  Contact Information
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
gauthier's avatar
gauthier committed
25

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

 *******************************************************************************/
29
30
31
32
33
/*
                                rlc_rrc.c
                             -------------------
  AUTHOR  : Lionel GAUTHIER
  COMPANY : EURECOM
gauthier's avatar
Licence    
gauthier committed
34
  EMAIL   : Lionel.Gauthier at eurecom dot fr
35
36
37
38
39
40
41
42
*/

#define RLC_RRC_C
#include "rlc.h"
#include "rlc_am.h"
#include "rlc_um.h"
#include "rlc_tm.h"
#include "UTIL/LOG/log.h"
gauthier's avatar
gauthier committed
43
44
45
#ifdef OAI_EMU
#include "UTIL/OCG/OCG_vars.h"
#endif
46
47
48
49
50
51
52
53
54
55
56
#include "RLC-Config.h"
#include "DRB-ToAddMod.h"
#include "DRB-ToAddModList.h"
#include "SRB-ToAddMod.h"
#include "SRB-ToAddModList.h"
#include "DL-UM-RLC.h"
#ifdef Rel10
#include "PMCH-InfoList-r9.h"
#endif

#include "LAYER2/MAC/extern.h"
gauthier's avatar
gauthier committed
57
#include "assertions.h"
58
//-----------------------------------------------------------------------------
59
rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP,
60
61
62
    const SRB_ToAddModList_t   * const srb2add_listP,
    const DRB_ToAddModList_t   * const drb2add_listP,
    const DRB_ToReleaseList_t  * const drb2release_listP
gauthier's avatar
gauthier committed
63
#if defined(Rel10)
64
    ,const PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP
gauthier's avatar
gauthier committed
65
#endif
66
67
                                        )
{
gauthier's avatar
gauthier committed
68
69
70
71
72
73
  //-----------------------------------------------------------------------------
  rb_id_t                rb_id           = 0;
  logical_chan_id_t      lc_id           = 0;
  DRB_Identity_t         drb_id          = 0;
  DRB_Identity_t*        pdrb_id         = NULL;
  long int               cnt             = 0;
74
75
76
  const SRB_ToAddMod_t  *srb_toaddmod_p  = NULL;
  const DRB_ToAddMod_t  *drb_toaddmod_p  = NULL;
  rlc_union_t           *rlc_union_p     = NULL;
77
  hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
78
  hashtable_rc_t         h_rc;
gauthier's avatar
gauthier committed
79
80
81
82
83
#if defined(Rel10)
  int                        i, j;
  MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL;
  MBMS_SessionInfo_r9_t     *MBMS_SessionInfo_p        = NULL;
  mbms_session_id_t          mbms_session_id;
84
  mbms_service_id_t          mbms_service_id;
gauthier's avatar
gauthier committed
85
  DL_UM_RLC_t                dl_um_rlc;
86
87


88
#endif
89

Cedric Roux's avatar
Cedric Roux committed
90
91
92
93
94
  /* for no gcc warnings */
  (void)rlc_union_p;
  (void)key;
  (void)h_rc;

95
96
  LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ ASN1 \n",
        PROTOCOL_CTXT_ARGS(ctxt_pP));
gauthier's avatar
gauthier committed
97
98

#ifdef OAI_EMU
99

100
  CHECK_CTXT_ARGS(ctxt_pP)
101

gauthier's avatar
gauthier committed
102
#endif
103

104
  if (srb2add_listP != NULL) {
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    for (cnt=0; cnt<srb2add_listP->list.count; cnt++) {
      rb_id = srb2add_listP->list.array[cnt]->srb_Identity;
      lc_id  = rb_id + 2;

      LOG_D(RLC, "Adding SRB %d, rb_id %d\n",srb2add_listP->list.array[cnt]->srb_Identity,rb_id);
      srb_toaddmod_p = srb2add_listP->list.array[cnt];

      if (srb_toaddmod_p->rlc_Config) {
        switch (srb_toaddmod_p->rlc_Config->present) {
        case SRB_ToAddMod__rlc_Config_PR_NOTHING:
          break;

        case SRB_ToAddMod__rlc_Config_PR_explicitValue:
          switch (srb_toaddmod_p->rlc_Config->choice.explicitValue.present) {
          case RLC_Config_PR_NOTHING:
            break;

          case RLC_Config_PR_am:
            if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM) != NULL) {
              config_req_rlc_am_asn1 (
                ctxt_pP,
                SRB_FLAG_YES,
                &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am,
                rb_id);
            } else {
130
131
              LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                    PROTOCOL_CTXT_ARGS(ctxt_pP),
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
                    rb_id);
            }

            break;

          case RLC_Config_PR_um_Bi_Directional:
            if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) {
              config_req_rlc_um_asn1(
                ctxt_pP,
                SRB_FLAG_YES,
                MBMS_FLAG_NO,
                UNUSED_PARAM_MBMS_SESSION_ID,
                UNUSED_PARAM_MBMS_SERVICE_ID,
                &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.ul_UM_RLC,
                &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.dl_UM_RLC,
                rb_id);
            } else {
149
150
              LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                    PROTOCOL_CTXT_ARGS(ctxt_pP),
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
                    rb_id);
            }

            break;

          case RLC_Config_PR_um_Uni_Directional_UL:
            if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) {
              config_req_rlc_um_asn1(
                ctxt_pP,
                SRB_FLAG_YES,
                MBMS_FLAG_NO,
                UNUSED_PARAM_MBMS_SESSION_ID,
                UNUSED_PARAM_MBMS_SERVICE_ID,
                &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_UL.ul_UM_RLC,
                NULL,
                rb_id);
            } else {
168
169
              LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                    PROTOCOL_CTXT_ARGS(ctxt_pP),
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
                    rb_id);
            }

            break;

          case RLC_Config_PR_um_Uni_Directional_DL:
            if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) {
              config_req_rlc_um_asn1(
                ctxt_pP,
                SRB_FLAG_YES,
                MBMS_FLAG_NO,
                UNUSED_PARAM_MBMS_SESSION_ID,
                UNUSED_PARAM_MBMS_SERVICE_ID,
                NULL,
                &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_DL.dl_UM_RLC,
                rb_id);
            } else {
187
188
              LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                    PROTOCOL_CTXT_ARGS(ctxt_pP),
189
190
191
192
193
194
                    rb_id);
            }

            break;

          default:
195
196
            LOG_E(RLC, PROTOCOL_CTXT_FMT" UNKNOWN RLC CONFIG %d \n",
                  PROTOCOL_CTXT_ARGS(ctxt_pP),
197
198
199
200
201
202
203
                  srb_toaddmod_p->rlc_Config->choice.explicitValue.present);
            break;
          }

          break;

        case SRB_ToAddMod__rlc_Config_PR_defaultValue:
204
//#warning TO DO SRB_ToAddMod__rlc_Config_PR_defaultValue
205
206
207
208
209
210
211
212
213
214
215
          if (rrc_rlc_add_rlc   (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) {
            config_req_rlc_um_asn1(
              ctxt_pP,
              SRB_FLAG_YES,
              MBMS_FLAG_NO,
              UNUSED_PARAM_MBMS_SESSION_ID,
              UNUSED_PARAM_MBMS_SERVICE_ID,
              NULL, // TO DO DEFAULT CONFIG
              NULL, // TO DO DEFAULT CONFIG
              rb_id);
          } else {
216
217
            LOG_D(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                  PROTOCOL_CTXT_ARGS(ctxt_pP),
218
                  rb_id);
219
          }
220
221
222
223
224
225

          break;

        default:
          ;
        }
226
      }
227
    }
228
  }
229

230
  if (drb2add_listP != NULL) {
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    for (cnt=0; cnt<drb2add_listP->list.count; cnt++) {
      drb_toaddmod_p = drb2add_listP->list.array[cnt];

      drb_id = drb_toaddmod_p->drb_Identity;
      lc_id  = drb_id + 2;

      LOG_D(RLC, "Adding DRB %d, lc_id %d\n",drb_id,lc_id);


      if (drb_toaddmod_p->rlc_Config) {

        switch (drb_toaddmod_p->rlc_Config->present) {
        case RLC_Config_PR_NOTHING:
          break;

        case RLC_Config_PR_am:
          if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_AM) != NULL) {
            config_req_rlc_am_asn1 (
              ctxt_pP,
              SRB_FLAG_NO,
              &drb_toaddmod_p->rlc_Config->choice.am,
              drb_id);
          }

          break;

        case RLC_Config_PR_um_Bi_Directional:
          if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) {
            config_req_rlc_um_asn1(
              ctxt_pP,
              SRB_FLAG_NO,
              MBMS_FLAG_NO,
              UNUSED_PARAM_MBMS_SESSION_ID,
              UNUSED_PARAM_MBMS_SERVICE_ID,
              &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.ul_UM_RLC,
              &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.dl_UM_RLC,
              drb_id);
          }

          break;

        case RLC_Config_PR_um_Uni_Directional_UL:
          if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) {
            config_req_rlc_um_asn1(
              ctxt_pP,
              SRB_FLAG_NO,
              MBMS_FLAG_NO,
              UNUSED_PARAM_MBMS_SESSION_ID,
              UNUSED_PARAM_MBMS_SERVICE_ID,
              &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_UL.ul_UM_RLC,
              NULL,
              drb_id);
          }

          break;

        case RLC_Config_PR_um_Uni_Directional_DL:
          if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) {
            config_req_rlc_um_asn1(
              ctxt_pP,
              SRB_FLAG_NO,
              MBMS_FLAG_NO,
              UNUSED_PARAM_MBMS_SESSION_ID,
              UNUSED_PARAM_MBMS_SERVICE_ID,
              NULL,
              &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_DL.dl_UM_RLC,
              drb_id);
298
          }
299
300
301
302

          break;

        default:
303
304
          LOG_W(RLC, PROTOCOL_CTXT_FMT"[RB %u] unknown drb_toaddmod_p->rlc_Config->present \n",
                PROTOCOL_CTXT_ARGS(ctxt_pP),
305
306
                drb_id);
        }
307
      }
308
    }
309
  }
310

311
  if (drb2release_listP != NULL) {
312
313
314
315
316
317
318
319
    for (cnt=0; cnt<drb2release_listP->list.count; cnt++) {
      pdrb_id = drb2release_listP->list.array[cnt];
      rrc_rlc_remove_rlc(
        ctxt_pP,
        SRB_FLAG_NO,
        MBMS_FLAG_NO,
        *pdrb_id);
    }
320
321
  }

gauthier's avatar
gauthier committed
322
#if defined(Rel10)
gauthier's avatar
gauthier committed
323

gauthier's avatar
gauthier committed
324
  if (pmch_InfoList_r9_pP != NULL) {
325
326
327
328
329
330
331
332
333
334
335
336
    for (i=0; i<pmch_InfoList_r9_pP->list.count; i++) {
      mbms_SessionInfoList_r9_p = &(pmch_InfoList_r9_pP->list.array[i]->mbms_SessionInfoList_r9);

      for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) {
        MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j];
        mbms_session_id    = MBMS_SessionInfo_p->sessionId_r9->buf[0];
        lc_id              = mbms_session_id;
        mbms_service_id    = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string

        // can set the mch_id = i
        if (ctxt_pP->enb_flag) {
          rb_id =  (mbms_service_id * maxSessionPerPMCH ) + mbms_session_id;//+ (maxDRB + 3) * MAX_MOBILES_PER_ENB; // 1
337
338
339
          rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lc_id].service_id                     = mbms_service_id;
          rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lc_id].session_id                     = mbms_session_id;
          rlc_mbms_enb_set_lcid_by_rb_id(ctxt_pP->module_id,rb_id,lc_id);
340
341
342

        } else {
          rb_id =  (mbms_service_id * maxSessionPerPMCH ) + mbms_session_id; // + (maxDRB + 3); // 15
343
344
345
          rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lc_id].service_id                    = mbms_service_id;
          rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lc_id].session_id                    = mbms_session_id;
          rlc_mbms_ue_set_lcid_by_rb_id(ctxt_pP->module_id,rb_id,lc_id);
346
347
        }

348
        key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->module_id, ctxt_pP->enb_flag, mbms_service_id, mbms_session_id);
349
350
351
352
353
354
355
356
357
358
359
360
361
362

        h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);

        if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) {
          rlc_union_p = rrc_rlc_add_rlc   (
                          ctxt_pP,
                          SRB_FLAG_NO,
                          MBMS_FLAG_YES,
                          rb_id,
                          lc_id,
                          RLC_MODE_UM);
          AssertFatal(rlc_union_p != NULL, "ADD MBMS RLC UM FAILED");
        }

363
364
        LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n",
              PROTOCOL_CTXT_ARGS(ctxt_pP),
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
              lc_id,
              rb_id,
              mbms_session_id,
              mbms_service_id
             );
        dl_um_rlc.sn_FieldLength = SN_FieldLength_size5;
        dl_um_rlc.t_Reordering   = T_Reordering_ms0;

        config_req_rlc_um_asn1 (
          ctxt_pP,
          SRB_FLAG_NO,
          MBMS_FLAG_YES,
          mbms_session_id,
          mbms_service_id,
          NULL,
          &dl_um_rlc,
          rb_id);
382
      }
383
    }
384
  }
385

386
#endif
387

388
389
  LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ ASN1 END \n",
        PROTOCOL_CTXT_ARGS(ctxt_pP));
390
391
392
  return RLC_OP_STATUS_OK;
}
//-----------------------------------------------------------------------------
393
void
394
rb_free_rlc_union (
395
  void *rlcu_pP)
396
{
397
  //-----------------------------------------------------------------------------
398
  rlc_union_t * rlcu_p;
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

  if (rlcu_pP) {
    rlcu_p = (rlc_union_t *)(rlcu_pP);
    LOG_D(RLC,"%s %p \n",__FUNCTION__,rlcu_pP);

    switch (rlcu_p->mode) {
    case RLC_MODE_AM:
      rlc_am_cleanup(&rlcu_p->rlc.am);
      break;

    case RLC_MODE_UM:
      rlc_um_cleanup(&rlcu_p->rlc.um);
      break;

    case RLC_MODE_TM:
      rlc_tm_cleanup(&rlcu_p->rlc.tm);
      break;

    default:
      LOG_W(RLC,
            "%s %p unknown RLC type\n",
            __FUNCTION__,
            rlcu_pP);
      break;
423
    }
424
  }
425
}
426

gauthier's avatar
   
gauthier committed
427
428
//-----------------------------------------------------------------------------
rlc_op_status_t rrc_rlc_remove_ue (
429
430
431
432
  const protocol_ctxt_t* const ctxt_pP)
{
  //-----------------------------------------------------------------------------
  rb_id_t                rb_id;
gauthier's avatar
   
gauthier committed
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
  for (rb_id = 1; rb_id <= 2; rb_id++) {
    rrc_rlc_remove_rlc(ctxt_pP,
                       SRB_FLAG_YES,
                       MBMS_FLAG_NO,
                       rb_id);
  }

  for (rb_id = 1; rb_id <= maxDRB; rb_id++) {
    rrc_rlc_remove_rlc(ctxt_pP,
                       SRB_FLAG_NO,
                       MBMS_FLAG_NO,
                       rb_id);
  }

  return RLC_OP_STATUS_OK;
gauthier's avatar
   
gauthier committed
449
450
}

451
//-----------------------------------------------------------------------------
452
rlc_op_status_t rrc_rlc_remove_rlc   (
453
454
455
456
457
458
459
  const protocol_ctxt_t* const ctxt_pP,
  const srb_flag_t  srb_flagP,
  const MBMS_flag_t MBMS_flagP,
  const rb_id_t     rb_idP)
{
  //-----------------------------------------------------------------------------
  logical_chan_id_t      lcid            = 0;
460
  hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
461
462
  hashtable_rc_t         h_rc;
  rlc_union_t           *rlc_union_p = NULL;
463
#ifdef Rel10
464
  rlc_mbms_id_t         *mbms_id_p  = NULL;
465
#endif
gauthier's avatar
gauthier committed
466
#ifdef OAI_EMU
467
  CHECK_CTXT_ARGS(ctxt_pP)
468

gauthier's avatar
gauthier committed
469
#endif
470

Cedric Roux's avatar
Cedric Roux committed
471
472
473
  /* for no gcc warnings */
  (void)lcid;

474
#ifdef Rel10
475

476
  if (MBMS_flagP == TRUE) {
477
    if (ctxt_pP->enb_flag) {
478
479
480
481
482
      lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP);
      mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid];
      rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0;
      rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0;
      rlc_mbms_rbid2lcid_ue[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED;
483
484

    } else {
485
486
487
488
489
      lcid = rlc_mbms_ue_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP);
      mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lcid];
      rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0;
      rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0;
      rlc_mbms_rbid2lcid_ue[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED;
490
491
    }

492
    key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id);
493
494
495
  } else
#endif
  {
496
    key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
497
498
499
  }


500
  AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
501

502
  h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
503

504
505
  if (h_rc == HASH_TABLE_OK) {
    h_rc = hashtable_remove(rlc_coll_p, key);
506
507
    LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASED %s\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
508
509
510
511
          (srb_flagP) ? "SRB" : "DRB",
          rb_idP,
          (srb_flagP) ? "SRB" : "DRB");
  } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) {
512
513
    LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASE : RLC NOT FOUND %s\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
514
515
516
517
          (srb_flagP) ? "SRB" : "DRB",
          rb_idP,
          (srb_flagP) ? "SRB" : "DRB");
  } else {
518
519
    LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASE : INTERNAL ERROR %s\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
520
521
522
523
524
525
          (srb_flagP) ? "SRB" : "DRB",
          rb_idP,
          (srb_flagP) ? "SRB" : "DRB");
  }

  return RLC_OP_STATUS_OK;
526
527
}
//-----------------------------------------------------------------------------
528
rlc_union_t* rrc_rlc_add_rlc   (
529
530
531
532
533
534
535
536
  const protocol_ctxt_t* const ctxt_pP,
  const srb_flag_t        srb_flagP,
  const MBMS_flag_t       MBMS_flagP,
  const rb_id_t           rb_idP,
  const logical_chan_id_t chan_idP,
  const rlc_mode_t        rlc_modeP)
{
  //-----------------------------------------------------------------------------
537
  hash_key_t             key         = HASHTABLE_NOT_A_KEY_VALUE;
538
539
540
  hashtable_rc_t         h_rc;
  rlc_union_t           *rlc_union_p = NULL;
#ifdef Rel10
541
542
  rlc_mbms_id_t         *mbms_id_p  = NULL;
  logical_chan_id_t      lcid            = 0;
543
#endif
544

gauthier's avatar
gauthier committed
545
#ifdef OAI_EMU
546

547
  CHECK_CTXT_ARGS(ctxt_pP)
548

gauthier's avatar
gauthier committed
549
#endif
550
551
552
553
554

  if (MBMS_flagP == FALSE) {
    AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
    AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC);
  }
gauthier's avatar
gauthier committed
555

556
#ifdef Rel10
557

558
  if (MBMS_flagP == TRUE) {
559
    if (ctxt_pP->enb_flag) {
560
561
562
563
564
      lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP);
      mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid];
      //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0;
      //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0;
      //LG 2014-04-15rlc_mbms_rbid2lcid_eNB[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED;
565
566

    } else {
567
568
569
570
571
      lcid = rlc_mbms_ue_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP);
      mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lcid];
      //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0;
      //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0;
      //LG 2014-04-15rlc_mbms_rbid2lcid_ue[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED;
572
573
    }

574
    key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id);
575
576
577
  } else
#endif
  {
578
    key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
579
580
581
  }

  h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
582

583
  if (h_rc == HASH_TABLE_OK) {
584
585
    LOG_W(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , already exist %s\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
586
587
588
          (srb_flagP) ? "SRB" : "DRB",
          rb_idP,
          (srb_flagP) ? "SRB" : "DRB");
589
590
    AssertFatal(rlc_union_p->mode == rlc_modeP, "Error rrc_rlc_add_rlc , already exist but RLC mode differ");
    return rlc_union_p;
591
  } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) {
592
593
594
595
    rlc_union_p = calloc(1, sizeof(rlc_union_t));
    h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p);

    if (h_rc == HASH_TABLE_OK) {
gauthier's avatar
gauthier committed
596
#ifdef Rel10
597
598

      if (MBMS_flagP == TRUE) {
599
600
        LOG_I(RLC, PROTOCOL_CTXT_FMT" RLC service id %u session id %u rrc_rlc_add_rlc\n",
              PROTOCOL_CTXT_ARGS(ctxt_pP),
601
602
603
              mbms_id_p->service_id,
              mbms_id_p->session_id);
      } else
gauthier's avatar
gauthier committed
604
#endif
605
      {
606
607
        LOG_I(RLC, PROTOCOL_CTXT_FMT" [%s %u] rrc_rlc_add_rlc  %s\n",
              PROTOCOL_CTXT_ARGS(ctxt_pP),
608
609
610
611
              (srb_flagP) ? "SRB" : "DRB",
              rb_idP,
              (srb_flagP) ? "SRB" : "DRB");
      }
612
613
614
615

      rlc_union_p->mode = rlc_modeP;
      return rlc_union_p;
    } else {
616
617
      LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc  FAILED %s\n",
            PROTOCOL_CTXT_ARGS(ctxt_pP),
618
619
620
621
622
623
624
            (srb_flagP) ? "SRB" : "DRB",
            rb_idP,
            (srb_flagP) ? "SRB" : "DRB");
      free(rlc_union_p);
      rlc_union_p = NULL;
      return NULL;
    }
625
  } else {
626
627
    LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , INTERNAL ERROR %s\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
628
629
630
631
          (srb_flagP) ? "SRB" : "DRB",
          rb_idP,
          (srb_flagP) ? "SRB" : "DRB");
  }
632

633
  return NULL;
634
635
}
//-----------------------------------------------------------------------------
636
rlc_op_status_t rrc_rlc_config_req   (
637
638
639
640
641
642
643
644
  const protocol_ctxt_t* const ctxt_pP,
  const srb_flag_t      srb_flagP,
  const MBMS_flag_t     mbms_flagP,
  const config_action_t actionP,
  const rb_id_t         rb_idP,
  const rlc_info_t      rlc_infoP)
{
  //-----------------------------------------------------------------------------
645
  //rlc_op_status_t status;
646

647
648
  LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG_REQ for RAB %u\n",
        PROTOCOL_CTXT_ARGS(ctxt_pP),
649
650
651
        rb_idP);

#ifdef OAI_EMU
652

653
  CHECK_CTXT_ARGS(ctxt_pP)
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

#endif
  AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);

  switch (actionP) {

  case CONFIG_ACTION_ADD:
    if (rrc_rlc_add_rlc(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, rb_idP, rlc_infoP.rlc_mode) != NULL) {
      return RLC_OP_STATUS_INTERNAL_ERROR;
    }

    // no break, fall to next case
  case CONFIG_ACTION_MODIFY:
    switch (rlc_infoP.rlc_mode) {
    case RLC_MODE_AM:
669
670
      LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB AM\n",
            PROTOCOL_CTXT_ARGS(ctxt_pP),
gauthier's avatar
gauthier committed
671
672
            rb_idP);

673
674
675
676
677
678
679
680
      config_req_rlc_am(
        ctxt_pP,
        srb_flagP,
        &rlc_infoP.rlc.rlc_am_info,
        rb_idP);
      break;

    case RLC_MODE_UM:
681
682
      LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB UM\n",
            PROTOCOL_CTXT_ARGS(ctxt_pP),
683
684
685
686
687
688
689
690
691
            rb_idP);
      config_req_rlc_um(
        ctxt_pP,
        srb_flagP,
        &rlc_infoP.rlc.rlc_um_info,
        rb_idP);
      break;

    case RLC_MODE_TM:
692
693
      LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB TM\n",
            PROTOCOL_CTXT_ARGS(ctxt_pP),
694
695
696
697
698
699
700
701
702
703
            rb_idP);
      config_req_rlc_tm(
        ctxt_pP,
        srb_flagP,
        &rlc_infoP.rlc.rlc_tm_info,
        rb_idP);
      break;

    default:
      return RLC_OP_STATUS_BAD_PARAMETER;
gauthier's avatar
gauthier committed
704
    }
705

706
    break;
707

708
709
710
  case CONFIG_ACTION_REMOVE:
    return rrc_rlc_remove_rlc(ctxt_pP, srb_flagP, mbms_flagP, rb_idP);
    break;
711

712
713
714
715
716
  default:
    return RLC_OP_STATUS_BAD_PARAMETER;
  }

  return RLC_OP_STATUS_OK;
717
718
}
//-----------------------------------------------------------------------------
719
rlc_op_status_t rrc_rlc_data_req     (
720
721
722
723
724
725
726
727
728
  const protocol_ctxt_t* const ctxt_pP,
  const MBMS_flag_t MBMS_flagP,
  const rb_id_t     rb_idP,
  const mui_t       muiP,
  const confirm_t   confirmP,
  const sdu_size_t  sdu_sizeP,
  char* sduP)
{
  //-----------------------------------------------------------------------------
729
730
731
  mem_block_t*   sdu;

  sdu = get_free_mem_block(sdu_sizeP);
732

733
734
  if (sdu != NULL) {
    memcpy (sdu->data, sduP, sdu_sizeP);
735
    return rlc_data_req(ctxt_pP, SRB_FLAG_YES, MBMS_flagP, rb_idP, muiP, confirmP, sdu_sizeP, sdu);
736
737
738
739
740
741
  } else {
    return RLC_OP_STATUS_INTERNAL_ERROR;
  }
}

//-----------------------------------------------------------------------------
742
743
744
745
746
void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t rrc_data_confP)
{
  //-----------------------------------------------------------------------------
  rlc_rrc_data_ind  = rrc_data_indP;
  rlc_rrc_data_conf = rrc_data_confP;
747
748
}