//----------------------------------------------------------------------------- void rlc_um_send_sdu (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP) { //----------------------------------------------------------------------------- if ((rlc_pP->output_sdu_in_construction)) { LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" SEND_SDU to upper layers %d bytes sdu %p\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->output_sdu_size_to_write, rlc_pP->output_sdu_in_construction); if (rlc_pP->output_sdu_size_to_write > 0) { rlc_pP->stat_rx_pdcp_sdu += 1; rlc_pP->stat_rx_pdcp_bytes += rlc_pP->output_sdu_size_to_write; MSC_LOG_TX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (const char*)(rlc_pP->output_sdu_in_construction->data), rlc_pP->output_sdu_size_to_write, MSC_AS_TIME_FMT" "PROTOCOL_RLC_UM_MSC_FMT" DATA-IND size %u", MSC_AS_TIME_ARGS(ctxt_pP), PROTOCOL_RLC_UM_MSC_ARGS(ctxt_pP,rlc_pP), rlc_pP->output_sdu_size_to_write ); #ifdef TEST_RLC_UM #ifdef TRACE_RLC_UM_DISPLAY_ASCII_DATA rlc_pP->output_sdu_in_construction->data[rlc_pP->output_sdu_size_to_write] = 0; LOG_T(RLC, PROTOCOL_RLC_UM_CTXT_FMT"[SEND_SDU] DATA :", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP)); rlc_util_print_hex_octets(RLC, rlc_pP->output_sdu_in_construction->data, rlc_pP->output_sdu_size_to_write); #endif rlc_um_v9_3_0_test_data_ind (rlc_pP->module_id, rlc_pP->rb_id, rlc_pP->output_sdu_size_to_write, rlc_pP->output_sdu_in_construction); #else // msg("[RLC] DATA IND ON MOD_ID %d RB ID %d, size %d\n",rlc_pP->module_id, rlc_pP->rb_id, ctxt_pP->frame,rlc_pP->output_sdu_size_to_write); rlc_data_ind ( ctxt_pP, BOOL_NOT(rlc_pP->is_data_plane), rlc_pP->is_mxch, rlc_pP->rb_id, rlc_pP->output_sdu_size_to_write, rlc_pP->output_sdu_in_construction); #endif rlc_pP->output_sdu_in_construction = NULL; } else { LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT"[SEND_SDU] ERROR SIZE <= 0 ... DO NOTHING, SET SDU SIZE TO 0\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP)); } rlc_pP->output_sdu_size_to_write = 0; } }
//----------------------------------------------------------------------------- int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) { //----------------------------------------------------------------------------- mem_block_t *sdu_p = list_get_head (&pdcp_sdu_list); int bytes_wrote = 0; int pdcp_nb_sdu_sent = 0; uint8_t cont = 1; #if defined(LINK_ENB_PDCP_TO_GTPV1U) //MessageDef *message_p = NULL; #endif #if defined(PDCP_USE_NETLINK) && defined(LINUX) int ret = 0; #endif while (sdu_p && cont) { #if ! defined(OAI_EMU) ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) if (ctxt_pP->enb_flag) { AssertFatal(0, "Now execution should not go here"); LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); gtpv1u_new_data_req( ctxt_pP->module_id, //gtpv1u_data_t *gtpv1u_data_p, ctxt_pP->rnti,//rb_id/maxDRB, TO DO UE ID ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4, &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]), ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu_p); cont = 1; pdcp_nb_sdu_sent += 1; sdu_p = list_get_head (&pdcp_sdu_list); LOG_D(OTG,"After GTPV1U\n"); continue; // loop again } #endif /* defined(ENABLE_USE_MME) */ #ifdef PDCP_DEBUG LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); #endif //PDCP_DEBUG cont = 0; if (!pdcp_output_sdu_bytes_to_write) { if (!pdcp_output_header_bytes_to_write) { pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t); } #ifdef PDCP_USE_RT_FIFO bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), pdcp_output_header_bytes_to_write); #else #ifdef PDCP_USE_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh_tx), &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), pdcp_output_header_bytes_to_write); nas_nlh_tx->nlmsg_len = pdcp_output_header_bytes_to_write; #endif //LINUX #endif //PDCP_USE_NETLINK bytes_wrote = pdcp_output_header_bytes_to_write; #endif //PDCP_USE_RT_FIFO #ifdef PDCP_DEBUG LOG_D(PDCP, "Frame %d Sent %d Bytes of header to Nas_mesh\n", ctxt_pP->frame, bytes_wrote); #endif //PDCP_DEBUG if (bytes_wrote > 0) { pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote; if (!pdcp_output_header_bytes_to_write) { // continue with sdu pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu_p->data)->data_size; #ifdef PDCP_USE_RT_FIFO bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); #else #ifdef PDCP_USE_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh_tx)+sizeof(pdcp_data_ind_header_t), &(sdu_p->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); nas_nlh_tx->nlmsg_len += pdcp_output_sdu_bytes_to_write; 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); MSC_LOG_TX_MESSAGE_FAILED( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL, 0, MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); mac_xface->macphy_exit("sendmsg failed for nas_sock_fd\n"); break; } else { MSC_LOG_TX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL, 0, MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); } #endif // LINUX #endif //PDCP_USE_NETLINK bytes_wrote= pdcp_output_sdu_bytes_to_write; #endif // PDCP_USE_RT_FIFO #ifdef PDCP_DEBUG LOG_D(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to higher layers\n", ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, bytes_wrote, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); #endif //PDCP_DEBUG if (bytes_wrote > 0) { pdcp_output_sdu_bytes_to_write -= bytes_wrote; if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU // LOG_D(PDCP, "rb sent a sdu qos_sap %d\n", sapiP); LOG_D(PDCP, "[FRAME %05d][xxx][PDCP][MOD xx/xx][RB %u][--- PDCP_DATA_IND / %d Bytes --->][IP][INSTANCE %u][RB %u]\n", ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu_p); cont = 1; pdcp_nb_sdu_sent += 1; sdu_p = list_get_head (&pdcp_sdu_list); } } else { LOG_W(PDCP, "RADIO->IP SEND SDU CONGESTION!\n"); } } else { LOG_W(PDCP, "RADIO->IP SEND SDU CONGESTION!\n"); } } } else { // continue writing sdu #ifdef PDCP_USE_RT_FIFO bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, (uint8_t *) (&(sdu_p->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size - pdcp_output_sdu_bytes_to_write])), pdcp_output_sdu_bytes_to_write); #else // PDCP_USE_RT_FIFO bytes_wrote = pdcp_output_sdu_bytes_to_write; #endif // PDCP_USE_RT_FIFO if (bytes_wrote > 0) { pdcp_output_sdu_bytes_to_write -= bytes_wrote; if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU //PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n"); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu_p); cont = 1; pdcp_nb_sdu_sent += 1; sdu_p = list_get_head (&pdcp_sdu_list); // LOG_D(PDCP, "rb sent a sdu from rab\n"); } } } } #ifdef PDCP_USE_RT_FIFO if ((pdcp_nb_sdu_sent)) { if ((pdcp_2_nas_irq > 0)) { #ifdef PDCP_DEBUG LOG_D(PDCP, "Frame %d : Trigger NAS RX interrupt\n", ctxt_pP->frame); #endif //PDCP_DEBUG rt_pend_linux_srq (pdcp_2_nas_irq); } else { LOG_E(PDCP, "Frame %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n", ctxt_pP->frame, pdcp_2_nas_irq); } } #endif //PDCP_USE_RT_FIFO return pdcp_nb_sdu_sent; }
//----------------------------------------------------------------------------- int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) { #ifdef PDCP_USE_NETLINK protocol_ctxt_t ctxt_cpy = *ctxt_pP; protocol_ctxt_t ctxt; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; struct pdcp_netlink_element_s* data_p = NULL; module_id_t ue_id = 0; pdcp_t* pdcp_p = NULL; # if defined(PDCP_USE_NETLINK_QUEUES) rb_id_t rab_id = 0; pdcp_transmission_mode_t pdcp_mode = PDCP_TRANSMISSION_MODE_UNKNOWN; while (pdcp_netlink_dequeue_element(ctxt_pP, &data_p) != 0) { DevAssert(data_p != NULL); rab_id = data_p->pdcp_read_header.rb_id % maxDRB; // ctxt_pP->rnti is NOT_A_RNTI ctxt_cpy.rnti = pdcp_module_id_to_rnti[ctxt_cpy.module_id][data_p->pdcp_read_header.inst]; key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_cpy.rnti, ctxt_pP->enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); if (h_rc != HASH_TABLE_OK) { LOG_W(PDCP, PROTOCOL_CTXT_FMT" Dropped IP PACKET cause no PDCP instanciated\n", PROTOCOL_CTXT_ARGS(ctxt_pP)); free(data_p->data); free(data_p); data_p = NULL; continue; } CHECK_CTXT_ARGS(&ctxt_cpy); AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); if (rab_id != 0) { LOG_D(PDCP, "[FRAME %05d][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ " "/ %d Bytes --->][PDCP][MOD %u][RB %u]\n", ctxt_cpy.frame, (ctxt_cpy.enb_flag) ? "eNB" : "UE", data_p->pdcp_read_header.inst, data_p->pdcp_read_header.rb_id, data_p->pdcp_read_header.data_size, ctxt_cpy.module_id, rab_id); #ifdef OAI_NW_DRIVER_TYPE_ETHERNET if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ || (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ || (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) { #if defined (Rel10) PDCP_TRANSMISSION_MODE_TRANSPARENT; #else pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; #endif } else if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_UNICAST) /* TRAFFIC_IPV6_TYPE_UNICAST */ || (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_UNICAST) /*TRAFFIC_IPV4_TYPE_UNICAST*/ ) { pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; } else { pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; LOG_W(PDCP,"unknown IP traffic type \n"); } #else // OAI_NW_DRIVER_TYPE_ETHERNET NASMESH driver does not curreenlty support multicast traffic pdcp_mode = PDCP_TRANSMISSION_MODE_DATA; #endif pdcp_data_req(&ctxt_cpy, SRB_FLAG_NO, rab_id % maxDRB, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, data_p->pdcp_read_header.data_size, data_p->data, pdcp_mode); } else if (ctxt_cpy.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 */ LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID first_ue_local %u nb_ue_local %u\n", oai_emulation.info.first_ue_local, oai_emulation.info.nb_ue_local); for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { if (pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id); ctxt.module_id = ctxt_cpy.module_id; ctxt.rnti = ctxt_cpy.pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; pdcp_data_req( &ctxt, SRB_FLAG_NO, DEFAULT_RAB_ID, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, data_p->pdcp_read_header.data_size, data_p->data, PDCP_TRANSMISSION_MODE_DATA); } } } else { LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); pdcp_data_req( &ctxt_cpy, SRB_FLAG_NO, DEFAULT_RAB_ID, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, data_p->pdcp_read_header.data_size, data_p->data, PDCP_TRANSMISSION_MODE_DATA); } free(data_p->data); free(data_p); data_p = NULL; } return 0; # else /* PDCP_USE_NETLINK_QUEUES*/ int len = 1; rb_id_t rab_id = 0; while (len > 0) { len = recvmsg(nas_sock_fd, &nas_msg_rx, 0); if (len<=0) { // nothing in pdcp NAS socket //LOG_D(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len); } else { for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf; NLMSG_OK (nas_nlh_rx, len); nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) { if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) { LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n"); //return; } if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) { LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n"); } if (pdcp_read_state_g == 0) { if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { pdcp_read_state_g = 1; //get memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d\n", pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size); } else { LOG_E(PDCP, "[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_g = 0; // print_active_requests() #ifdef PDCP_DEBUG LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %d \n", nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr)); #endif #ifdef OAI_EMU // overwrite function input parameters, because only one netlink socket for all instances if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) { ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_YES; ctxt.module_id = pdcp_read_header_g.inst + oai_emulation.info.first_enb_local; ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / maxDRB + oai_emulation.info.first_ue_local]; rab_id = pdcp_read_header_g.rb_id % maxDRB; } else { ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_NO; ctxt.module_id = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; rab_id = pdcp_read_header_g.rb_id; } CHECK_CTXT_ARGS(&ctxt); AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); /*LGpdcp_read_header.inst = (pdcp_read_header_g.inst >= oai_emulation.info.nb_enb_local) ? \ pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/ #else // OAI_EMU pdcp_read_header_g.inst = 0; #warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; if (ctxt_cpy.enb_flag) { ctxt.module_id = 0; rab_id = pdcp_read_header_g.rb_id % maxDRB; ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index]; } else { ctxt.module_id = 0; rab_id = pdcp_read_header_g.rb_id % maxDRB; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; } #endif if (ctxt.enb_flag) { if (rab_id != 0) { rab_id = rab_id % maxDRB; key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); if (h_rc == HASH_TABLE_OK) { #ifdef PDCP_DEBUG LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n", ctxt.frame, pdcp_read_header_g.inst, len, nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), pdcp_read_header_g.rb_id); #endif MSC_LOG_RX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL, 0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, rab_id, pdcp_read_header_g.data_size); LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n", ctxt_cpy.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size, ctxt.module_id, ctxt.rnti, rab_id); pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA); } else { LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size, ctxt.module_id, ctxt.rnti, rab_id); } } else { // 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 (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size, ctxt.module_id, ctxt.rnti, DEFAULT_RAB_ID); pdcp_data_req ( &ctxt, SRB_FLAG_NO, DEFAULT_RAB_ID, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA); } } } } else { // enb_flag if (rab_id != 0) { rab_id = rab_id % maxDRB; key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); if (h_rc == HASH_TABLE_OK) { #ifdef PDCP_DEBUG LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n", ctxt.frame, pdcp_read_header_g.inst, len, nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), pdcp_read_header_g.rb_id); LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size, ctxt.module_id, ctxt.rnti, rab_id); #endif MSC_LOG_RX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL, 0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, rab_id, pdcp_read_header_g.data_size); pdcp_data_req( &ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA); } else { MSC_LOG_RX_DISCARDED_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL, 0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, rab_id, pdcp_read_header_g.data_size); LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size, ctxt.module_id, ctxt.rnti, rab_id, key); } } else { LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size, ctxt.module_id, ctxt.rnti, DEFAULT_RAB_ID); MSC_LOG_RX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL,0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, DEFAULT_RAB_ID, pdcp_read_header_g.data_size); pdcp_data_req ( &ctxt, SRB_FLAG_NO, DEFAULT_RAB_ID, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA); } } } } } } return len; # endif #else // neither PDCP_USE_NETLINK nor PDCP_USE_RT_FIFO return 0; #endif // PDCP_USE_NETLINK }
//----------------------------------------------------------------------------- void rlc_am_send_sdu ( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP) { # if TRACE_RLC_UM_PDU char message_string[7000]; size_t message_string_size = 0; #if ENABLE_ITTI MessageDef *msg_p; #endif int octet_index, index; #endif if ((rlc_pP->output_sdu_in_construction)) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND_SDU] %d bytes sdu %p\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->output_sdu_size_to_write, rlc_pP->output_sdu_in_construction); if (rlc_pP->output_sdu_size_to_write > 0) { rlc_pP->stat_rx_pdcp_sdu += 1; rlc_pP->stat_rx_pdcp_bytes += rlc_pP->output_sdu_size_to_write; #if TEST_RLC_AM rlc_am_v9_3_0_test_data_ind (rlc_pP->module_id, rlc_pP->rb_id, rlc_pP->output_sdu_size_to_write, rlc_pP->output_sdu_in_construction); #else # if TRACE_RLC_AM_PDU message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_pP->rb_id); message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", rlc_pP->output_sdu_size_to_write); message_string_size += sprintf(&message_string[message_string_size], "\nPayload : \n"); message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n"); message_string_size += sprintf(&message_string[message_string_size], " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"); message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n"); for (octet_index = 0; octet_index < rlc_pP->output_sdu_size_to_write; octet_index++) { if ((octet_index % 16) == 0) { if (octet_index != 0) { message_string_size += sprintf(&message_string[message_string_size], " |\n"); } message_string_size += sprintf(&message_string[message_string_size], " %04d |", octet_index); } /* * Print every single octet in hexadecimal form */ message_string_size += sprintf(&message_string[message_string_size], " %02x", rlc_pP->output_sdu_in_construction->data[octet_index]); /* * Align newline and pipes according to the octets in groups of 2 */ } /* * Append enough spaces and put final pipe */ for (index = octet_index; index < 16; ++index) { message_string_size += sprintf(&message_string[message_string_size], " "); } message_string_size += sprintf(&message_string[message_string_size], " |\n"); # if ENABLE_ITTI msg_p = itti_alloc_new_message_sized (ctxt_pP->enb_flag > 0 ? TASK_RLC_ENB:TASK_RLC_UE , RLC_AM_SDU_IND, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rlc_am_sdu_ind.size = message_string_size; memcpy(&msg_p->ittiMsg.rlc_am_sdu_ind.text, message_string, message_string_size); itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); # else LOG_T(RLC, "%s", message_string); # endif # endif #if !ENABLE_ITTI RLC_AM_MUTEX_UNLOCK(&rlc_pP->lock_input_sdus); #endif MSC_LOG_TX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (const char*)(rlc_pP->output_sdu_in_construction->data), rlc_pP->output_sdu_size_to_write, MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" DATA-IND size %u", MSC_AS_TIME_ARGS(ctxt_pP), PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP), rlc_pP->output_sdu_size_to_write ); rlc_data_ind (ctxt_pP, BOOL_NOT(rlc_pP->is_data_plane), MBMS_FLAG_NO, rlc_pP->rb_id, rlc_pP->output_sdu_size_to_write, rlc_pP->output_sdu_in_construction); #if !ENABLE_ITTI RLC_AM_MUTEX_LOCK(&rlc_pP->lock_input_sdus, ctxt_pP, rlc_pP); #endif #endif rlc_pP->output_sdu_in_construction = NULL; } else { LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND_SDU] ERROR SIZE <= 0 ... DO NOTHING, SET SDU SIZE TO 0\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); //msg("[RLC_AM][MOD %d] Freeing mem_block ...\n", rlc_pP->module_id); //free_mem_block (rlc_pP->output_sdu_in_construction); AssertFatal(3==4, PROTOCOL_RLC_AM_CTXT_FMT" SEND SDU REQUESTED %d bytes", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->output_sdu_size_to_write); } rlc_pP->output_sdu_size_to_write = 0; } }
void config_req_rlc_um_asn1 ( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t mbms_flagP, const mbms_session_id_t mbms_session_idP, const mbms_service_id_t mbms_service_idP, const UL_UM_RLC_t * const ul_rlc_pP, const DL_UM_RLC_t * const dl_rlc_pP, const rb_id_t rb_idP) { uint32_t ul_sn_FieldLength = 0; uint32_t dl_sn_FieldLength = 0; uint32_t t_Reordering = 0; rlc_union_t *rlc_union_p = NULL; rlc_um_entity_t *rlc_p = NULL; hash_key_t key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); hashtable_rc_t h_rc; #if Rel10 if (mbms_flagP) { AssertFatal(dl_rlc_pP, "No RLC UM DL config"); AssertFatal(ul_rlc_pP == NULL, "RLC UM UL config present"); key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_service_idP, mbms_session_idP); h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); AssertFatal (h_rc == HASH_TABLE_OK, "RLC NOT FOUND enb id %u rnti %i enb flag %u service id %u, session id %u", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_service_idP, mbms_session_idP); rlc_p = &rlc_union_p->rlc.um; } else #endif { key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); AssertFatal (h_rc == HASH_TABLE_OK, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %u, srb flag %u", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); rlc_p = &rlc_union_p->rlc.um; } //----------------------------------------------------------------------------- LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%dms sn_field_length= RB %u \n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), (dl_rlc_pP && dl_rlc_pP->t_Reordering<31)?t_Reordering_tab[dl_rlc_pP->t_Reordering]:-1, rb_idP); rlc_um_init(ctxt_pP, rlc_p); if (rlc_um_fsm_notify_event (ctxt_pP, rlc_p, RLC_UM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) { rlc_um_set_debug_infos(ctxt_pP,rlc_p, srb_flagP, rb_idP); if (ul_rlc_pP != NULL) { switch (ul_rlc_pP->sn_FieldLength) { case SN_FieldLength_size5: ul_sn_FieldLength = 5; break; case SN_FieldLength_size10: ul_sn_FieldLength = 10; break; default: LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID UL sn_FieldLength %d, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, ul_rlc_pP->sn_FieldLength); MSC_LOG_RX_DISCARDED_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RRC_ENB:MSC_RRC_UE, NULL, 0, MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" CONFIG-REQ UL sn_FieldLength %u", MSC_AS_TIME_ARGS(ctxt_pP), PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc_p), ul_rlc_pP->sn_FieldLength); return; } } if (dl_rlc_pP != NULL) { switch (dl_rlc_pP->sn_FieldLength) { case SN_FieldLength_size5: dl_sn_FieldLength = 5; break; case SN_FieldLength_size10: dl_sn_FieldLength = 10; break; default: LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID DL sn_FieldLength %d, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, dl_rlc_pP->sn_FieldLength); MSC_LOG_RX_DISCARDED_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RRC_ENB:MSC_RRC_UE, NULL, 0, MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" CONFIG-REQ DL sn_FieldLength %u", MSC_AS_TIME_ARGS(ctxt_pP), PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc_p), dl_rlc_pP->sn_FieldLength); return; } if (dl_rlc_pP->t_Reordering<T_Reordering_spare1) { t_Reordering = t_Reordering_tab[dl_rlc_pP->t_Reordering]; } else { LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID T_Reordering %d, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, dl_rlc_pP->t_Reordering); MSC_LOG_RX_DISCARDED_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RRC_ENB:MSC_RRC_UE, NULL, 0, MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" CONFIG-REQ t_Reord %u", MSC_AS_TIME_ARGS(ctxt_pP), PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc_p), dl_rlc_pP->t_Reordering); return; } } if (ctxt_pP->enb_flag > 0) { rlc_um_configure(ctxt_pP,rlc_p, t_Reordering, ul_sn_FieldLength, dl_sn_FieldLength, mbms_flagP); MSC_LOG_RX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RRC_ENB:MSC_RRC_UE, NULL, 0, MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" CONFIG-REQ t_Reord %u rx snfl %u tx snfl %u", MSC_AS_TIME_ARGS(ctxt_pP), PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc_p), t_Reordering, ul_sn_FieldLength, dl_sn_FieldLength); } else { rlc_um_configure(ctxt_pP,rlc_p, t_Reordering, dl_sn_FieldLength, ul_sn_FieldLength, mbms_flagP); MSC_LOG_RX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RRC_ENB:MSC_RRC_UE, NULL, 0, MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" CONFIG-REQ t_Reord %u rx snfl %u tx snfl %u", MSC_AS_TIME_ARGS(ctxt_pP), PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc_p), t_Reordering, dl_sn_FieldLength, ul_sn_FieldLength); } } }