Commit f147fa6e authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge remote-tracking branch 'origin/nr-rlc' into integration-develop-nr-2019w50

parents d046545b d2af44b7
......@@ -1473,15 +1473,8 @@ set(RRC_DIR ${OPENAIR2_DIR}/RRC/LTE)
set(NR_RRC_DIR ${OPENAIR2_DIR}/RRC/NR)
set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE)
set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0)
set(L2_SRC
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
${PDCP_DIR}/pdcp_primitives.c
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
set(LTE_RLC_SRC
${RLC_AM_DIR}/rlc_am.c
${RLC_AM_DIR}/rlc_am_init.c
${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
......@@ -1509,6 +1502,29 @@ set(L2_SRC
${RLC_DIR}/rlc.c
${RLC_DIR}/rlc_rrc.c
${RLC_DIR}/rlc_mpls.c
)
set(NR_RLC_SRC
${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_am.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_tm.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_um.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_oai_api.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_pdu.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c
)
set(L2_SRC
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
${PDCP_DIR}/pdcp_primitives.c
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_S1AP.c
......@@ -1519,7 +1535,12 @@ set(L2_SRC
${RRC_DIR}/L2_interface_ue.c
)
set(L2_LTE_SRC
${LTE_RLC_SRC}
)
set(L2_NR_SRC
${NR_RLC_SRC}
${NR_RRC_DIR}/rrc_gNB.c
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/L2_nr_interface.c
......@@ -1534,40 +1555,13 @@ set(L2_SRC_UE
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
${RLC_AM_DIR}/rlc_am.c
${RLC_AM_DIR}/rlc_am_init.c
${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
${RLC_AM_DIR}/rlc_am_timer_reordering.c
${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c
${RLC_AM_DIR}/rlc_am_segment.c
${RLC_AM_DIR}/rlc_am_segments_holes.c
${RLC_AM_DIR}/rlc_am_in_sdu.c
${RLC_AM_DIR}/rlc_am_receiver.c
${RLC_AM_DIR}/rlc_am_retransmit.c
${RLC_AM_DIR}/rlc_am_windows.c
${RLC_AM_DIR}/rlc_am_rx_list.c
${RLC_AM_DIR}/rlc_am_reassembly.c
${RLC_AM_DIR}/rlc_am_status_report.c
${RLC_TM_DIR}/rlc_tm.c
${RLC_TM_DIR}/rlc_tm_init.c
${RLC_UM_DIR}/rlc_um.c
${RLC_UM_DIR}/rlc_um_fsm.c
${RLC_UM_DIR}/rlc_um_control_primitives.c
${RLC_UM_DIR}/rlc_um_segment.c
${RLC_UM_DIR}/rlc_um_reassembly.c
${RLC_UM_DIR}/rlc_um_receiver.c
${RLC_UM_DIR}/rlc_um_dar.c
${RLC_DIR}/rlc_mac.c
${RLC_DIR}/rlc.c
${RLC_DIR}/rlc_rrc.c
${RLC_DIR}/rlc_mpls.c
${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set(LTE_NR_L2_SRC_UE
set(LTE_NR_L2_SRC_UE
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
......@@ -1575,37 +1569,11 @@ set(L2_SRC_UE
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
${RLC_AM_DIR}/rlc_am.c
${RLC_AM_DIR}/rlc_am_init.c
${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
${RLC_AM_DIR}/rlc_am_timer_reordering.c
${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c
${RLC_AM_DIR}/rlc_am_segment.c
${RLC_AM_DIR}/rlc_am_segments_holes.c
${RLC_AM_DIR}/rlc_am_in_sdu.c
${RLC_AM_DIR}/rlc_am_receiver.c
${RLC_AM_DIR}/rlc_am_retransmit.c
${RLC_AM_DIR}/rlc_am_windows.c
${RLC_AM_DIR}/rlc_am_rx_list.c
${RLC_AM_DIR}/rlc_am_reassembly.c
${RLC_AM_DIR}/rlc_am_status_report.c
${RLC_TM_DIR}/rlc_tm.c
${RLC_TM_DIR}/rlc_tm_init.c
${RLC_UM_DIR}/rlc_um.c
${RLC_UM_DIR}/rlc_um_fsm.c
${RLC_UM_DIR}/rlc_um_control_primitives.c
${RLC_UM_DIR}/rlc_um_segment.c
${RLC_UM_DIR}/rlc_um_reassembly.c
${RLC_UM_DIR}/rlc_um_receiver.c
${RLC_UM_DIR}/rlc_um_dar.c
${RLC_DIR}/rlc_mac.c
${RLC_DIR}/rlc.c
${RLC_DIR}/rlc_rrc.c
${RLC_DIR}/rlc_mpls.c
${RRC_DIR}/L2_interface_common.c
${LTE_RLC_SRC}
)
set(NR_L2_SRC_UE
${NR_RLC_SRC}
${NR_UE_RRC_DIR}/L2_interface_ue.c
${NR_UE_RRC_DIR}/main_ue.c
${NR_UE_RRC_DIR}/rrc_UE.c
......@@ -1693,6 +1661,10 @@ add_library(MAC_UE_NR
${MAC_NR_SRC_UE}
)
add_library(L2_LTE
${L2_LTE_SRC}
)
add_library(L2_NR
${L2_NR_SRC}
${MAC_NR_SRC}
......@@ -2345,7 +2317,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag)
target_link_libraries (lte-softmodem
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
......@@ -2417,7 +2389,7 @@ endif()
target_link_libraries (lte-uesoftmodem
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
PHY_UE PHY_RU LFDS L2_UE L2_LTE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
......@@ -2745,7 +2717,7 @@ if (${T_TRACER})
SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB
SCHED_NR_UE_LIB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB
NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_UE PHY_RU PHY_MEX
L2 L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U
L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U
SCTP_CLIENT UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB)
if (TARGET ${i})
add_dependencies(${i} generate_T)
......
......@@ -924,6 +924,10 @@ init_opt();
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
if(IS_SOFTMODEM_NOS1)
init_pdcp();
#if defined(ENABLE_ITTI)
if (RC.nb_nr_inst > 0) {
......@@ -942,9 +946,6 @@ init_opt();
flexran_agent_start(i);
}
if(IS_SOFTMODEM_NOS1)
init_pdcp();
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
......
......@@ -68,7 +68,7 @@ uint16_t NB_UE_INST = 1;
//Dummy Functions
lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms, unsigned char subframe) {return(SF_DL);}
int rlc_module_init (void) {return(0);}
int rlc_module_init (int enb) {return(0);}
void pdcp_layer_init (void) {}
int rrc_init_nr_global_param (void) {return(0);}
void config_common(int Mod_idP,int CC_idP,int Nid_cell,int nr_bandP,uint64_t SSB_positions,uint16_t ssb_periodicity,uint64_t dl_CarrierFreqP,uint32_t dl_BandwidthP);
......
......@@ -115,7 +115,7 @@ int generate_dlsch_header(unsigned char *mac_header,
unsigned char short_padding,
unsigned short post_padding){return 0;}
uint64_t get_softmodem_optmask(void) {return 0;}
int rlc_module_init (void) {return(0);}
int rlc_module_init (int enb) {return(0);}
void pdcp_layer_init (void) {}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
......
......@@ -146,7 +146,7 @@ void mac_top_init_eNB(void)
RC.mac = mac;
AssertFatal(rlc_module_init() == 0,
AssertFatal(rlc_module_init(1) == 0,
"Could not initialize RLC layer\n");
// These should be out of here later
......@@ -184,7 +184,7 @@ int rlcmac_init_global_param(void)
LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n");
if (rlc_module_init() != 0) {
if (rlc_module_init(1) != 0) {
return (-1);
}
......
......@@ -110,7 +110,7 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer,
int rlcmac_init_global_param_ue(void) {
LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n");
if (rlc_module_init() != 0) {
if (rlc_module_init(0) != 0) {
return (-1);
}
......
......@@ -47,7 +47,7 @@ nr_l2_init_ue(void)
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)malloc(sizeof(NR_UE_MAC_INST_t)*NB_NR_UE_MAC_INST);
if (IS_SOFTMODEM_NOS1){
if (rlc_module_init() != 0) {
if (rlc_module_init(0) != 0) {
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
......
......@@ -128,7 +128,7 @@ void mac_top_init_gNB(void)
}//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
AssertFatal(rlc_module_init() == 0,"Could not initialize RLC layer\n");
AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n");
// These should be out of here later
pdcp_layer_init();
......
......@@ -601,7 +601,8 @@ void rlc_data_conf (const protocol_ctxt_t *const ctxt_pP,
}
//-----------------------------------------------------------------------------
int
rlc_module_init (void) {
rlc_module_init (int enb_flag) { /* enb_flag is unused, but needed for binary
* compatibility with rlc_v2 */
//-----------------------------------------------------------------------------
int k;
module_id_t module_id1;
......
......@@ -620,10 +620,10 @@ rlc_op_status_t rlc_stat_req (
unsigned int *const stat_timer_poll_retransmit_timed_out,
unsigned int *const stat_timer_status_prohibit_timed_out);
/*! \fn int rlc_module_init(void)
/*! \fn int rlc_module_init(int enb_flag)
* \brief RAZ the memory of the RLC layer, initialize the memory pool manager (mem_block_t structures mainly used in RLC module).
*/
int rlc_module_init(void);
int rlc_module_init(int enb_flag);
/** @} */
......
CC=gcc
CFLAGS=-Wall -g -Itests
OBJS=nr_rlc_entity.o nr_rlc_entity_am.o nr_rlc_entity_um.o \
nr_rlc_entity_tm.o nr_rlc_sdu.o nr_rlc_pdu.o test.o
PROG=test
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f test *.o
RLC AM:
- status reporting (38.322 5.3.4): implement this (not done because not
clearly understood):
"delay triggering the STATUS report until x < RX_Highest_Status
or x >= RX_Next + AM_Window_Size."
- send indication of successful delivery as soon as possible. Today we
signal successful delivery in order. Probably not a big issue though.
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#include "rlc.h"
int decode_t_reordering(int v)
{
static int tab[32] = {
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85,
90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 1600
};
if (v < 0 || v > 31) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
int decode_t_status_prohibit(int v)
{
static int tab[62] = {
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90,
95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165,
170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240,
245, 250, 300, 350, 400, 450, 500, 800, 1000, 1200, 1600, 2000, 2400
};
if (v < 0 || v > 61) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
int decode_t_poll_retransmit(int v)
{
static int tab[59] = {
5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95,
100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170,
175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245,
250, 300, 350, 400, 450, 500, 800, 1000, 2000, 4000
};
if (v < 0 || v > 58) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
int decode_poll_pdu(int v)
{
static int tab[8] = {
4, 8, 16, 32, 64, 128, 256, -1 /* -1 means infinity */
};
if (v < 0 || v > 7) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
int decode_poll_byte(int v)
{
static int tab[15] = {
25, 50, 75, 100, 125, 250, 375, 500, 750, 1000, 1250, 1500, 2000, 3000,
-1 /* -1 means infinity */
};
if (v < 0 || v > 14) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (tab[v] == -1) return -1;
return tab[v] * 1024;
}
int decode_max_retx_threshold(int v)
{
static int tab[8] = {
1, 2, 3, 4, 6, 8, 16, 32
};
if (v < 0 || v > 7) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
int decode_sn_field_length(int v)
{
static int tab[2] = {
5, 10
};
if (v < 0 || v > 1) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#ifndef _ASN1_UTILS_H_
#define _ASN1_UTILS_H_
int decode_t_reordering(int v);
int decode_t_status_prohibit(int v);
int decode_t_poll_retransmit(int v);
int decode_poll_pdu(int v);
int decode_poll_byte(int v);
int decode_max_retx_threshold(int v);
int decode_sn_field_length(int v);
#endif /* _ASN1_UTILS_H_ */
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#include "nr_rlc_entity.h"
#include <stdlib.h>
#include "nr_rlc_entity_am.h"
#include "nr_rlc_entity_um.h"
#include "nr_rlc_entity_tm.h"
#include "LOG/log.h"
nr_rlc_entity_t *new_nr_rlc_entity_am(
int rx_maxsize,
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*sdu_successful_delivery)(void *sdu_successful_delivery_data,
struct nr_rlc_entity_t *entity,
int sdu_id),
void *sdu_successful_delivery_data,
void (*max_retx_reached)(void *max_retx_reached_data,
struct nr_rlc_entity_t *entity),
void *max_retx_reached_data,
int t_poll_retransmit,
int t_reassembly,
int t_status_prohibit,
int poll_pdu,
int poll_byte,
int max_retx_threshold,
int sn_field_length)
{
nr_rlc_entity_am_t *ret;
ret = calloc(1, sizeof(nr_rlc_entity_am_t));
if (ret == NULL) {
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ret->tx_maxsize = tx_maxsize;
ret->rx_maxsize = rx_maxsize;
ret->t_poll_retransmit = t_poll_retransmit;
ret->t_reassembly = t_reassembly;
ret->t_status_prohibit = t_status_prohibit;
ret->poll_pdu = poll_pdu;
ret->poll_byte = poll_byte;
ret->max_retx_threshold = max_retx_threshold;
ret->sn_field_length = sn_field_length;
if (!(sn_field_length == 12 || sn_field_length == 18)) {
LOG_E(RLC, "%s:%d:%s: wrong SN field_lenght (%d), must be 12 or 18\n",
__FILE__, __LINE__, __FUNCTION__, sn_field_length);
exit(1);
}
ret->sn_modulus = 1 << ret->sn_field_length;
ret->window_size = ret->sn_modulus / 2;
ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu;
ret->common.buffer_status = nr_rlc_entity_am_buffer_status;
ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu;
ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu;
ret->common.set_time = nr_rlc_entity_am_set_time;
ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu;
ret->common.reestablishment = nr_rlc_entity_am_reestablishment;
ret->common.delete = nr_rlc_entity_am_delete;
ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data;
ret->common.sdu_successful_delivery = sdu_successful_delivery;
ret->common.sdu_successful_delivery_data = sdu_successful_delivery_data;
ret->common.max_retx_reached = max_retx_reached;
ret->common.max_retx_reached_data = max_retx_reached_data;
return (nr_rlc_entity_t *)ret;
}
nr_rlc_entity_t *new_nr_rlc_entity_um(
int rx_maxsize,
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
int t_reassembly,
int sn_field_length)
{
nr_rlc_entity_um_t *ret;
ret = calloc(1, sizeof(nr_rlc_entity_um_t));
if (ret == NULL) {
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ret->tx_maxsize = tx_maxsize;
ret->rx_maxsize = rx_maxsize;
ret->t_reassembly = t_reassembly;
ret->sn_field_length = sn_field_length;
if (!(sn_field_length == 6 || sn_field_length == 12)) {
LOG_E(RLC, "%s:%d:%s: wrong SN field_lenght (%d), must be 6 or 12\n",
__FILE__, __LINE__, __FUNCTION__, sn_field_length);
exit(1);
}
ret->sn_modulus = 1 << ret->sn_field_length;
ret->window_size = ret->sn_modulus / 2;
ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu;
ret->common.buffer_status = nr_rlc_entity_um_buffer_status;
ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu;
ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu;
ret->common.set_time = nr_rlc_entity_um_set_time;
ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu;
ret->common.reestablishment = nr_rlc_entity_um_reestablishment;
ret->common.delete = nr_rlc_entity_um_delete;
ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data;
return (nr_rlc_entity_t *)ret;
}
nr_rlc_entity_t *new_nr_rlc_entity_tm(
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data)
{
nr_rlc_entity_tm_t *ret;
ret = calloc(1, sizeof(nr_rlc_entity_tm_t));
if (ret == NULL) {
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ret->tx_maxsize = tx_maxsize;
ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu;
ret->common.buffer_status = nr_rlc_entity_tm_buffer_status;
ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu;
ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu;
ret->common.set_time = nr_rlc_entity_tm_set_time;
ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu;
ret->common.reestablishment = nr_rlc_entity_tm_reestablishment;
ret->common.delete = nr_rlc_entity_tm_delete;
ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data;
return (nr_rlc_entity_t *)ret;
}
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#ifndef _NR_RLC_ENTITY_H_
#define _NR_RLC_ENTITY_H_
#include <stdint.h>
#define NR_SDU_MAX 16000 /* max NR PDCP SDU size is 9000, let's take more */
typedef struct {
int status_size;
int tx_size;
int retx_size;
} nr_rlc_entity_buffer_status_t;
typedef struct nr_rlc_entity_t {
/* functions provided by the RLC module */
void (*recv_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size);
nr_rlc_entity_buffer_status_t (*buffer_status)(
struct nr_rlc_entity_t *entity, int maxsize);
int (*generate_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size);
void (*recv_sdu)(struct nr_rlc_entity_t *entity, char *buffer, int size,
int sdu_id);
void (*set_time)(struct nr_rlc_entity_t *entity, uint64_t now);
void (*discard_sdu)(struct nr_rlc_entity_t *entity, int sdu_id);
void (*reestablishment)(struct nr_rlc_entity_t *entity);
void (*delete)(struct nr_rlc_entity_t *entity);
/* callbacks provided to the RLC module */
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size);
void *deliver_sdu_data;
void (*sdu_successful_delivery)(void *sdu_successful_delivery_data,
struct nr_rlc_entity_t *entity,
int sdu_id);
void *sdu_successful_delivery_data;
void (*max_retx_reached)(void *max_retx_reached_data,
struct nr_rlc_entity_t *entity);
void *max_retx_reached_data;
} nr_rlc_entity_t;
nr_rlc_entity_t *new_nr_rlc_entity_am(
int rx_maxsize,
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*sdu_successful_delivery)(void *sdu_successful_delivery_data,
struct nr_rlc_entity_t *entity,
int sdu_id),
void *sdu_successful_delivery_data,
void (*max_retx_reached)(void *max_retx_reached_data,
struct nr_rlc_entity_t *entity),
void *max_retx_reached_data,
int t_poll_retransmit,
int t_reassembly,
int t_status_prohibit,
int poll_pdu,
int poll_byte,
int max_retx_threshold,
int sn_field_length);
nr_rlc_entity_t *new_nr_rlc_entity_um(
int rx_maxsize,
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
int t_reassembly,
int sn_field_length);
nr_rlc_entity_t *new_nr_rlc_entity_tm(
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data);
#endif /* _NR_RLC_ENTITY_H_ */
This diff is collapsed.
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#ifndef _NR_RLC_ENTITY_AM_H_
#define _NR_RLC_ENTITY_AM_H_
#include "nr_rlc_entity.h"
#include "nr_rlc_sdu.h"
#include "nr_rlc_pdu.h"
typedef struct {
nr_rlc_entity_t common;
/* configuration */
int t_poll_retransmit;
int t_reassembly;
int t_status_prohibit;
int poll_pdu; /* -1 means infinity */
int poll_byte; /* -1 means infinity */
int max_retx_threshold;
int sn_field_length;
int sn_modulus;
int window_size;
/* runtime rx */
int rx_next;
int rx_next_status_trigger;
int rx_highest_status;
int rx_next_highest;
int status_triggered;
/* runtime tx */
int tx_next;
int tx_next_ack;
int poll_sn;
int pdu_without_poll;
int byte_without_poll;
int force_poll;
/* set to the latest know time by the user of the module. Unit: ms */
uint64_t t_current;
/* timers (stores the TTI of activation, 0 means not active) */
uint64_t t_poll_retransmit_start;
uint64_t t_reassembly_start;
uint64_t t_status_prohibit_start;
/* rx management */
nr_rlc_pdu_t *rx_list;
int rx_size;
int rx_maxsize;
/* tx management */
nr_rlc_sdu_segment_t *tx_list;
nr_rlc_sdu_segment_t *tx_end;
int tx_size;
int tx_maxsize;
nr_rlc_sdu_segment_t *wait_list;
nr_rlc_sdu_segment_t *wait_end;
nr_rlc_sdu_segment_t *retransmit_list;
nr_rlc_sdu_segment_t *retransmit_end;
nr_rlc_sdu_segment_t *ack_list;
} nr_rlc_entity_am_t;
void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *entity,
char *buffer, int size,
int sdu_id);
void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *entity,
char *buffer, int size);
nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status(
nr_rlc_entity_t *entity, int maxsize);
int nr_rlc_entity_am_generate_pdu(nr_rlc_entity_t *entity,
char *buffer, int size);
void nr_rlc_entity_am_set_time(nr_rlc_entity_t *entity, uint64_t now);
void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity);
void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity);
#endif /* _NR_RLC_ENTITY_AM_H_ */
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#include "nr_rlc_entity_tm.h"
#include <stdlib.h>
#include <string.h>
#include "nr_rlc_pdu.h"
#include "LOG/log.h"
/*************************************************************************/
/* PDU RX functions */
/*************************************************************************/
void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *_entity,
char *buffer, int size)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_rlc_entity_t *)entity,
buffer, size);
}
/*************************************************************************/
/* TX functions */
/*************************************************************************/
static int generate_tx_pdu(nr_rlc_entity_tm_t *entity, char *buffer, int size)
{
nr_rlc_sdu_segment_t *sdu;
int ret;
if (entity->tx_list == NULL)
return 0;
sdu = entity->tx_list;
/* not enough room? do nothing */
if (sdu->size > size)
return 0;
entity->tx_list = entity->tx_list->next;
if (entity->tx_list == NULL)
entity->tx_end = NULL;
ret = sdu->size;
memcpy(buffer, sdu->sdu->data, sdu->size);
entity->tx_size -= sdu->size;
nr_rlc_free_sdu_segment(sdu);
return ret;
}
static int tx_list_size(nr_rlc_entity_tm_t *entity,
nr_rlc_sdu_segment_t *l, int maxsize)
{
int ret = 0;
while (l != NULL) {
ret += l->size;
l = l->next;
}
if (ret > maxsize) ret = maxsize;
return ret;
}
nr_rlc_entity_buffer_status_t nr_rlc_entity_tm_buffer_status(
nr_rlc_entity_t *_entity, int maxsize)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
nr_rlc_entity_buffer_status_t ret;
ret.status_size = 0;
ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize);
ret.retx_size = 0;
return ret;
}
int nr_rlc_entity_tm_generate_pdu(nr_rlc_entity_t *_entity,
char *buffer, int size)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
return generate_tx_pdu(entity, buffer, size);
}
/*************************************************************************/
/* SDU RX functions */
/*************************************************************************/
void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity,
char *buffer, int size,
int sdu_id)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
nr_rlc_sdu_segment_t *sdu;
if (size > NR_SDU_MAX) {
LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n",
__FILE__, __LINE__, __FUNCTION__, size);
exit(1);
}
if (entity->tx_size + size > entity->tx_maxsize) {
LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
__FILE__, __LINE__, __FUNCTION__);
return;
}
entity->tx_size += size;
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
}
/*************************************************************************/
/* time/timers */
/*************************************************************************/
void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *_entity, uint64_t now)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
entity->t_current = now;
}
/*************************************************************************/
/* discard/re-establishment/delete */
/*************************************************************************/
void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id)
{
/* nothing to do */
}
static void clear_entity(nr_rlc_entity_tm_t *entity)
{
nr_rlc_free_sdu_segment_list(entity->tx_list);
entity->tx_list = NULL;
entity->tx_end = NULL;
entity->tx_size = 0;
}
void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
clear_entity(entity);
}
void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
clear_entity(entity);
free(entity);
}
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#ifndef _NR_RLC_ENTITY_TM_H_
#define _NR_RLC_ENTITY_TM_H_
#include "nr_rlc_entity.h"
#include "nr_rlc_sdu.h"
typedef struct {
nr_rlc_entity_t common;
/* set to the latest know time by the user of the module. Unit: ms */
uint64_t t_current;
/* tx management */
nr_rlc_sdu_segment_t *tx_list;
nr_rlc_sdu_segment_t *tx_end;
int tx_size;
int tx_maxsize;
} nr_rlc_entity_tm_t;
void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *entity,
char *buffer, int size,
int sdu_id);
void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *entity,
char *buffer, int size);
nr_rlc_entity_buffer_status_t nr_rlc_entity_tm_buffer_status(
nr_rlc_entity_t *entity, int maxsize);
int nr_rlc_entity_tm_generate_pdu(nr_rlc_entity_t *entity,
char *buffer, int size);
void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *entity, uint64_t now);
void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity);
void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity);
#endif /* _NR_RLC_ENTITY_TM_H_ */
This diff is collapsed.
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#ifndef _NR_RLC_ENTITY_UM_H_
#define _NR_RLC_ENTITY_UM_H_
#include "nr_rlc_entity.h"
#include "nr_rlc_sdu.h"
#include "nr_rlc_pdu.h"
typedef struct {
nr_rlc_entity_t common;
/* configuration */
int t_reassembly;
int sn_field_length;
int sn_modulus;
int window_size;
/* runtime rx */
int rx_next_highest;
int rx_next_reassembly;
int rx_timer_trigger;
/* runtime tx */
int tx_next;
/* set to the latest know time by the user of the module. Unit: ms */
uint64_t t_current;
/* timers (stores the TTI of activation, 0 means not active) */
uint64_t t_reassembly_start;
/* rx management */
nr_rlc_pdu_t *rx_list;
int rx_size;
int rx_maxsize;
/* tx management */
nr_rlc_sdu_segment_t *tx_list;
nr_rlc_sdu_segment_t *tx_end;
int tx_size;
int tx_maxsize;
} nr_rlc_entity_um_t;
void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *entity,
char *buffer, int size,
int sdu_id);
void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *entity,
char *buffer, int size);
nr_rlc_entity_buffer_status_t nr_rlc_entity_um_buffer_status(
nr_rlc_entity_t *entity, int maxsize);
int nr_rlc_entity_um_generate_pdu(nr_rlc_entity_t *entity,
char *buffer, int size);
void nr_rlc_entity_um_set_time(nr_rlc_entity_t *entity, uint64_t now);
void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id);
void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity);
void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity);
#endif /* _NR_RLC_ENTITY_UM_H_ */
This diff is collapsed.
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#include "nr_rlc_pdu.h"
#include <stdlib.h>
#include <string.h>
#include "LOG/log.h"
/**************************************************************************/
/* RX PDU management */
/**************************************************************************/
nr_rlc_pdu_t *nr_rlc_new_pdu(int sn, int so, int is_first,
int is_last, char *data, int size)
{
nr_rlc_pdu_t *ret = malloc(sizeof(nr_rlc_pdu_t));
if (ret == NULL) {
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ret->sn = sn;
ret->so = so;
ret->size = size;
ret->is_first = is_first;
ret->is_last = is_last;
ret->next = NULL;
ret->data = malloc(size);
if (ret->data == NULL) {
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
memcpy(ret->data, data, size);
return ret;
}
void nr_rlc_free_pdu(nr_rlc_pdu_t *pdu)
{
free(pdu->data);
free(pdu);
}
nr_rlc_pdu_t *nr_rlc_pdu_list_add(
int (*sn_compare)(void *, int, int), void *sn_compare_data,
nr_rlc_pdu_t *list, nr_rlc_pdu_t *pdu)
{
nr_rlc_pdu_t head;
nr_rlc_pdu_t *cur;
nr_rlc_pdu_t *prev;
head.next = list;
cur = list;
prev = &head;
/* order is by 'sn', if 'sn' is the same then order is by 'so' */
while (cur != NULL) {
/* check if 'pdu' is before 'cur' in the list */
if (sn_compare(sn_compare_data, cur->sn, pdu->sn) > 0 ||
(cur->sn == pdu->sn && cur->so > pdu->so)) {
break;
}
prev = cur;
cur = cur->next;
}
prev->next = pdu;
pdu->next = cur;
return head.next;
}
/**************************************************************************/
/* PDU decoder */
/**************************************************************************/
void nr_rlc_pdu_decoder_init(nr_rlc_pdu_decoder_t *decoder,
char *buffer, int size)
{
decoder->error = 0;
decoder->byte = 0;
decoder->bit = 0;
decoder->buffer = buffer;
decoder->size = size;
}
static int get_bit(nr_rlc_pdu_decoder_t *decoder)
{
int ret;
if (decoder->byte >= decoder->size) {
decoder->error = 1;
return 0;
}
ret = (decoder->buffer[decoder->byte] >> (7 - decoder->bit)) & 1;
decoder->bit++;
if (decoder->bit == 8) {
decoder->bit = 0;
decoder->byte++;
}
return ret;
}
int nr_rlc_pdu_decoder_get_bits(nr_rlc_pdu_decoder_t *decoder, int count)
{
int ret = 0;
int i;
if (count > 31) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
for (i = 0; i < count; i++) {
ret <<= 1;
ret |= get_bit(decoder);
if (decoder->error) return -1;
}
return ret;
}
/**************************************************************************/
/* PDU encoder */
/**************************************************************************/
void nr_rlc_pdu_encoder_init(nr_rlc_pdu_encoder_t *encoder,
char *buffer, int size)
{
encoder->byte = 0;
encoder->bit = 0;
encoder->buffer = buffer;
encoder->size = size;
}
static void put_bit(nr_rlc_pdu_encoder_t *encoder, int bit)
{
if (encoder->byte == encoder->size) {
LOG_E(RLC, "%s:%d:%s: fatal, buffer full\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
encoder->buffer[encoder->byte] <<= 1;
if (bit)
encoder->buffer[encoder->byte] |= 1;
encoder->bit++;
if (encoder->bit == 8) {
encoder->bit = 0;
encoder->byte++;
}
}
void nr_rlc_pdu_encoder_put_bits(nr_rlc_pdu_encoder_t *encoder,
int value, int count)
{
int i;
int x;
if (count > 31) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
x = 1 << (count - 1);
for (i = 0; i < count; i++, x >>= 1)
put_bit(encoder, value & x);
}
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#ifndef _NR_RLC_PDU_H_
#define _NR_RLC_PDU_H_
/**************************************************************************/
/* RX PDU management */
/**************************************************************************/
typedef struct nr_rlc_pdu_t {
int sn;
char *data; /* contains only SDU bytes, no PDU header */
int size; /* size of SDU data, no PDU header bytes counted */
int so;
int is_first;
int is_last;
struct nr_rlc_pdu_t *next;
} nr_rlc_pdu_t;
nr_rlc_pdu_t *nr_rlc_new_pdu(int sn, int so, int is_first,
int is_last, char *data, int size);
void nr_rlc_free_pdu(nr_rlc_pdu_t *pdu);
nr_rlc_pdu_t *nr_rlc_pdu_list_add(
int (*sn_compare)(void *, int, int), void *sn_compare_data,
nr_rlc_pdu_t *list, nr_rlc_pdu_t *pdu);
/**************************************************************************/
/* PDU decoder */
/**************************************************************************/
typedef struct {
int error;
int byte; /* next byte to decode */
int bit; /* next bit in next byte to decode */
char *buffer;
int size;
} nr_rlc_pdu_decoder_t;
void nr_rlc_pdu_decoder_init(nr_rlc_pdu_decoder_t *decoder,
char *buffer, int size);
#define nr_rlc_pdu_decoder_in_error(d) ((d)->error == 1)
int nr_rlc_pdu_decoder_get_bits(nr_rlc_pdu_decoder_t *decoder, int count);
/**************************************************************************/
/* PDU encoder */
/**************************************************************************/
typedef struct {
int byte; /* next byte to encode */
int bit; /* next bit in next byte to encode */
char *buffer;
int size;
} nr_rlc_pdu_encoder_t;
void nr_rlc_pdu_encoder_init(nr_rlc_pdu_encoder_t *encoder,
char *buffer, int size);
void nr_rlc_pdu_encoder_put_bits(nr_rlc_pdu_encoder_t *encoder,
int value, int count);
#endif /* _NR_RLC_PDU_H_ */
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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
*/
#include "nr_rlc_sdu.h"
#include <stdlib.h>
#include <string.h>
#include "LOG/log.h"
nr_rlc_sdu_segment_t *nr_rlc_new_sdu(
char *buffer, int size,
int upper_layer_id)
{
nr_rlc_sdu_t *sdu = calloc(1, sizeof(nr_rlc_sdu_t));
nr_rlc_sdu_segment_t *ret = calloc(1, sizeof(nr_rlc_sdu_segment_t));
if (sdu == NULL || ret == NULL)
goto oom;
sdu->ref_count = 1;
sdu->sn = -1; /* set later */
sdu->upper_layer_id = upper_layer_id;
sdu->data = malloc(size);
if (sdu->data == NULL)
goto oom;
memcpy(sdu->data, buffer, size);
sdu->size = size;
sdu->retx_count = -1;
ret->sdu = sdu;
ret->size = size;
ret->so = 0;
ret->is_first = 1;
ret->is_last = 1;
return ret;
oom:
LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu)
{
sdu->sdu->ref_count--;
if (sdu->sdu->ref_count == 0) {
free(sdu->sdu->data);
free(sdu->sdu);
}
free(sdu);
}
void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list,
nr_rlc_sdu_segment_t **end,
nr_rlc_sdu_segment_t *sdu)
{
if (*list == NULL) {
*list = sdu;
*end = sdu;
return;
}
(*end)->next = sdu;
*end = sdu;
}
nr_rlc_sdu_segment_t *nr_rlc_sdu_segment_list_add(
int (*sn_compare)(void *, int, int), void *sn_compare_data,
nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment)
{
nr_rlc_sdu_segment_t head;
nr_rlc_sdu_segment_t *cur;
nr_rlc_sdu_segment_t *prev;
head.next = list;
cur = list;
prev = &head;
/* order is by 'sn', if 'sn' is the same then order is by 'so' */
while (cur != NULL) {
/* check if 'sdu_segment' is before 'cur' in the list */
if (sn_compare(sn_compare_data, cur->sdu->sn, sdu_segment->sdu->sn) > 0 ||
(cur->sdu->sn == sdu_segment->sdu->sn && cur->so > sdu_segment->so)) {
break;
}
prev = cur;
cur = cur->next;
}
prev->next = sdu_segment;
sdu_segment->next = cur;
return head.next;
}
void nr_rlc_free_sdu_segment_list(nr_rlc_sdu_segment_t *l)
{
nr_rlc_sdu_segment_t *cur;
while (l != NULL) {
cur = l;
l = l->next;
nr_rlc_free_sdu_segment(cur);
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include "nr_rlc_entity.h"
#include <stdio.h>
int main(void)
{
char out[32768];
nr_rlc_entity_t *am;
int sdu_id = 0;
int size;
int i;
am = new_nr_rlc_entity_am(100000, 100000,
0, 0,
0, 0,
0, 0,
45, 35, 0,
-1, -1, 8,
12);
char data[8] = { 1, 2, 3, 4, 8, 7, 6, 5 };
am->recv_sdu(am, data, sizeof(data), sdu_id++);
size = am->generate_pdu(am, out, 32768);
printf("generate_pdu[%d]:", size);
for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)out[i]);
printf("\n");
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment