From 8fa560227832d8582e5c0d04bcc64bfff27662c0 Mon Sep 17 00:00:00 2001 From: Cedric Roux <cedric.roux@eurecom.fr> Date: Fri, 11 Oct 2013 14:45:30 +0000 Subject: [PATCH] - Added thread that fetch netlink packets and place them in a FIFO (option enabled by default) to reduce pdcp_run execution time - Fix some debug formats git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4187 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 3 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 2 +- .../SIMULATION/ETH_TRANSPORT/netlink_init.c | 2 + openair2/LAYER2/Makefile.inc | 1 + openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 53 ++-- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 11 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 88 ++++++- openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c | 238 ++++++++++++++++++ .../LAYER2/PDCP_v10.1.0/pdcp_primitives.h | 3 + openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c | 2 + openair2/UTIL/FIFO/types.h | 6 +- openair2/UTIL/OSA/osa_internal.h | 2 +- openair2/UTIL/OSA/osa_key_deriver.c | 9 +- openair2/UTIL/OTG/otg_models.c | 22 +- targets/SIMU/USER/Makefile | 1 + targets/SIMU/USER/oaisim_functions.c | 5 +- 16 files changed, 382 insertions(+), 66 deletions(-) create mode 100644 openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 90926004cd..feb30915c6 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -169,7 +169,8 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne return(dlsch); } } - msg("new_eNB_dlsch exit flag %d, size of %d\n",exit_flag, sizeof(LTE_eNB_DLSCH_t)); + LOG_D(PHY, "new_eNB_dlsch exit flag %d, size of %ld\n", + exit_flag, sizeof(LTE_eNB_DLSCH_t)); free_eNB_dlsch(dlsch); return(NULL); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index be0cbe12d9..5f62d2d2ee 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -120,7 +120,7 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint8_t max_turbo_ite if (exit_flag==0) return(dlsch); } - msg("new_ue_dlsch with size %d: exit_flag = %d\n",sizeof(LTE_DL_UE_HARQ_t), exit_flag); + msg("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(LTE_DL_UE_HARQ_t), exit_flag); free_ue_dlsch(dlsch); return(NULL); diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index c1395c4637..691744ffb0 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -43,11 +43,13 @@ int netlink_init(void) } printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd); +#if !defined(ENABLE_PDCP_NETLINK_FIFO) ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK); if (ret == -1) { printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno)); // exit(1); } +#endif memset(&nas_src_addr, 0, sizeof(nas_src_addr)); nas_src_addr.nl_family = AF_NETLINK; diff --git a/openair2/LAYER2/Makefile.inc b/openair2/LAYER2/Makefile.inc index 41cac88a1e..9cc4055597 100644 --- a/openair2/LAYER2/Makefile.inc +++ b/openair2/LAYER2/Makefile.inc @@ -27,6 +27,7 @@ SOURCES_L2 += $(PDCP_DIR)/pdcp_sequence_manager.c SOURCES_L2 += $(PDCP_DIR)/pdcp_primitives.c SOURCES_L2 += $(PDCP_DIR)/pdcp_util.c SOURCES_L2 += $(PDCP_DIR)/pdcp_security.c +SOURCES_L2 += $(PDCP_DIR)/pdcp_netlink.c SOURCES_L2 += $(RLC_AM_DIR)/rlc_am.c SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_init.c diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 0ced904b73..bd14ff4e9e 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -82,8 +82,8 @@ extern int otg_rx_pkt( int src, int dst, int ctime, char *buffer_tx, unsigned in BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb_id, sdu_size_t sdu_buffer_size, \ unsigned char* sdu_buffer, pdcp_t* test_pdcp_entity, list_t* test_list) #else - BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb_id, u32 muiP, u32 confirmP, \ - sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer, u8 mode) +BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb_id, u32 muiP, u32 confirmP, \ + sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer, u8 mode) #endif { //----------------------------------------------------------------------------- @@ -126,7 +126,7 @@ BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb memcpy(&pdcp_pdu->data[0], sdu_buffer, sdu_buffer_size); rlc_status = rlc_data_req(module_id, frame, eNB_flag, RLC_MBMS_YES, rb_id, muiP, confirmP, sdu_buffer_size, pdcp_pdu); } else - rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES; + rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES; } else { // calculate the pdcp header and trailer size if ((rb_id % NB_RB_MAX) < DTCH) { @@ -137,15 +137,15 @@ BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb pdcp_tailer_len = 0; } pdcp_pdu_size= sdu_buffer_size + pdcp_header_len + pdcp_tailer_len; - + LOG_I(PDCP, "Data request notification for PDCP entity with module ID %d and radio bearer ID %d pdu size %d (header%d, trailer%d)\n", module_id, rb_id,pdcp_pdu_size, pdcp_header_len,pdcp_tailer_len); - + /* * Allocate a new block for the new PDU (i.e. PDU header and SDU payload) */ LOG_D(PDCP, "Asking for a new mem_block of size %d\n", pdcp_pdu_size); pdcp_pdu = get_free_mem_block(pdcp_pdu_size); - + if (pdcp_pdu != NULL) { /* * Create a Data PDU with header and append data @@ -295,7 +295,7 @@ BOOL pdcp_data_ind(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb "ID %d and radio bearer ID %d rlc sdu size %d eNB_flag %d\n", module_id, rb_id, sdu_buffer_size, eNB_flag); if (sdu_buffer_size == 0) { - LOG_W(PDCP, "SDU buffer size is zero! Ignoring this chunk!"); + LOG_W(PDCP, "SDU buffer size is zero! Ignoring this chunk!\n"); return FALSE; } @@ -469,14 +469,13 @@ BOOL pdcp_data_ind(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb } //----------------------------------------------------------------------------- -void - pdcp_run (u32_t frame, u8 eNB_flag, u8 UE_index, u8 eNB_index) { +void pdcp_run (u32_t frame, u8 eNB_flag, u8 UE_index, u8 eNB_index) { //----------------------------------------------------------------------------- #ifndef NAS_NETLINK #ifdef USER_MODE #define PDCP_DUMMY_BUFFER_SIZE 38 - unsigned char pdcp_dummy_buffer[PDCP_DUMMY_BUFFER_SIZE]; + unsigned char pdcp_dummy_buffer[PDCP_DUMMY_BUFFER_SIZE]; #endif #endif // unsigned int diff, i, k, j; @@ -487,7 +486,7 @@ void // int pkt_size=0; // unsigned int ctime=0; - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); /* if ((frame % 128) == 0) { @@ -510,10 +509,10 @@ void pdcp_fifo_read_input_sdus_from_otg(frame, eNB_flag, UE_index, eNB_index); // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer - pdcp_fifo_read_input_sdus(frame,eNB_flag); + pdcp_fifo_read_input_sdus(frame, eNB_flag, UE_index, eNB_index); // PDCP -> NAS/IP traffic: RX - pdcp_fifo_flush_sdus(frame,eNB_flag); + pdcp_fifo_flush_sdus(frame, eNB_flag); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT); } @@ -531,21 +530,21 @@ BOOL rrc_pdcp_config_asn1_req (module_id_t module_id, u32_t frame, u8_t eNB_flag #endif ){ - long int rb_id = 0; - long int lc_id = 0; - long int srb_id = 0; + long int rb_id = 0; + long int lc_id = 0; + long int srb_id = 0; long int mch_id = 0; - rlc_mode_t rlc_type = RLC_NONE; - DRB_Identity_t drb_id = 0; - DRB_Identity_t* pdrb_id = NULL; - u8 drb_sn = 0; - u8 srb_sn = 5; // fixed sn for SRBs - u8 drb_report = 0; - long int cnt = 0; + rlc_mode_t rlc_type = RLC_NONE; + DRB_Identity_t drb_id = 0; + DRB_Identity_t* pdrb_id = NULL; + u8 drb_sn = 0; + u8 srb_sn = 5; // fixed sn for SRBs + u8 drb_report = 0; + long int cnt = 0; u16 header_compression_profile = 0; - u32 action = ACTION_ADD; - SRB_ToAddMod_t* srb_toaddmod = NULL; - DRB_ToAddMod_t* drb_toaddmod = NULL; + u32 action = ACTION_ADD; + SRB_ToAddMod_t* srb_toaddmod = NULL; + DRB_ToAddMod_t* drb_toaddmod = NULL; #ifdef Rel10 int i,j; @@ -692,7 +691,7 @@ BOOL rrc_pdcp_config_asn1_req (module_id_t module_id, u32_t frame, u8_t eNB_flag if (drb2release_list != NULL) { for (cnt=0;cnt<drb2add_list->list.count;cnt++) { pdrb_id = drb2release_list->list.array[cnt]; - rb_id = (index * NB_RB_MAX) + pdrb_id; + rb_id = (index * NB_RB_MAX) + *pdrb_id; action = ACTION_REMOVE; pdcp_config_req_asn1 (module_id, frame, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 13be1f28aa..0332e513f6 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -91,7 +91,6 @@ extern pthread_mutex_t pdcp_mutex; extern pthread_cond_t pdcp_cond; extern int pdcp_instance_cnt; -static void *pdcp_thread_main(void* param); int init_pdcp_thread(void); void cleanup_pdcp_thread(void); @@ -343,13 +342,14 @@ public_pdcp(int pdcp_module_init ();) public_pdcp(void pdcp_module_cleanup ();) public_pdcp(void pdcp_layer_init ();) public_pdcp(void pdcp_layer_cleanup ();) +public_pdcp(int pdcp_netlink_init(void);) #define PDCP2NAS_FIFO 21 #define NAS2PDCP_FIFO 22 protected_pdcp_fifo(int pdcp_fifo_flush_sdus (u32_t,u8_t);) protected_pdcp_fifo(int pdcp_fifo_read_input_sdus_remaining_bytes (u32_t,u8_t);) -protected_pdcp_fifo(int pdcp_fifo_read_input_sdus(u32_t,u8_t);) +protected_pdcp_fifo(int pdcp_fifo_read_input_sdus (u32_t frame, u8_t eNB_flag, u8_t UE_index, u8_t eNB_index);) protected_pdcp_fifo(void pdcp_fifo_read_input_sdus_from_otg (u32_t frame, u8_t eNB_flag, u8 UE_index, u8 eNB_index);) //----------------------------------------------------------------------------- @@ -368,6 +368,13 @@ typedef struct pdcp_data_ind_header_t { int inst; } pdcp_data_ind_header_t; +struct pdcp_netlink_element_s { + pdcp_data_req_header_t pdcp_read_header; + + /* Data part of the message */ + uint8_t *data; +}; + #if 0 /* * Missing PDU information struct, a copy of this will be enqueued diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index a938813f16..a7c36709d6 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -93,8 +93,7 @@ extern Packet_OTG_List *otg_pdcp_buffer; pdcp_data_req_header_t pdcp_read_header; //----------------------------------------------------------------------------- -int - pdcp_fifo_flush_sdus (u32_t frame,u8 eNB_flag) +int pdcp_fifo_flush_sdus (u32_t frame,u8 eNB_flag) { //----------------------------------------------------------------------------- @@ -170,7 +169,7 @@ int ret = sendmsg(nas_sock_fd,&nas_msg_tx,0); if (ret<0) { LOG_D(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno); - mac_xface->macphy_exit(""); + mac_xface->macphy_exit("sendmsg failed for nas_sock_fd\n"); break; } #endif // LINUX @@ -350,8 +349,7 @@ int } //----------------------------------------------------------------------------- -int - pdcp_fifo_read_input_sdus (u32_t frame, u8_t eNB_flag) +int pdcp_fifo_read_input_sdus (u32_t frame, u8_t eNB_flag, u8_t UE_index, u8_t eNB_index) { //----------------------------------------------------------------------------- //#ifdef NAS_FIFO @@ -426,11 +424,11 @@ int // } else { //#ifdef PDCP_DEBUG //#ifdef LINUX -// LOG_I(PDCP, "[PDCP][NETLINK] Received socket with length %d (nlmsg_len = %d)\n", \ +// LOG_I(PDCP, "[PDCP][NETLINK] Received socket with length %d (nlmsg_len = %d)\n", // len, nas_nlh->nlmsg_len-sizeof(struct nlmsghdr)); //#else -// LOG_I(PDCP, "[PDCP][NETLINK] nlmsg_len = %d (%d,%d)\n", \ -// nas_nlh->nlmsg_len, sizeof(pdcp_data_req_header_t), \ +// LOG_I(PDCP, "[PDCP][NETLINK] nlmsg_len = %d (%d,%d)\n", +// nas_nlh->nlmsg_len, sizeof(pdcp_data_req_header_t), // sizeof(struct nlmsghdr)); //#endif //#endif @@ -465,7 +463,7 @@ int //#endif // //#ifdef OAI_EMU -// pdcp_read_header.inst = (pdcp_read_header.inst >= oai_emulation.info.nb_enb_local) ? \ +// pdcp_read_header.inst = (pdcp_read_header.inst >= oai_emulation.info.nb_enb_local) ? // pdcp_read_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : // pdcp_read_header.inst + oai_emulation.info.first_enb_local; //#else @@ -475,7 +473,7 @@ int // if (pdcp_read_header.rb_id != 0) { // if (pdcp_array[pdcp_read_header.inst][pdcp_read_header.rb_id].instanciated_instance) { //#ifdef PDCP_DEBUG -// LOG_I(PDCP, "[PDCP][NETLINK][IP->PDCP] TTI %d, INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n", \ +// LOG_I(PDCP, "[PDCP][NETLINK][IP->PDCP] TTI %d, INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n", // frame, pdcp_read_header.inst, len, nas_nlh->nlmsg_len-sizeof(struct nlmsghdr), pdcp_read_header.rb_id); // LOG_D(PDCP, "[MSC_MSG][FRAME %05d][IP][MOD %02d][][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %02d][RB %02d]\n", // frame, pdcp_read_header.inst, pdcp_read_header.data_size, pdcp_read_header.inst, pdcp_read_header.rb_id); @@ -527,8 +525,72 @@ int //#else // neither NAS_NETLINK nor NAS_FIFO // return 0; //#endif // NAS_NETLINK -//#endif // NAS_FIFO #ifdef NAS_NETLINK +# if defined(ENABLE_PDCP_NETLINK_FIFO) + rb_id_t rab_id; + + struct pdcp_netlink_element_s *data = NULL; + + while (pdcp_netlink_dequeue_element(eNB_flag, UE_index, eNB_index, &data) != 0) { + if (data->pdcp_read_header.rb_id != 0) { + if (pdcp_array[data->pdcp_read_header.inst][data->pdcp_read_header.rb_id%NB_RB_MAX].instanciated_instance) { +#ifdef PDCP_DEBUG + LOG_D(PDCP, "[MSC_MSG][FRAME %05d][IP][MOD %02d][][--- PDCP_DATA_REQ " + "/ %d Bytes --->][PDCP][MOD %02d][RB %02d]\n", + frame, data->pdcp_read_header.inst, data->pdcp_read_header.data_size, + data->pdcp_read_header.inst, data->pdcp_read_header.rb_id); +#endif + + pdcp_data_req(data->pdcp_read_header.inst, + frame, + eNB_flag, + data->pdcp_read_header.rb_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + data->pdcp_read_header.data_size, + data->data, + PDCP_DATA_PDU); + } else { + LOG_E(PDCP, "Received packet for non-instanciated instance %u with rb_id %u\n", + data->pdcp_read_header.inst, data->pdcp_read_header.rb_id); + } + } else if (eNB_flag) { + /* rb_id = 0, thus interpreated as broadcast and transported as + * multiple unicast is a broadcast packet, we have to send this + * packet on all default RABS of all connected UEs + */ +#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES + for (rab_id = DEFAULT_RAB_ID; rab_id < MAX_RB; rab_id = rab_id + NB_RB_MAX) { + if (pdcp_array[pdcp_input_header.inst][rab_id%NB_RB_MAX].instanciated_instance == (pdcp_input_header.inst + 1)) { + pdcp_data_req(data->pdcp_read_header.inst, + frame, + eNB_flag, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + data->pdcp_read_header.data_size, + data->data, + PDCP_DATA_PDU); + } + } + } else { + LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); + pdcp_data_req(data->pdcp_read_header.inst, + frame, eNB_flag, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + data->pdcp_read_header.data_size, + data->data, + PDCP_DATA_PDU); + } + + free(data->data); + free(data); + data = NULL; + } + return 0; +# else int len = 1; rb_id_t rab_id = 0; @@ -546,7 +608,7 @@ int if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) { LOG_I(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n"); //return; - }; + } if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) { LOG_I(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n"); @@ -624,7 +686,7 @@ int } } return len; - +# endif #else // neither NAS_NETLINK nor NAS_FIFO return 0; #endif // NAS_NETLINK diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c new file mode 100644 index 0000000000..37bda5c3a6 --- /dev/null +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c @@ -0,0 +1,238 @@ +/******************************************************************************* + + Eurecom OpenAirInterface + Copyright(c) 1999 - 2013 Eurecom + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope 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 + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information + Openair Admin: openair_admin@eurecom.fr + Openair Tech : openair_tech@eurecom.fr + Forums : http://forums.eurecom.fsr/openairinterface + Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France + +*******************************************************************************/ + +/*! \file pdcp_netlink.c +* \brief pdcp communication with linux IP interface, +* have a look at http://man7.org/linux/man-pages/man7/netlink.7.html for netlink. +* Read operation from netlink should be achieved in an asynchronous way to avoid +* subframe overload, netlink congestion... +* \author Sebastien ROUX +* \date 2013 +* \version 0.1 +* @ingroup pdcp +*/ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <error.h> +#include <unistd.h> + +#include <linux/netlink.h> + +#include "assertions.h" +#include "queue.h" +#include "liblfds611.h" + +#include "UTIL/LOG/log.h" +#include "UTIL/OCG/OCG.h" +#include "UTIL/OCG/OCG_extern.h" +#include "LAYER2/MAC/extern.h" + +#include "pdcp.h" +#include "pdcp_primitives.h" + +#define PDCP_QUEUE_NB_ELEMENTS 200 + +extern char nl_rx_buf[NL_MAX_PAYLOAD]; +extern struct nlmsghdr *nas_nlh_rx; +extern struct iovec nas_iov_rx; +extern int nas_sock_fd; +extern struct msghdr nas_msg_rx; + +static pthread_t pdcp_netlink_thread; + +/* We use lock-free queues between the User-plane driver running in kernel-space + * and the corresponding entity in User-space. + * one queue for eNBs (index 0)/one queue for UEs (index 1) + */ +static struct lfds611_queue_state **pdcp_netlink_queue = NULL; +static uint32_t *pdcp_netlink_nb_element = NULL; + +static void *pdcp_netlink_thread_fct(void *arg); + +int pdcp_netlink_init(void) { + + int i, nb_modules; + pthread_attr_t attr; + struct sched_param sched_param; + +#if defined(USER_MODE) && defined(OAI_EMU) + nb_modules = NB_eNB_INST + NB_UE_INST; +#else + nb_modules = 1; +#endif + + pdcp_netlink_queue = calloc(nb_modules, sizeof(struct lfds611_queue_state*)); + pdcp_netlink_nb_element = malloc(nb_modules * sizeof(uint32_t)); + + LOG_I(PDCP, "Creating %d queues for Netlink -> PDCP communication\n", + nb_modules); + + for (i = 0; i < nb_modules; i++) { + pdcp_netlink_nb_element[i] = 0; + if (lfds611_queue_new(&pdcp_netlink_queue[i], PDCP_QUEUE_NB_ELEMENTS) < 0) { + LOG_E(PDCP, "Failed to create new FIFO for Netlink -> PDCP communcation instance %d\n", i); + exit(EXIT_FAILURE); + } + } + + if (pthread_attr_init(&attr) != 0) { + LOG_E(PDCP, "Failed to initialize pthread attribute for Netlink -> PDCP communication (%d:%s)\n", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + sched_param.sched_priority = 10; + + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setschedparam(&attr, &sched_param); + + /* Create one thread that fetchs packets from the netlink. + * When the netlink fifo is full, packets are silently dropped, this behaviour + * should be avoided if we want a reliable link. + */ + if (pthread_create(&pdcp_netlink_thread, &attr, pdcp_netlink_thread_fct, NULL) != 0) { + LOG_E(PDCP, "Failed to create new thread for Netlink/PDCP communcation (%d:%s)\n", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + return 0; +} + +int pdcp_netlink_dequeue_element(uint8_t eNB_flag, uint8_t UE_index, uint8_t eNB_index, + struct pdcp_netlink_element_s **data) +{ + int ret = 0; + module_id_t module_id; + +#if defined(USER_MODE) && defined(OAI_EMU) + module_id = (eNB_flag != 0) ? eNB_index : NB_eNB_INST + UE_index; +#else + module_id = 0; +#endif + + ret = lfds611_queue_dequeue(pdcp_netlink_queue[module_id], (void **)data); + + if (ret != 0) { + LOG_D(PDCP, "De-queueing packet for module %d\n", module_id); + } + return ret; +} + +static +void *pdcp_netlink_thread_fct(void *arg) { + int len; + struct pdcp_netlink_element_s *new_data = NULL; + uint8_t pdcp_read_state; + + pdcp_read_state = 0; + memset(nl_rx_buf, 0, NL_MAX_PAYLOAD); + + while (1) { + + len = recvmsg(nas_sock_fd, &nas_msg_rx, 0); + + if (len == 0) { + /* Other peer (kernel) has performed an orderly shutdown + */ + LOG_E(PDCP, "Kernel module has closed the netlink\n"); + exit(EXIT_FAILURE); + } else if (len < 0) { + /* There was an error */ + LOG_E(PDCP, "An error occured while reading netlink (%d:%s)\n", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } else { + /* Normal read. + * NOTE: netlink messages can be assembled to form a multipart message + */ + for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf; + NLMSG_OK(nas_nlh_rx, len); + nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) { + + /* There is no need to check for nlmsg_type because + * the header is not set in our drivers. + */ + if (pdcp_read_state == 0) { + new_data = malloc(sizeof(struct pdcp_netlink_element_s)); + + if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { + pdcp_read_state = 1; + memcpy((void *)&new_data->pdcp_read_header, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); + LOG_I(PDCP, "[NETLINK] RX pdcp_data_req_header_t inst %u, " + "rb_id %u data_size %d\n", + new_data->pdcp_read_header.inst, new_data->pdcp_read_header.rb_id, + new_data->pdcp_read_header.data_size); + } else { + LOG_E(PDCP, "[NETLINK] WRONG size %d should be sizeof " + "(pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n", + nas_nlh_rx->nlmsg_len); + } + } else { + pdcp_read_state = 0; + +#ifdef OAI_EMU + if (new_data->pdcp_read_header.inst >= oai_emulation.info.nb_enb_local) { + new_data->pdcp_read_header.inst = new_data->pdcp_read_header.inst + - oai_emulation.info.nb_enb_local + NB_eNB_INST + + oai_emulation.info.first_ue_local; + } else { + new_data->pdcp_read_header.inst = new_data->pdcp_read_header.inst + + oai_emulation.info.first_enb_local; + } +#else + new_data->pdcp_read_header.inst = 0; +#endif + new_data->data = malloc(sizeof(uint8_t) * new_data->pdcp_read_header.data_size); + /* Copy the data */ + memcpy(new_data->data, NLMSG_DATA(nas_nlh_rx), new_data->pdcp_read_header.data_size); + + if (pdcp_netlink_nb_element[new_data->pdcp_read_header.inst] + > PDCP_QUEUE_NB_ELEMENTS) { + LOG_E(PDCP, "[Mod %02x] We reached maximum number of elements in pdcp queue (%d)\n", + new_data->pdcp_read_header.inst, pdcp_netlink_nb_element); + } + + LOG_D(PDCP, "En-queueing packet for module %d\n", new_data->pdcp_read_header.inst); + + /* Enqueue the element in the right queue */ +// lfds611_queue_enqueue(pdcp_netlink_queue[new_data->pdcp_read_header.inst], new_data); + lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue[new_data->pdcp_read_header.inst], new_data); + } + } + } + } + return NULL; +} diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h index 10b868bc08..16bedd27ba 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h @@ -153,6 +153,9 @@ BOOL pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_b BOOL pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, \ u8 bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu); +int pdcp_netlink_dequeue_element(uint8_t eNB_flag, uint8_t UE_index, uint8_t eNB_index, + struct pdcp_netlink_element_s **data); + void pdcp_config_set_security(module_id_t module_id, u32 frame, u8 eNB_flag, rb_id_t rb_id, u16 lc_id, u8 security_mode, u8 *kRRCenc, u8 *kRRCint, u8 *kUPenc); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c index 9aff9de7d3..3cc41a16a3 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c @@ -57,6 +57,8 @@ pthread_mutex_t pdcp_mutex; pthread_cond_t pdcp_cond; int pdcp_instance_cnt; +static void *pdcp_thread_main(void* param); + static void *pdcp_thread_main(void* param) { //u8 eNB_flag = *((u8*)param); diff --git a/openair2/UTIL/FIFO/types.h b/openair2/UTIL/FIFO/types.h index 0c630d4c22..74dfe1f01e 100644 --- a/openair2/UTIL/FIFO/types.h +++ b/openair2/UTIL/FIFO/types.h @@ -69,12 +69,12 @@ typedef struct Packet_otg_elt { } Packet_otg_elt; typedef struct Job_element { - struct Job_elt *next; + struct Job_element *next; Job job; } Job_elt; typedef struct Event_element { - struct Event_elt *next; - struct Event_elt *previous; + struct Event_element *next; + struct Event_element *previous; Event event; } Event_elt; diff --git a/openair2/UTIL/OSA/osa_internal.h b/openair2/UTIL/OSA/osa_internal.h index 318549b2f7..3f0116017d 100644 --- a/openair2/UTIL/OSA/osa_internal.h +++ b/openair2/UTIL/OSA/osa_internal.h @@ -21,6 +21,6 @@ ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24)) #endif -#define SECU_DEBUG +// #define SECU_DEBUG #endif /* OSA_INTERNAL_H_ */ diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index 625fe0e403..b05bbc226f 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -24,7 +24,7 @@ void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key, } /*! - * @brief Derive the keys from kasme and perform truncate on the generated key to + * @brief Derive the keys from key and perform truncate on the generated key to * reduce his size to 128 bits. Definition of the derivation function can * be found in 3GPP TS.33401 #A.7 * @param[in] alg_type Algorithm distinguisher @@ -41,9 +41,6 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { uint8_t string[7]; -#if defined(SECU_DEBUG) - int i; -#endif /* FC */ string[0] = FC_ALG_KEY_DER; @@ -79,7 +76,7 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, return 0; } -int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB) +int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) { uint8_t string[7]; @@ -107,7 +104,7 @@ int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keN } #endif - kdf(string, 7, kasme, 32, keNB, 32); + kdf(string, 7, key, 32, keNB, 32); return 0; } diff --git a/openair2/UTIL/OTG/otg_models.c b/openair2/UTIL/OTG/otg_models.c index 19dbe763cf..6324cfbd87 100644 --- a/openair2/UTIL/OTG/otg_models.c +++ b/openair2/UTIL/OTG/otg_models.c @@ -111,7 +111,7 @@ double tarmaCalculateSample( double inputSamples[], tarmaProcess_t *proc){ */ void tarmaUpdateInputSample (tarmaStream_t *stream){ int cnt; - LOG_T(OTG,"TARMA_DEBUG: tarmaUpdateInputSample(%d)\n",(int)stream); + LOG_T(OTG,"TARMA_DEBUG: tarmaUpdateInputSample(%p)\n", stream); if(stream){ for(cnt=0; cnt<TARMA_NUM_PROCESSES; cnt++){ stream->tarma_input_samples[cnt]=gaussian_dist(10000,1)-10000; @@ -153,7 +153,7 @@ tarmaStream_t *tarmaInitStream(tarmaStream_t *stream){ proc->polyWeight[cntpy]=0; } } - LOG_D(OTG,"TARMA_DEBUG: tarmaInitStream(%d) called\n",(int)stream); + LOG_D(OTG,"TARMA_DEBUG: tarmaInitStream(%p) called\n", stream); return stream; } @@ -188,7 +188,7 @@ void tarmaPrintProc(tarmaProcess_t *proc){ char prefix[]="OTG TARMA DEBUG: "; int cntma, cntar; - printf("%s tarmaPrintProc(%d) called\n",prefix,(int)proc); + printf("%s tarmaPrintProc(%p) called\n", prefix, proc); printf("%s ma history:\n",prefix); for(cntma=0; cntma<TARMA_NUM_MA_MAX; cntma++){ printf("%s ma[%d]: %f\n",prefix,cntma,proc->maHist[cntma]); @@ -209,7 +209,7 @@ void tarmaPrintStreamInit(tarmaStream_t *stream){ tarmaProcess_t *proc; int cntvar, cntp, cntma, cntar, cntpy; - printf("%s tarmaPrintStreamInit(%d) called\n",prefix,(int)stream); + printf("%s tarmaPrintStreamInit(%p) called\n", prefix, stream); for(cntvar=0; cntvar<2; cntvar++){ if(cntvar==0){ proc=&(stream->tarma_idt); @@ -258,7 +258,7 @@ double tarmaCalculateVideoSample(tarmaVideo_t *video){ if(video){ proc=&(video->tarma_size); frameidx=video->tarmaVideoGopStructure[video->tarmaVideoFrameNumber]; - LOG_D(OTG,"TARMA_DEBUG: tarmaCalculateVideoSample(%d) called\n",(int)video); + LOG_D(OTG,"TARMA_DEBUG: tarmaCalculateVideoSample(%p) called\n", video); LOG_D(OTG,"TARMA_DEBUG: frameidx=%d\n",frameidx); if(frameidx>=0 && frameidx<=TARMA_NUM_FRAME_TYPES){ for(cntpy=0; cntpy<TARMA_NUM_POLY_MAX; cntpy++){ @@ -291,7 +291,7 @@ tarmaVideo_t *tarmaInitVideo(tarmaVideo_t *video){ tarmaProcess_t *proc; int cntp, cntma, cntar, cntpy, cntgop, cnttype; - LOG_D(OTG,"TARMA_DEBUG: tarmaInitVideo(%d) called\n",(int)video); + LOG_D(OTG,"TARMA_DEBUG: tarmaInitVideo(%p) called\n", video); if(video==0){ video=(tarmaVideo_t*) malloc(sizeof(tarmaVideo_t)); } @@ -382,7 +382,7 @@ void tarmaPrintVideoInit(tarmaVideo_t *video){ tarmaProcess_t *proc; int cntp, cntma, cntar, cntpy, cntgop, cnttype; - printf("%s tarmaPrintVideoInit(%d) called\n",prefix,(int)video); + printf("%s tarmaPrintVideoInit(%p) called\n", prefix, video); proc=&(video->tarma_size); printf("%s input process weights\n",prefix); for(cntp=0; cntp<TARMA_NUM_PROCESSES; cntp++){ @@ -482,7 +482,7 @@ backgroundStream_t *backgroundStreamInit(backgroundStream_t *stream, double lamb } } - LOG_D(OTG,"BACKGROUND_USERS DEBUG: backgroundStreamInit(%d) called\n",(int)stream); + LOG_D(OTG,"BACKGROUND_USERS DEBUG: backgroundStreamInit(%p) called\n", stream); backgroundPrintStream (stream); return stream; } @@ -496,7 +496,7 @@ backgroundStream_t *backgroundStreamInit(backgroundStream_t *stream, double lamb void backgroundUpdateStream(backgroundStream_t *stream, int ctime){ int numNewSessions, cnts, period; - LOG_D(OTG,"BACKGROUND DEBUG: backgroundUpdateStream(stream*=%d,ctime=%d,period=%d) called\n",(int)stream, ctime); + LOG_D(OTG,"BACKGROUND DEBUG: backgroundUpdateStream(stream*=%p,ctime=%d) called\n", stream, ctime); if(stream){ period=ctime-stream->lastUpdateTime; numNewSessions=poisson_dist(stream->meanNumSessions/5710*period); @@ -532,7 +532,7 @@ double backgroundCalculateSize(backgroundStream_t *stream, int ctime, int idt){ double mrate=0; backgroundUpdateStream(stream, ctime); - LOG_D(OTG,"BACKGROUND DEBUG: backgroundCalculateSize(stream*=%d,idt=%d,ctime=%d) called\n",(int)stream, idt, ctime); + LOG_D(OTG,"BACKGROUND DEBUG: backgroundCalculateSize(stream*=%p,idt=%d,ctime=%d) called\n", stream, idt, ctime); if(stream){ for(cnts=0; cnts<BACKGROUND_NUM_ACTIVE_MAX; cnts++){ if(stream->activeSessions[cnts].endTime>ctime){ @@ -554,7 +554,7 @@ double backgroundCalculateSize(backgroundStream_t *stream, int ctime, int idt){ void backgroundPrintStream(backgroundStream_t *stream){ int cnts; - LOG_D(OTG,"BACKGROUND DEBUG: backgroundPrintStream(%d)\n",(int)stream); + LOG_D(OTG,"BACKGROUND DEBUG: backgroundPrintStream(%p)\n", stream); if(stream){ LOG_D(OTG,"BACKGROUND DEBUG: meanNumSessions(lambda_n)=%f\n",stream->meanNumSessions); for(cnts=0; cnts<BACKGROUND_NUM_ACTIVE_MAX; cnts++){ diff --git a/targets/SIMU/USER/Makefile b/targets/SIMU/USER/Makefile index 4227e7fa93..b46ca33c2f 100644 --- a/targets/SIMU/USER/Makefile +++ b/targets/SIMU/USER/Makefile @@ -247,6 +247,7 @@ endif CFLAGS += -DENABLE_VCD_FIFO CFLAGS += -DENABLE_NEW_MULTICAST +CFLAGS += -DENABLE_PDCP_NETLINK_FIFO # CFLAGS += -DENABLE_LOG_FIFO # Check if libpgm is installed and use it if found instead of the unreliable diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 7354c2d274..8a8aacce06 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -405,7 +405,6 @@ void check_and_adjust_params() { if (ret < 0) LOG_E(EMU,"[INIT] Netlink not available, careful ...\n"); - if (ethernet_flag == 1) { oai_emulation.info.master[oai_emulation.info.master_id].nb_ue = oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local; oai_emulation.info.master[oai_emulation.info.master_id].nb_enb = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_rn_local; @@ -434,6 +433,10 @@ void check_and_adjust_params() { NB_eNB_INST = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_enb_remote; NB_RN_INST = oai_emulation.info.nb_rn_local + oai_emulation.info.nb_rn_remote; +#if defined(ENABLE_PDCP_NETLINK_FIFO) + pdcp_netlink_init(); +#endif + if (NB_RN_INST > 0 ) { LOG_N(EMU,"Total number of RN %d (local %d, remote %d) mobility (the same as eNB) %s \n", NB_RN_INST,oai_emulation.info.nb_rn_local,oai_emulation.info.nb_rn_remote, oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option); -- GitLab