Commit 8fa56022 authored by Cedric Roux's avatar Cedric Roux

- Added thread that fetch netlink packets and place them in a FIFO (option...

- 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
parent e03b125c
...@@ -169,7 +169,8 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne ...@@ -169,7 +169,8 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne
return(dlsch); 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); free_eNB_dlsch(dlsch);
return(NULL); return(NULL);
......
...@@ -120,7 +120,7 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint8_t max_turbo_ite ...@@ -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) if (exit_flag==0)
return(dlsch); 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); free_ue_dlsch(dlsch);
return(NULL); return(NULL);
......
...@@ -43,11 +43,13 @@ int netlink_init(void) ...@@ -43,11 +43,13 @@ int netlink_init(void)
} }
printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd); 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); ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK);
if (ret == -1) { if (ret == -1) {
printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno)); printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno));
// exit(1); // exit(1);
} }
#endif
memset(&nas_src_addr, 0, sizeof(nas_src_addr)); memset(&nas_src_addr, 0, sizeof(nas_src_addr));
nas_src_addr.nl_family = AF_NETLINK; nas_src_addr.nl_family = AF_NETLINK;
......
...@@ -27,6 +27,7 @@ SOURCES_L2 += $(PDCP_DIR)/pdcp_sequence_manager.c ...@@ -27,6 +27,7 @@ SOURCES_L2 += $(PDCP_DIR)/pdcp_sequence_manager.c
SOURCES_L2 += $(PDCP_DIR)/pdcp_primitives.c SOURCES_L2 += $(PDCP_DIR)/pdcp_primitives.c
SOURCES_L2 += $(PDCP_DIR)/pdcp_util.c SOURCES_L2 += $(PDCP_DIR)/pdcp_util.c
SOURCES_L2 += $(PDCP_DIR)/pdcp_security.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.c
SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_init.c SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_init.c
......
...@@ -82,8 +82,8 @@ extern int otg_rx_pkt( int src, int dst, int ctime, char *buffer_tx, unsigned in ...@@ -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, \ 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) unsigned char* sdu_buffer, pdcp_t* test_pdcp_entity, list_t* test_list)
#else #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, \ 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) sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer, u8 mode)
#endif #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 ...@@ -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); 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); rlc_status = rlc_data_req(module_id, frame, eNB_flag, RLC_MBMS_YES, rb_id, muiP, confirmP, sdu_buffer_size, pdcp_pdu);
} else } else
rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES; rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES;
} else { } else {
// calculate the pdcp header and trailer size // calculate the pdcp header and trailer size
if ((rb_id % NB_RB_MAX) < DTCH) { 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 ...@@ -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_tailer_len = 0;
} }
pdcp_pdu_size= sdu_buffer_size + pdcp_header_len + pdcp_tailer_len; 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); 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) * 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); 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); pdcp_pdu = get_free_mem_block(pdcp_pdu_size);
if (pdcp_pdu != NULL) { if (pdcp_pdu != NULL) {
/* /*
* Create a Data PDU with header and append data * 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 ...@@ -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); "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) { 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; 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 ...@@ -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 void pdcp_run (u32_t frame, u8 eNB_flag, u8 UE_index, u8 eNB_index) {
pdcp_run (u32_t frame, u8 eNB_flag, u8 UE_index, u8 eNB_index) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef NAS_NETLINK #ifndef NAS_NETLINK
#ifdef USER_MODE #ifdef USER_MODE
#define PDCP_DUMMY_BUFFER_SIZE 38 #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
#endif #endif
// unsigned int diff, i, k, j; // unsigned int diff, i, k, j;
...@@ -487,7 +486,7 @@ void ...@@ -487,7 +486,7 @@ void
// int pkt_size=0; // int pkt_size=0;
// unsigned int ctime=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) { if ((frame % 128) == 0) {
...@@ -510,10 +509,10 @@ void ...@@ -510,10 +509,10 @@ void
pdcp_fifo_read_input_sdus_from_otg(frame, eNB_flag, UE_index, eNB_index); 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 // 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 -> 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); 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 ...@@ -531,21 +530,21 @@ BOOL rrc_pdcp_config_asn1_req (module_id_t module_id, u32_t frame, u8_t eNB_flag
#endif #endif
){ ){
long int rb_id = 0; long int rb_id = 0;
long int lc_id = 0; long int lc_id = 0;
long int srb_id = 0; long int srb_id = 0;
long int mch_id = 0; long int mch_id = 0;
rlc_mode_t rlc_type = RLC_NONE; rlc_mode_t rlc_type = RLC_NONE;
DRB_Identity_t drb_id = 0; DRB_Identity_t drb_id = 0;
DRB_Identity_t* pdrb_id = NULL; DRB_Identity_t* pdrb_id = NULL;
u8 drb_sn = 0; u8 drb_sn = 0;
u8 srb_sn = 5; // fixed sn for SRBs u8 srb_sn = 5; // fixed sn for SRBs
u8 drb_report = 0; u8 drb_report = 0;
long int cnt = 0; long int cnt = 0;
u16 header_compression_profile = 0; u16 header_compression_profile = 0;
u32 action = ACTION_ADD; u32 action = ACTION_ADD;
SRB_ToAddMod_t* srb_toaddmod = NULL; SRB_ToAddMod_t* srb_toaddmod = NULL;
DRB_ToAddMod_t* drb_toaddmod = NULL; DRB_ToAddMod_t* drb_toaddmod = NULL;
#ifdef Rel10 #ifdef Rel10
int i,j; 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 ...@@ -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) { if (drb2release_list != NULL) {
for (cnt=0;cnt<drb2add_list->list.count;cnt++) { for (cnt=0;cnt<drb2add_list->list.count;cnt++) {
pdrb_id = drb2release_list->list.array[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; action = ACTION_REMOVE;
pdcp_config_req_asn1 (module_id, pdcp_config_req_asn1 (module_id,
frame, frame,
......
...@@ -91,7 +91,6 @@ extern pthread_mutex_t pdcp_mutex; ...@@ -91,7 +91,6 @@ extern pthread_mutex_t pdcp_mutex;
extern pthread_cond_t pdcp_cond; extern pthread_cond_t pdcp_cond;
extern int pdcp_instance_cnt; extern int pdcp_instance_cnt;
static void *pdcp_thread_main(void* param);
int init_pdcp_thread(void); int init_pdcp_thread(void);
void cleanup_pdcp_thread(void); void cleanup_pdcp_thread(void);
...@@ -343,13 +342,14 @@ public_pdcp(int pdcp_module_init ();) ...@@ -343,13 +342,14 @@ public_pdcp(int pdcp_module_init ();)
public_pdcp(void pdcp_module_cleanup ();) public_pdcp(void pdcp_module_cleanup ();)
public_pdcp(void pdcp_layer_init ();) public_pdcp(void pdcp_layer_init ();)
public_pdcp(void pdcp_layer_cleanup ();) public_pdcp(void pdcp_layer_cleanup ();)
public_pdcp(int pdcp_netlink_init(void);)
#define PDCP2NAS_FIFO 21 #define PDCP2NAS_FIFO 21
#define NAS2PDCP_FIFO 22 #define NAS2PDCP_FIFO 22
protected_pdcp_fifo(int pdcp_fifo_flush_sdus (u32_t,u8_t);) 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_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);) 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 { ...@@ -368,6 +368,13 @@ typedef struct pdcp_data_ind_header_t {
int inst; int inst;
} pdcp_data_ind_header_t; } 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 #if 0
/* /*
* Missing PDU information struct, a copy of this will be enqueued * Missing PDU information struct, a copy of this will be enqueued
......
...@@ -93,8 +93,7 @@ extern Packet_OTG_List *otg_pdcp_buffer; ...@@ -93,8 +93,7 @@ extern Packet_OTG_List *otg_pdcp_buffer;
pdcp_data_req_header_t pdcp_read_header; pdcp_data_req_header_t pdcp_read_header;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int int pdcp_fifo_flush_sdus (u32_t frame,u8 eNB_flag)
pdcp_fifo_flush_sdus (u32_t frame,u8 eNB_flag)
{ {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -170,7 +169,7 @@ int ...@@ -170,7 +169,7 @@ int
ret = sendmsg(nas_sock_fd,&nas_msg_tx,0); ret = sendmsg(nas_sock_fd,&nas_msg_tx,0);
if (ret<0) { if (ret<0) {
LOG_D(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno); 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; break;
} }
#endif // LINUX #endif // LINUX
...@@ -350,8 +349,7 @@ int ...@@ -350,8 +349,7 @@ int
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int int pdcp_fifo_read_input_sdus (u32_t frame, u8_t eNB_flag, u8_t UE_index, u8_t eNB_index)
pdcp_fifo_read_input_sdus (u32_t frame, u8_t eNB_flag)
{ {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//#ifdef NAS_FIFO //#ifdef NAS_FIFO
...@@ -426,11 +424,11 @@ int ...@@ -426,11 +424,11 @@ int
// } else { // } else {
//#ifdef PDCP_DEBUG //#ifdef PDCP_DEBUG
//#ifdef LINUX //#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)); // len, nas_nlh->nlmsg_len-sizeof(struct nlmsghdr));
//#else //#else
// LOG_I(PDCP, "[PDCP][NETLINK] nlmsg_len = %d (%d,%d)\n", \ // LOG_I(PDCP, "[PDCP][NETLINK] nlmsg_len = %d (%d,%d)\n",
// nas_nlh->nlmsg_len, sizeof(pdcp_data_req_header_t), \ // nas_nlh->nlmsg_len, sizeof(pdcp_data_req_header_t),
// sizeof(struct nlmsghdr)); // sizeof(struct nlmsghdr));
//#endif //#endif
//#endif //#endif
...@@ -465,7 +463,7 @@ int ...@@ -465,7 +463,7 @@ int
//#endif //#endif
// //
//#ifdef OAI_EMU //#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.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local :
// pdcp_read_header.inst + oai_emulation.info.first_enb_local; // pdcp_read_header.inst + oai_emulation.info.first_enb_local;
//#else //#else
...@@ -475,7 +473,7 @@ int ...@@ -475,7 +473,7 @@ int
// if (pdcp_read_header.rb_id != 0) { // if (pdcp_read_header.rb_id != 0) {
// if (pdcp_array[pdcp_read_header.inst][pdcp_read_header.rb_id].instanciated_instance) { // if (pdcp_array[pdcp_read_header.inst][pdcp_read_header.rb_id].instanciated_instance) {
//#ifdef PDCP_DEBUG //#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); // 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", // 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); // frame, pdcp_read_header.inst, pdcp_read_header.data_size, pdcp_read_header.inst, pdcp_read_header.rb_id);
...@@ -527,8 +525,72 @@ int ...@@ -527,8 +525,72 @@ int
//#else // neither NAS_NETLINK nor NAS_FIFO //#else // neither NAS_NETLINK nor NAS_FIFO
// return 0; // return 0;
//#endif // NAS_NETLINK //#endif // NAS_NETLINK
//#endif // NAS_FIFO
#ifdef NAS_NETLINK #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; int len = 1;
rb_id_t rab_id = 0; rb_id_t rab_id = 0;
...@@ -546,7 +608,7 @@ int ...@@ -546,7 +608,7 @@ int
if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) { if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) {
LOG_I(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n"); LOG_I(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n");
//return; //return;
}; }
if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) { if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) {
LOG_I(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n"); LOG_I(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n");
...@@ -624,7 +686,7 @@ int ...@@ -624,7 +686,7 @@ int
} }
} }
return len; return len;
# endif
#else // neither NAS_NETLINK nor NAS_FIFO #else // neither NAS_NETLINK nor NAS_FIFO
return 0; return 0;
#endif // NAS_NETLINK #endif // NAS_NETLINK
......
/*******************************************************************************
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);