769 lines
26 KiB
C
769 lines
26 KiB
C
/*******************************************************************************
|
|
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
|
|
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
|
|
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
|
|
|
*******************************************************************************/
|
|
/*
|
|
rlc.c
|
|
-------------------
|
|
AUTHOR : Lionel GAUTHIER
|
|
COMPANY : EURECOM
|
|
EMAIL : Lionel.Gauthier at eurecom dot fr
|
|
*/
|
|
#define RLC_C
|
|
#include "rlc.h"
|
|
#include "mem_block.h"
|
|
#include "../MAC/extern.h"
|
|
#include "UTIL/LOG/log.h"
|
|
#include "UTIL/OCG/OCG_vars.h"
|
|
#include "UTIL/LOG/vcd_signal_dumper.h"
|
|
|
|
#include "assertions.h"
|
|
|
|
|
|
|
|
// PROTO AGENT
|
|
void
|
|
async_server_thread_init (void)
|
|
{
|
|
//create log_list
|
|
//log_list_init(&log_list);
|
|
|
|
async_server_shutdown = 0;
|
|
|
|
if ((pthread_mutex_init (&async_server_lock, NULL) != 0)
|
|
|| (pthread_cond_init (&async_server_notify, NULL) != 0)) {
|
|
return;
|
|
}
|
|
|
|
if (pthread_create (&async_server_thread, NULL, proto_server_init, (void*) NULL)
|
|
!= 0) {
|
|
async_server_thread_finalize();
|
|
return;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
async_server_thread_finalize (void)
|
|
{
|
|
int err = 0;
|
|
|
|
|
|
if (pthread_mutex_lock (&async_server_lock) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
async_server_shutdown = 1;
|
|
|
|
/* Wake up LOG thread */
|
|
if ((pthread_cond_broadcast (&async_server_notify) != 0)
|
|
|| (pthread_mutex_unlock (&async_server_lock) != 0)) {
|
|
err = -1;
|
|
}
|
|
|
|
if (pthread_join (async_server_thread, NULL) != 0) {
|
|
err = -1;
|
|
}
|
|
|
|
if (pthread_mutex_unlock (&async_server_lock) != 0) {
|
|
err = -1;
|
|
}
|
|
|
|
if (!err) {
|
|
//log_list_free(&log_list);
|
|
pthread_mutex_lock (&async_server_lock);
|
|
pthread_mutex_destroy (&async_server_lock);
|
|
pthread_cond_destroy (&async_server_notify);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern boolean_t pdcp_data_ind(
|
|
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 sdu_size_t sdu_buffer_sizeP,
|
|
mem_block_t* const sdu_buffer_pP);
|
|
|
|
#define DEBUG_RLC_PDCP_INTERFACE 1
|
|
//#define TRACE_RLC_PAYLOAD 1
|
|
#define DEBUG_RLC_DATA_REQ 1
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, const signed long sizeP)
|
|
//-----------------------------------------------------------------------------
|
|
{
|
|
unsigned long octet_index = 0;
|
|
|
|
if (dataP == NULL) {
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
LOG_T(componentP, "+-----+-------------------------------------------------+\n");
|
|
LOG_T(componentP, "| | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n");
|
|
LOG_T(componentP, "+-----+-------------------------------------------------+\n");
|
|
|
|
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
|
if ((octet_index % 16) == 0) {
|
|
if (octet_index != 0) {
|
|
LOG_T(componentP, " |\n");
|
|
}
|
|
|
|
LOG_T(componentP, " %04d |", octet_index);
|
|
}
|
|
|
|
/*
|
|
* Print every single octet in hexadecimal form
|
|
*/
|
|
LOG_T(componentP, " %02x", dataP[octet_index]);
|
|
/*
|
|
* Align newline and pipes according to the octets in groups of 2
|
|
*/
|
|
}
|
|
|
|
/*
|
|
* Append enough spaces and put final pipe
|
|
*/
|
|
unsigned char index;
|
|
|
|
for (index = octet_index; index < 16; ++index) {
|
|
LOG_T(componentP, " ");
|
|
}
|
|
|
|
LOG_T(componentP, " |\n");
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
rlc_op_status_t rlc_stat_req (
|
|
const protocol_ctxt_t* const ctxt_pP,
|
|
const srb_flag_t srb_flagP,
|
|
const rb_id_t rb_idP,
|
|
unsigned int* stat_rlc_mode,
|
|
unsigned int* stat_tx_pdcp_sdu,
|
|
unsigned int* stat_tx_pdcp_bytes,
|
|
unsigned int* stat_tx_pdcp_sdu_discarded,
|
|
unsigned int* stat_tx_pdcp_bytes_discarded,
|
|
unsigned int* stat_tx_data_pdu,
|
|
unsigned int* stat_tx_data_bytes,
|
|
unsigned int* stat_tx_retransmit_pdu_by_status,
|
|
unsigned int* stat_tx_retransmit_bytes_by_status,
|
|
unsigned int* stat_tx_retransmit_pdu,
|
|
unsigned int* stat_tx_retransmit_bytes,
|
|
unsigned int* stat_tx_control_pdu,
|
|
unsigned int* stat_tx_control_bytes,
|
|
unsigned int* stat_rx_pdcp_sdu,
|
|
unsigned int* stat_rx_pdcp_bytes,
|
|
unsigned int* stat_rx_data_pdus_duplicate,
|
|
unsigned int* stat_rx_data_bytes_duplicate,
|
|
unsigned int* stat_rx_data_pdu,
|
|
unsigned int* stat_rx_data_bytes,
|
|
unsigned int* stat_rx_data_pdu_dropped,
|
|
unsigned int* stat_rx_data_bytes_dropped,
|
|
unsigned int* stat_rx_data_pdu_out_of_window,
|
|
unsigned int* stat_rx_data_bytes_out_of_window,
|
|
unsigned int* stat_rx_control_pdu,
|
|
unsigned int* stat_rx_control_bytes,
|
|
unsigned int* stat_timer_reordering_timed_out,
|
|
unsigned int* stat_timer_poll_retransmit_timed_out,
|
|
unsigned int* stat_timer_status_prohibit_timed_out)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
rlc_mode_t rlc_mode = RLC_MODE_NONE;
|
|
rlc_union_t *rlc_union_p = NULL;
|
|
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
|
|
hashtable_rc_t h_rc;
|
|
|
|
#ifdef OAI_EMU
|
|
|
|
CHECK_CTXT_ARGS(ctxt_pP)
|
|
|
|
#endif
|
|
AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
|
|
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
|
|
h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
|
|
|
|
if (h_rc == HASH_TABLE_OK) {
|
|
rlc_mode = rlc_union_p->mode;
|
|
}
|
|
*stat_rlc_mode = rlc_mode;
|
|
switch (rlc_mode) {
|
|
case RLC_MODE_NONE:
|
|
*stat_tx_pdcp_sdu = 0;
|
|
*stat_tx_pdcp_bytes = 0;
|
|
*stat_tx_pdcp_sdu_discarded = 0;
|
|
*stat_tx_pdcp_bytes_discarded = 0;
|
|
*stat_tx_data_pdu = 0;
|
|
*stat_tx_data_bytes = 0;
|
|
*stat_tx_retransmit_pdu_by_status = 0;
|
|
*stat_tx_retransmit_bytes_by_status = 0;
|
|
*stat_tx_retransmit_pdu = 0;
|
|
*stat_tx_retransmit_bytes = 0;
|
|
*stat_tx_control_pdu = 0;
|
|
*stat_tx_control_bytes = 0;
|
|
*stat_rx_pdcp_sdu = 0;
|
|
*stat_rx_pdcp_bytes = 0;
|
|
*stat_rx_data_pdus_duplicate = 0;
|
|
*stat_rx_data_bytes_duplicate = 0;
|
|
*stat_rx_data_pdu = 0;
|
|
*stat_rx_data_bytes = 0;
|
|
*stat_rx_data_pdu_dropped = 0;
|
|
*stat_rx_data_bytes_dropped = 0;
|
|
*stat_rx_data_pdu_out_of_window = 0;
|
|
*stat_rx_data_bytes_out_of_window = 0;
|
|
*stat_rx_control_pdu = 0;
|
|
*stat_rx_control_bytes = 0;
|
|
*stat_timer_reordering_timed_out = 0;
|
|
*stat_timer_poll_retransmit_timed_out = 0;
|
|
*stat_timer_status_prohibit_timed_out = 0;
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
break;
|
|
|
|
case RLC_MODE_AM:
|
|
rlc_am_stat_req(ctxt_pP,
|
|
&rlc_union_p->rlc.am,
|
|
stat_tx_pdcp_sdu,
|
|
stat_tx_pdcp_bytes,
|
|
stat_tx_pdcp_sdu_discarded,
|
|
stat_tx_pdcp_bytes_discarded,
|
|
stat_tx_data_pdu,
|
|
stat_tx_data_bytes,
|
|
stat_tx_retransmit_pdu_by_status,
|
|
stat_tx_retransmit_bytes_by_status,
|
|
stat_tx_retransmit_pdu,
|
|
stat_tx_retransmit_bytes,
|
|
stat_tx_control_pdu,
|
|
stat_tx_control_bytes,
|
|
stat_rx_pdcp_sdu,
|
|
stat_rx_pdcp_bytes,
|
|
stat_rx_data_pdus_duplicate,
|
|
stat_rx_data_bytes_duplicate,
|
|
stat_rx_data_pdu,
|
|
stat_rx_data_bytes,
|
|
stat_rx_data_pdu_dropped,
|
|
stat_rx_data_bytes_dropped,
|
|
stat_rx_data_pdu_out_of_window,
|
|
stat_rx_data_bytes_out_of_window,
|
|
stat_rx_control_pdu,
|
|
stat_rx_control_bytes,
|
|
stat_timer_reordering_timed_out,
|
|
stat_timer_poll_retransmit_timed_out,
|
|
stat_timer_status_prohibit_timed_out);
|
|
return RLC_OP_STATUS_OK;
|
|
break;
|
|
|
|
case RLC_MODE_UM:
|
|
*stat_tx_retransmit_pdu_by_status = 0;
|
|
*stat_tx_retransmit_bytes_by_status = 0;
|
|
*stat_tx_retransmit_pdu = 0;
|
|
*stat_tx_retransmit_bytes = 0;
|
|
*stat_tx_control_pdu = 0;
|
|
*stat_tx_control_bytes = 0;
|
|
*stat_rx_data_pdu_dropped = 0;
|
|
*stat_rx_data_bytes_dropped = 0;
|
|
*stat_rx_data_pdu_out_of_window = 0;
|
|
*stat_rx_data_bytes_out_of_window = 0;
|
|
*stat_timer_poll_retransmit_timed_out = 0;
|
|
*stat_timer_status_prohibit_timed_out = 0;
|
|
rlc_um_stat_req (ctxt_pP,
|
|
&rlc_union_p->rlc.um,
|
|
stat_tx_pdcp_sdu,
|
|
stat_tx_pdcp_bytes,
|
|
stat_tx_pdcp_sdu_discarded,
|
|
stat_tx_pdcp_bytes_discarded,
|
|
stat_tx_data_pdu,
|
|
stat_tx_data_bytes,
|
|
stat_rx_pdcp_sdu,
|
|
stat_rx_pdcp_bytes,
|
|
stat_rx_data_pdus_duplicate,
|
|
stat_rx_data_bytes_duplicate,
|
|
stat_rx_data_pdu,
|
|
stat_rx_data_bytes,
|
|
stat_rx_data_pdu_dropped,
|
|
stat_rx_data_bytes_dropped,
|
|
stat_rx_data_pdu_out_of_window,
|
|
stat_rx_data_bytes_out_of_window,
|
|
stat_timer_reordering_timed_out);
|
|
return RLC_OP_STATUS_OK;
|
|
break;
|
|
|
|
case RLC_MODE_TM:
|
|
*stat_tx_pdcp_sdu = 0;
|
|
*stat_tx_pdcp_bytes = 0;
|
|
*stat_tx_pdcp_sdu_discarded = 0;
|
|
*stat_tx_pdcp_bytes_discarded = 0;
|
|
*stat_tx_data_pdu = 0;
|
|
*stat_tx_data_bytes = 0;
|
|
*stat_tx_retransmit_pdu_by_status = 0;
|
|
*stat_tx_retransmit_bytes_by_status = 0;
|
|
*stat_tx_retransmit_pdu = 0;
|
|
*stat_tx_retransmit_bytes = 0;
|
|
*stat_tx_control_pdu = 0;
|
|
*stat_tx_control_bytes = 0;
|
|
*stat_rx_pdcp_sdu = 0;
|
|
*stat_rx_pdcp_bytes = 0;
|
|
*stat_rx_data_pdus_duplicate = 0;
|
|
*stat_rx_data_bytes_duplicate = 0;
|
|
*stat_rx_data_pdu = 0;
|
|
*stat_rx_data_bytes = 0;
|
|
*stat_rx_data_pdu_dropped = 0;
|
|
*stat_rx_data_bytes_dropped = 0;
|
|
*stat_rx_data_pdu_out_of_window = 0;
|
|
*stat_rx_data_bytes_out_of_window = 0;
|
|
*stat_rx_control_pdu = 0;
|
|
*stat_rx_control_bytes = 0;
|
|
*stat_timer_reordering_timed_out = 0;
|
|
*stat_timer_poll_retransmit_timed_out = 0;
|
|
*stat_timer_status_prohibit_timed_out = 0;
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
break;
|
|
|
|
default:
|
|
*stat_tx_pdcp_sdu = 0;
|
|
*stat_tx_pdcp_bytes = 0;
|
|
*stat_tx_pdcp_sdu_discarded = 0;
|
|
*stat_tx_pdcp_bytes_discarded = 0;
|
|
*stat_tx_data_pdu = 0;
|
|
*stat_tx_data_bytes = 0;
|
|
*stat_tx_retransmit_pdu_by_status = 0;
|
|
*stat_tx_retransmit_bytes_by_status = 0;
|
|
*stat_tx_retransmit_pdu = 0;
|
|
*stat_tx_retransmit_bytes = 0;
|
|
*stat_tx_control_pdu = 0;
|
|
*stat_tx_control_bytes = 0;
|
|
*stat_rx_pdcp_sdu = 0;
|
|
*stat_rx_pdcp_bytes = 0;
|
|
*stat_rx_data_pdus_duplicate = 0;
|
|
*stat_rx_data_bytes_duplicate = 0;
|
|
*stat_rx_data_pdu = 0;
|
|
*stat_rx_data_bytes = 0;
|
|
*stat_rx_data_pdu_dropped = 0;
|
|
*stat_rx_data_bytes_dropped = 0;
|
|
*stat_rx_data_pdu_out_of_window = 0;
|
|
*stat_rx_data_bytes_out_of_window = 0;
|
|
*stat_rx_control_pdu = 0;
|
|
*stat_rx_control_bytes = 0;
|
|
|
|
*stat_timer_poll_retransmit_timed_out = 0;
|
|
*stat_timer_status_prohibit_timed_out = 0;
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
rlc_op_status_t rlc_data_req (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 mui_t muiP,
|
|
confirm_t confirmP,
|
|
sdu_size_t sdu_sizeP,
|
|
mem_block_t *sdu_pP)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
mem_block_t *new_sdu_p = NULL;
|
|
rlc_mode_t rlc_mode = RLC_MODE_NONE;
|
|
rlc_union_t *rlc_union_p = NULL;
|
|
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
|
|
hashtable_rc_t h_rc;
|
|
|
|
#ifdef Rel10
|
|
rlc_mbms_id_t *mbms_id_p = NULL;
|
|
logical_chan_id_t log_ch_id = 0;
|
|
#endif
|
|
#ifdef DEBUG_RLC_DATA_REQ
|
|
LOG_D(RLC,PROTOCOL_CTXT_FMT"rlc_data_req: rb_id %u (MAX %d), muip %d, confirmP %d, sdu_sizeP %d, sdu_pP %p\n",
|
|
PROTOCOL_CTXT_ARGS(ctxt_pP),
|
|
rb_idP,
|
|
NB_RAB_MAX,
|
|
muiP,
|
|
confirmP,
|
|
sdu_sizeP,
|
|
sdu_pP);
|
|
#endif
|
|
#ifdef Rel10
|
|
#else
|
|
AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP);
|
|
#endif
|
|
#ifdef OAI_EMU
|
|
|
|
CHECK_CTXT_ARGS(ctxt_pP)
|
|
|
|
#endif
|
|
|
|
#if T_TRACER
|
|
if (ctxt_pP->enb_flag)
|
|
T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
|
|
#endif
|
|
|
|
if (MBMS_flagP) {
|
|
AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
|
|
} else {
|
|
AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
|
|
}
|
|
|
|
DevAssert(sdu_pP != NULL);
|
|
DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0);
|
|
|
|
#ifndef Rel10
|
|
DevCheck(MBMS_flagP == 0, MBMS_flagP, 0, 0);
|
|
#endif
|
|
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN);
|
|
|
|
#ifdef Rel10
|
|
|
|
if (MBMS_flagP == TRUE) {
|
|
if (ctxt_pP->enb_flag) {
|
|
log_ch_id = 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][log_ch_id];
|
|
} else {
|
|
log_ch_id = rlc_mbms_ue_get_lcid_by_rb_id(ctxt_pP->rnti,rb_idP);
|
|
mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[ctxt_pP->rnti][log_ch_id];
|
|
}
|
|
|
|
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);
|
|
} else
|
|
#endif
|
|
{
|
|
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
|
|
}
|
|
|
|
h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
|
|
|
|
if (h_rc == HASH_TABLE_OK) {
|
|
rlc_mode = rlc_union_p->mode;
|
|
} else {
|
|
rlc_mode = RLC_MODE_NONE;
|
|
AssertFatal (0 , "RLC not configured key %ju\n", key);
|
|
}
|
|
|
|
if (MBMS_flagP == 0) {
|
|
LOG_D(RLC, PROTOCOL_CTXT_FMT"[RB %u] Display of rlc_data_req:\n",
|
|
PROTOCOL_CTXT_ARGS(ctxt_pP),
|
|
rb_idP);
|
|
#if defined(TRACE_RLC_PAYLOAD)
|
|
rlc_util_print_hex_octets(RLC, (unsigned char*)sdu_pP->data, sdu_sizeP);
|
|
#endif
|
|
|
|
#ifdef DEBUG_RLC_DATA_REQ
|
|
LOG_D(RLC,"RLC_TYPE : %d\n", rlc_mode);
|
|
#endif
|
|
|
|
switch (rlc_mode) {
|
|
case RLC_MODE_NONE:
|
|
free_mem_block(sdu_pP);
|
|
LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %u\n",
|
|
PROTOCOL_CTXT_ARGS(ctxt_pP),
|
|
rb_idP);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
|
|
case RLC_MODE_AM:
|
|
#ifdef DEBUG_RLC_DATA_REQ
|
|
msg("RLC_MODE_AM\n");
|
|
#endif
|
|
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_am_data_req_alloc));
|
|
|
|
if (new_sdu_p != NULL) {
|
|
// PROCESS OF COMPRESSION HERE:
|
|
memset (new_sdu_p->data, 0, sizeof (struct rlc_am_data_req_alloc));
|
|
memcpy (&new_sdu_p->data[sizeof (struct rlc_am_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
|
|
|
|
((struct rlc_am_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
|
|
((struct rlc_am_data_req *) (new_sdu_p->data))->conf = confirmP;
|
|
((struct rlc_am_data_req *) (new_sdu_p->data))->mui = muiP;
|
|
((struct rlc_am_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_am_data_req_alloc);
|
|
free_mem_block(sdu_pP);
|
|
rlc_am_data_req(ctxt_pP, &rlc_union_p->rlc.am, new_sdu_p);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_OK;
|
|
} else {
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_INTERNAL_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
case RLC_MODE_UM:
|
|
|
|
//proto_server_receive();
|
|
|
|
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc));
|
|
|
|
if (new_sdu_p != NULL) {
|
|
// PROCESS OF COMPRESSION HERE:
|
|
memset (new_sdu_p->data, 0, sizeof (struct rlc_um_data_req_alloc));
|
|
memcpy (&new_sdu_p->data[sizeof (struct rlc_um_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
|
|
|
|
((struct rlc_um_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
|
|
((struct rlc_um_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_um_data_req_alloc);
|
|
free_mem_block(sdu_pP);
|
|
|
|
rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
|
|
|
|
//free_mem_block(new_sdu);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_OK;
|
|
} else {
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_INTERNAL_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
case RLC_MODE_TM:
|
|
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_tm_data_req_alloc));
|
|
|
|
if (new_sdu_p != NULL) {
|
|
// PROCESS OF COMPRESSION HERE:
|
|
memset (new_sdu_p->data, 0, sizeof (struct rlc_tm_data_req_alloc));
|
|
memcpy (&new_sdu_p->data[sizeof (struct rlc_tm_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
|
|
|
|
((struct rlc_tm_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
|
|
((struct rlc_tm_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_tm_data_req_alloc);
|
|
free_mem_block(sdu_pP);
|
|
rlc_tm_data_req(ctxt_pP, &rlc_union_p->rlc.tm, new_sdu_p);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_OK;
|
|
} else {
|
|
//handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : out of memory\n", __FILE__, __LINE__);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_INTERNAL_ERROR;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
free_mem_block(sdu_pP);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_INTERNAL_ERROR;
|
|
|
|
}
|
|
|
|
#ifdef Rel10
|
|
} else { /* MBMS_flag != 0 */
|
|
// LOG_I(RLC,"DUY rlc_data_req: mbms_rb_id in RLC instant is: %d\n", mbms_rb_id);
|
|
if (sdu_pP != NULL) {
|
|
if (sdu_sizeP > 0) {
|
|
LOG_I(RLC,"received a packet with size %d for MBMS \n", sdu_sizeP);
|
|
new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc));
|
|
|
|
if (new_sdu_p != NULL) {
|
|
// PROCESS OF COMPRESSION HERE:
|
|
memset (new_sdu_p->data, 0, sizeof (struct rlc_um_data_req_alloc));
|
|
memcpy (&new_sdu_p->data[sizeof (struct rlc_um_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
|
|
((struct rlc_um_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
|
|
((struct rlc_um_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_um_data_req_alloc);
|
|
free_mem_block(sdu_pP);
|
|
rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
|
|
|
|
//free_mem_block(new_sdu);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_OK;
|
|
} else {
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
}
|
|
} else {
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
}
|
|
} else {
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
}
|
|
}
|
|
|
|
#else
|
|
}
|
|
else /* MBMS_flag != 0 */
|
|
{
|
|
free_mem_block(sdu_pP);
|
|
LOG_E(RLC, "MBMS_flag != 0 while Rel10 is not defined...\n");
|
|
//handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : parameter module_id out of bounds :%d\n", __FILE__, __LINE__, module_idP);
|
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
|
|
return RLC_OP_STATUS_BAD_PARAMETER;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void rlc_data_ind (
|
|
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 sdu_size_t sdu_sizeP,
|
|
mem_block_t *sdu_pP)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
#if defined(TRACE_RLC_PAYLOAD)
|
|
LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n",
|
|
PROTOCOL_CTXT_ARGS(ctxt_pP),
|
|
(srb_flagP) ? "SRB" : "DRB",
|
|
rb_idP,
|
|
sdu_sizeP);
|
|
|
|
rlc_util_print_hex_octets(RLC, (unsigned char*)sdu_pP->data, sdu_sizeP);
|
|
#endif
|
|
|
|
#if T_TRACER
|
|
if (ctxt_pP->enb_flag)
|
|
T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
|
|
#endif
|
|
|
|
// if (!srb_flagP)
|
|
// {
|
|
proto_agent_send_pdcp_data_ind(ctxt_pP,
|
|
srb_flagP,
|
|
MBMS_flagP,
|
|
rb_idP,
|
|
sdu_sizeP,
|
|
sdu_pP);
|
|
// }
|
|
// else
|
|
// {
|
|
// pdcp_data_ind (
|
|
// ctxt_pP,
|
|
// srb_flagP,
|
|
// MBMS_flagP,
|
|
// rb_idP,
|
|
// sdu_sizeP,
|
|
// sdu_pP);
|
|
// }
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void rlc_data_conf (const protocol_ctxt_t* const ctxt_pP,
|
|
const srb_flag_t srb_flagP,
|
|
const rb_id_t rb_idP,
|
|
const mui_t muiP,
|
|
const rlc_tx_status_t statusP)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
|
|
if (srb_flagP) {
|
|
if (rlc_rrc_data_conf != NULL) {
|
|
rlc_rrc_data_conf (ctxt_pP, rb_idP , muiP, statusP);
|
|
}
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
int
|
|
rlc_module_init (void)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
int k;
|
|
module_id_t module_id1;
|
|
|
|
/* for no gcc warnings */
|
|
(void)k;
|
|
|
|
LOG_D(RLC, "MODULE INIT\n");
|
|
rlc_rrc_data_ind = NULL;
|
|
rlc_rrc_data_conf = NULL;
|
|
|
|
rlc_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, rb_free_rlc_union);
|
|
AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed");
|
|
|
|
for (module_id1=0; module_id1 < NUMBER_OF_UE_MAX; module_id1++) {
|
|
#if defined(Rel10)
|
|
|
|
for (k=0; k < RLC_MAX_MBMS_LC; k++) {
|
|
rlc_mbms_lcid2service_session_id_ue[module_id1][k].service_id = 0;
|
|
rlc_mbms_lcid2service_session_id_ue[module_id1][k].session_id = 0;
|
|
}
|
|
|
|
for (k=0; k < NB_RB_MBMS_MAX; k++) {
|
|
rlc_mbms_rbid2lcid_ue[module_id1][k] = RLC_LC_UNALLOCATED;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
for (module_id1=0; module_id1 < NUMBER_OF_eNB_MAX; module_id1++) {
|
|
#if defined(Rel10)
|
|
|
|
for (k=0; k < RLC_MAX_MBMS_LC; k++) {
|
|
rlc_mbms_lcid2service_session_id_eNB[module_id1][k].service_id = 0;
|
|
rlc_mbms_lcid2service_session_id_eNB[module_id1][k].session_id = 0;
|
|
}
|
|
|
|
for (k=0; k < NB_RB_MBMS_MAX; k++) {
|
|
rlc_mbms_rbid2lcid_eNB[module_id1][k] = RLC_LC_UNALLOCATED;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
pool_buffer_init();
|
|
|
|
/* Launch the RLC listening server
|
|
* as a separate thread
|
|
*/
|
|
async_server_thread_init();
|
|
|
|
|
|
return(0);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
rlc_module_cleanup (void)
|
|
//-----------------------------------------------------------------------------
|
|
{
|
|
hashtable_destroy(rlc_coll_p);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
rlc_layer_init (void)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
rlc_layer_cleanup (void)
|
|
//-----------------------------------------------------------------------------
|
|
{
|
|
}
|
|
|