//----------------------------------------------------------------------------- void rlc_am_configure( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlc_pP, const uint16_t max_retx_thresholdP, const uint16_t poll_pduP, const uint16_t poll_byteP, const uint32_t t_poll_retransmitP, const uint32_t t_reorderingP, const uint32_t t_status_prohibitP) //----------------------------------------------------------------------------- { if (rlc_pP->configured == TRUE) { LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB AM %u][RECONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rlc_pP->rb_id, max_retx_thresholdP, poll_pduP, poll_byteP, t_poll_retransmitP, t_reorderingP, t_status_prohibitP); rlc_pP->max_retx_threshold = max_retx_thresholdP; rlc_pP->poll_pdu = poll_pduP; rlc_pP->poll_byte = poll_byteP; rlc_pP->protocol_state = RLC_DATA_TRANSFER_READY_STATE; rlc_pP->t_poll_retransmit.time_out = t_poll_retransmitP; rlc_pP->t_reordering.time_out = t_reorderingP; rlc_pP->t_status_prohibit.time_out = t_status_prohibitP; } else { LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB AM %u][CONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rlc_pP->rb_id, max_retx_thresholdP, poll_pduP, poll_byteP, t_poll_retransmitP, t_reorderingP, t_status_prohibitP); rlc_pP->max_retx_threshold = max_retx_thresholdP; rlc_pP->poll_pdu = poll_pduP; rlc_pP->poll_byte = poll_byteP; rlc_pP->protocol_state = RLC_DATA_TRANSFER_READY_STATE; rlc_am_init_timer_poll_retransmit(ctxt_pP, rlc_pP, t_poll_retransmitP); rlc_am_init_timer_reordering (ctxt_pP, rlc_pP, t_reorderingP); rlc_am_init_timer_status_prohibit(ctxt_pP, rlc_pP, t_status_prohibitP); rlc_pP->configured = TRUE; } }
//----------------------------------------------------------------------------- void rlc_am_init( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlc_pP) //----------------------------------------------------------------------------- { if (rlc_pP->initialized == TRUE) { LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] INITIALIZATION ALREADY DONE, DOING NOTHING\n", PROTOCOL_CTXT_ARGS(ctxt_pP)); } else { LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] INITIALIZATION: STATE VARIABLES, BUFFERS, LISTS\n", PROTOCOL_CTXT_ARGS(ctxt_pP)); memset(rlc_pP, 0, sizeof(rlc_am_entity_t)); list2_init(&rlc_pP->receiver_buffer, "RX BUFFER"); list_init(&rlc_pP->pdus_to_mac_layer, "PDUS TO MAC"); list_init(&rlc_pP->control_pdu_list, "CONTROL PDU LIST"); list_init(&rlc_pP->segmentation_pdu_list, "SEGMENTATION PDU LIST"); //LOG_D(RLC,"RLC_AM_SDU_CONTROL_BUFFER_SIZE %d sizeof(rlc_am_tx_sdu_management_t) %d \n", RLC_AM_SDU_CONTROL_BUFFER_SIZE, sizeof(rlc_am_tx_sdu_management_t)); pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL); rlc_pP->input_sdus = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t)); #warning "cast the rlc retrans buffer to uint32" // rlc_pP->pdu_retrans_buffer = calloc(1, (uint16_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(rlc_am_tx_data_pdu_management_t))); rlc_pP->pdu_retrans_buffer = calloc(1, (uint32_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(rlc_am_tx_data_pdu_management_t))); LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] input_sdus[] = %p element size=%d\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rlc_pP->input_sdus, sizeof(rlc_am_tx_sdu_management_t)); LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM INIT] pdu_retrans_buffer[] = %p element size=%d\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rlc_pP->pdu_retrans_buffer, sizeof(rlc_am_tx_data_pdu_management_t)); // TX state variables //rlc_pP->vt_a = 0; rlc_pP->vt_ms = rlc_pP->vt_a + RLC_AM_WINDOW_SIZE; //rlc_pP->vt_s = 0; //rlc_pP->poll_sn = 0; // TX counters //rlc_pP->c_pdu_without_poll = 0; //rlc_pP->c_byte_without_poll = 0; // RX state variables //rlc_pP->vr_r = 0; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; //rlc_pP->vr_x = 0; //rlc_pP->vr_ms = 0; //rlc_pP->vr_h = 0; rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->initialized = TRUE; } }
//----------------------------------------------------------------------------- void rlc_am_reestablish( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlc_pP) //----------------------------------------------------------------------------- { /* * RLC re-establishment is performed upon request by RRC, and the function * is applicable for AM, UM and TM RLC entities. * When RRC indicates that an RLC entity should be re-established, the RLC entity shall: * - if it is an AM RLC entity: * - when possible, reassemble RLC SDUs from any byte segments of AMD PDUs with SN < VR(MR) in the * receiving side, remove RLC headers when doing so and deliver all reassembled RLC SDUs to upper layer in * ascending order of the RLC SN, if not delivered before; * - discard the remaining AMD PDUs and byte segments of AMD PDUs in the receiving side; * - discard all RLC SDUs and AMD PDUs in the transmitting side; * - discard all RLC control PDUs. * - stop and reset all timers; * - reset all state variables to their initial values. */ LOG_D(RLC, PROTOCOL_CTXT_FMT"[AM REESTABLISH] RE-INIT STATE VARIABLES, BUFFERS, LISTS\n", PROTOCOL_CTXT_ARGS(ctxt_pP)); #warning TODO when possible reassemble RLC SDUs from any byte segments of AMD PDUs with SN inf VR(MR) list2_free(&rlc_pP->receiver_buffer); list_free(&rlc_pP->pdus_to_mac_layer); list_free(&rlc_pP->control_pdu_list); list_free(&rlc_pP->segmentation_pdu_list); // TX state variables rlc_pP->vt_a = 0; rlc_pP->vt_ms = rlc_pP->vt_a + RLC_AM_WINDOW_SIZE; rlc_pP->vt_s = 0; rlc_pP->poll_sn = 0; // TX counters rlc_pP->c_pdu_without_poll = 0; rlc_pP->c_byte_without_poll = 0; // RX state variables rlc_pP->vr_r = 0; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; rlc_pP->vr_x = 0; rlc_pP->vr_ms = 0; rlc_pP->vr_h = 0; rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->initialized = TRUE; }
//----------------------------------------------------------------------------- void rlc_am_set_debug_infos( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlc_pP, const srb_flag_t srb_flagP, const rb_id_t rb_idP) //----------------------------------------------------------------------------- { rlc_pP->rb_id = rb_idP; if (srb_flagP) { rlc_pP->is_data_plane = 0; } else { rlc_pP->is_data_plane = 1; } LOG_D(RLC, PROTOCOL_CTXT_FMT RB_AM_FMT "[SET DEBUG INFOS]\n", PROTOCOL_CTXT_ARGS(ctxt_pP), RB_AM_ARGS(rlc_pP)); }
//----------------------------------------------------------------------------- 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 mac_rlc_data_ind ( const module_id_t module_idP, const rnti_t rntiP, const module_id_t eNB_index, const frame_t frameP, const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, char *buffer_pP, const tb_size_t tb_sizeP, num_tb_t num_tbP, crc_t *crcs_pP) { //----------------------------------------------------------------------------- rb_id_t rb_id = 0; rlc_mode_t rlc_mode = RLC_MODE_NONE; rlc_mbms_id_t *mbms_id_p = NULL; rlc_union_t *rlc_union_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; srb_flag_t srb_flag = (channel_idP <= 2) ? SRB_FLAG_YES : SRB_FLAG_NO; protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0, eNB_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_IND,VCD_FUNCTION_IN); #ifdef DEBUG_MAC_INTERFACE if (num_tbP) { LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, Num_tb %d\n", PROTOCOL_CTXT_ARGS(&ctxt), channel_idP, RLC_MAX_LC, NB_RB_MAX, num_tbP); } #endif // DEBUG_MAC_INTERFACE #ifdef OAI_EMU if (MBMS_flagP) AssertFatal (channel_idP < RLC_MAX_MBMS_LC, "channel id is too high (%u/%d)!\n", channel_idP, RLC_MAX_MBMS_LC); else AssertFatal (channel_idP < NB_RB_MAX, "channel id is too high (%u/%d)!\n", channel_idP, NB_RB_MAX); CHECK_CTXT_ARGS(&ctxt); #endif if (MBMS_flagP) { if (BOOL_NOT(enb_flagP)) { mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[module_idP][channel_idP]; key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id); } else { return; } } else { if (channel_idP > 2) { rb_id = channel_idP - 2; } else { rb_id = channel_idP; } key = RLC_COLL_KEY_VALUE(module_idP, rntiP, enb_flagP, rb_id, srb_flag); } h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); if (h_rc == HASH_TABLE_OK) { rlc_mode = rlc_union_p->mode; } else { rlc_mode = RLC_MODE_NONE; //AssertFatal (0 , "%s RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP); } struct mac_data_ind data_ind = mac_rlc_deserialize_tb(buffer_pP, tb_sizeP, num_tbP, crcs_pP); switch (rlc_mode) { case RLC_MODE_NONE: //handle_event(WARNING,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no radio bearer configured :%d\n", __FILE__, __LINE__, channel_idP); break; case RLC_MODE_AM: rlc_am_mac_data_indication(&ctxt, &rlc_union_p->rlc.am, data_ind); break; case RLC_MODE_UM: rlc_um_mac_data_indication(&ctxt, &rlc_union_p->rlc.um, data_ind); break; case RLC_MODE_TM: rlc_tm_mac_data_indication(&ctxt, &rlc_union_p->rlc.tm, data_ind); break; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_IND,VCD_FUNCTION_OUT); }
//----------------------------------------------------------------------------- tbs_size_t mac_rlc_data_req( const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, const frame_t frameP, const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, char *buffer_pP) { //----------------------------------------------------------------------------- struct mac_data_req data_request; rb_id_t rb_id = 0; rlc_mode_t rlc_mode = RLC_MODE_NONE; rlc_mbms_id_t *mbms_id_p = NULL; rlc_union_t *rlc_union_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; srb_flag_t srb_flag = (channel_idP <= 2) ? SRB_FLAG_YES : SRB_FLAG_NO; tbs_size_t ret_tb_size = 0; protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0,eNB_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,VCD_FUNCTION_IN); #ifdef DEBUG_MAC_INTERFACE LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_REQ channel %d (%d) MAX RB %d, Num_tb %d\n", PROTOCOL_CTXT_ARGS((&ctxt)), channel_idP, RLC_MAX_LC, NB_RB_MAX); #endif // DEBUG_MAC_INTERFACE if (MBMS_flagP) { AssertFatal (channel_idP < RLC_MAX_MBMS_LC, "channel id is too high (%u/%d)!\n", channel_idP, RLC_MAX_MBMS_LC); } else { AssertFatal (channel_idP < NB_RB_MAX, "channel id is too high (%u/%d)!\n", channel_idP, NB_RB_MAX); } #ifdef OAI_EMU CHECK_CTXT_ARGS(&ctxt); //printf("MBMS_flagP %d, MBMS_FLAG_NO %d \n",MBMS_flagP, MBMS_FLAG_NO); // AssertFatal (MBMS_flagP == MBMS_FLAG_NO ," MBMS FLAG SHOULD NOT BE SET IN mac_rlc_data_req in UE\n"); #endif if (MBMS_flagP) { if (enb_flagP) { mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[module_idP][channel_idP]; key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id); } else { return (tbs_size_t)0; } } else { if (channel_idP > 2) { rb_id = channel_idP - 2; } else { rb_id = channel_idP; } key = RLC_COLL_KEY_VALUE(module_idP, rntiP, enb_flagP, rb_id, srb_flag); } h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); if (h_rc == HASH_TABLE_OK) { rlc_mode = rlc_union_p->mode; } else { rlc_mode = RLC_MODE_NONE; AssertFatal (0 , "RLC not configured rb id %u lcid %u RNTI %x!\n", rb_id, channel_idP, rntiP); } switch (rlc_mode) { case RLC_MODE_NONE: ret_tb_size =0; break; case RLC_MODE_AM: data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am); ret_tb_size =mac_rlc_serialize_tb(buffer_pP, data_request.data); break; case RLC_MODE_UM: data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um); ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data); break; case RLC_MODE_TM: data_request = rlc_tm_mac_data_request(&ctxt, &rlc_union_p->rlc.tm); ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data); break; default: ; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,VCD_FUNCTION_OUT); return ret_tb_size; }
//----------------------------------------------------------------------------- rlc_op_status_t rrc_rlc_config_req ( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t mbms_flagP, const config_action_t actionP, const rb_id_t rb_idP, const rlc_info_t rlc_infoP) { //----------------------------------------------------------------------------- rlc_op_status_t status; LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG_REQ for RAB %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); #ifdef OAI_EMU CHECK_CTXT_ARGS(ctxt_pP) #endif AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); switch (actionP) { case CONFIG_ACTION_ADD: if (rrc_rlc_add_rlc(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, rb_idP, rlc_infoP.rlc_mode) != NULL) { return RLC_OP_STATUS_INTERNAL_ERROR; } // no break, fall to next case case CONFIG_ACTION_MODIFY: switch (rlc_infoP.rlc_mode) { case RLC_MODE_AM: LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB AM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_am( ctxt_pP, srb_flagP, &rlc_infoP.rlc.rlc_am_info, rb_idP); break; case RLC_MODE_UM: LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB UM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_um( ctxt_pP, srb_flagP, &rlc_infoP.rlc.rlc_um_info, rb_idP); break; case RLC_MODE_TM: LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB TM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_tm( ctxt_pP, srb_flagP, &rlc_infoP.rlc.rlc_tm_info, rb_idP); break; default: return RLC_OP_STATUS_BAD_PARAMETER; } break; case CONFIG_ACTION_REMOVE: return rrc_rlc_remove_rlc(ctxt_pP, srb_flagP, mbms_flagP, rb_idP); break; default: return RLC_OP_STATUS_BAD_PARAMETER; } return RLC_OP_STATUS_OK; }
//----------------------------------------------------------------------------- rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, const SRB_ToAddModList_t * const srb2add_listP, const DRB_ToAddModList_t * const drb2add_listP, const DRB_ToReleaseList_t * const drb2release_listP #if defined(Rel10) ,const PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP #endif ) { //----------------------------------------------------------------------------- rb_id_t rb_id = 0; logical_chan_id_t lc_id = 0; DRB_Identity_t drb_id = 0; DRB_Identity_t* pdrb_id = NULL; long int cnt = 0; const SRB_ToAddMod_t *srb_toaddmod_p = NULL; const DRB_ToAddMod_t *drb_toaddmod_p = NULL; rlc_union_t *rlc_union_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; #if defined(Rel10) int i, j; MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; mbms_session_id_t mbms_session_id; mbms_service_id_t mbms_service_id; DL_UM_RLC_t dl_um_rlc; #endif LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ ASN1 \n", PROTOCOL_CTXT_ARGS(ctxt_pP)); #ifdef OAI_EMU CHECK_CTXT_ARGS(ctxt_pP) #endif if (srb2add_listP != NULL) { for (cnt=0; cnt<srb2add_listP->list.count; cnt++) { rb_id = srb2add_listP->list.array[cnt]->srb_Identity; lc_id = rb_id + 2; LOG_D(RLC, "Adding SRB %d, rb_id %d\n",srb2add_listP->list.array[cnt]->srb_Identity,rb_id); srb_toaddmod_p = srb2add_listP->list.array[cnt]; if (srb_toaddmod_p->rlc_Config) { switch (srb_toaddmod_p->rlc_Config->present) { case SRB_ToAddMod__rlc_Config_PR_NOTHING: break; case SRB_ToAddMod__rlc_Config_PR_explicitValue: switch (srb_toaddmod_p->rlc_Config->choice.explicitValue.present) { case RLC_Config_PR_NOTHING: break; case RLC_Config_PR_am: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM) != NULL) { config_req_rlc_am_asn1 ( ctxt_pP, SRB_FLAG_YES, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am, rb_id); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } break; case RLC_Config_PR_um_Bi_Directional: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, UNUSED_PARAM_MBMS_SESSION_ID, UNUSED_PARAM_MBMS_SERVICE_ID, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.ul_UM_RLC, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.dl_UM_RLC, rb_id); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } break; case RLC_Config_PR_um_Uni_Directional_UL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, UNUSED_PARAM_MBMS_SESSION_ID, UNUSED_PARAM_MBMS_SERVICE_ID, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_UL.ul_UM_RLC, NULL, rb_id); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } break; case RLC_Config_PR_um_Uni_Directional_DL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, UNUSED_PARAM_MBMS_SESSION_ID, UNUSED_PARAM_MBMS_SERVICE_ID, NULL, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_DL.dl_UM_RLC, rb_id); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } break; default: LOG_E(RLC, PROTOCOL_CTXT_FMT" UNKNOWN RLC CONFIG %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), srb_toaddmod_p->rlc_Config->choice.explicitValue.present); break; } break; case SRB_ToAddMod__rlc_Config_PR_defaultValue: #warning TO DO SRB_ToAddMod__rlc_Config_PR_defaultValue if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, UNUSED_PARAM_MBMS_SESSION_ID, UNUSED_PARAM_MBMS_SERVICE_ID, NULL, // TO DO DEFAULT CONFIG NULL, // TO DO DEFAULT CONFIG rb_id); } else { LOG_D(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } break; default: ; } } } } if (drb2add_listP != NULL) { for (cnt=0; cnt<drb2add_listP->list.count; cnt++) { drb_toaddmod_p = drb2add_listP->list.array[cnt]; drb_id = drb_toaddmod_p->drb_Identity; lc_id = drb_id + 2; LOG_D(RLC, "Adding DRB %d, lc_id %d\n",drb_id,lc_id); if (drb_toaddmod_p->rlc_Config) { switch (drb_toaddmod_p->rlc_Config->present) { case RLC_Config_PR_NOTHING: break; case RLC_Config_PR_am: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_AM) != NULL) { config_req_rlc_am_asn1 ( ctxt_pP, SRB_FLAG_NO, &drb_toaddmod_p->rlc_Config->choice.am, drb_id); } break; case RLC_Config_PR_um_Bi_Directional: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, UNUSED_PARAM_MBMS_SESSION_ID, UNUSED_PARAM_MBMS_SERVICE_ID, &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.ul_UM_RLC, &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.dl_UM_RLC, drb_id); } break; case RLC_Config_PR_um_Uni_Directional_UL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, UNUSED_PARAM_MBMS_SESSION_ID, UNUSED_PARAM_MBMS_SERVICE_ID, &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_UL.ul_UM_RLC, NULL, drb_id); } break; case RLC_Config_PR_um_Uni_Directional_DL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, UNUSED_PARAM_MBMS_SESSION_ID, UNUSED_PARAM_MBMS_SERVICE_ID, NULL, &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_DL.dl_UM_RLC, drb_id); } break; default: LOG_W(RLC, PROTOCOL_CTXT_FMT"[RB %u] unknown drb_toaddmod_p->rlc_Config->present \n", PROTOCOL_CTXT_ARGS(ctxt_pP), drb_id); } } } } if (drb2release_listP != NULL) { for (cnt=0; cnt<drb2release_listP->list.count; cnt++) { pdrb_id = drb2release_listP->list.array[cnt]; rrc_rlc_remove_rlc( ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, *pdrb_id); } } #if defined(Rel10) if (pmch_InfoList_r9_pP != NULL) { for (i=0; i<pmch_InfoList_r9_pP->list.count; i++) { mbms_SessionInfoList_r9_p = &(pmch_InfoList_r9_pP->list.array[i]->mbms_SessionInfoList_r9); for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; lc_id = mbms_session_id; mbms_service_id = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string // can set the mch_id = i if (ctxt_pP->enb_flag) { rb_id = (mbms_service_id * maxSessionPerPMCH ) + mbms_session_id;//+ (maxDRB + 3) * MAX_MOBILES_PER_ENB; // 1 rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lc_id].service_id = mbms_service_id; rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lc_id].session_id = mbms_session_id; rlc_mbms_enb_set_lcid_by_rb_id(ctxt_pP->module_id,rb_id,lc_id); } else { rb_id = (mbms_service_id * maxSessionPerPMCH ) + mbms_session_id; // + (maxDRB + 3); // 15 rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lc_id].service_id = mbms_service_id; rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lc_id].session_id = mbms_session_id; rlc_mbms_ue_set_lcid_by_rb_id(ctxt_pP->module_id,rb_id,lc_id); } key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->module_id, ctxt_pP->enb_flag, mbms_service_id, mbms_session_id); h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) { rlc_union_p = rrc_rlc_add_rlc ( ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_YES, rb_id, lc_id, RLC_MODE_UM); AssertFatal(rlc_union_p != NULL, "ADD MBMS RLC UM FAILED"); } LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id, rb_id, mbms_session_id, mbms_service_id ); dl_um_rlc.sn_FieldLength = SN_FieldLength_size5; dl_um_rlc.t_Reordering = T_Reordering_ms0; config_req_rlc_um_asn1 ( ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_YES, mbms_session_id, mbms_service_id, NULL, &dl_um_rlc, rb_id); } } } #endif LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ ASN1 END \n", PROTOCOL_CTXT_ARGS(ctxt_pP)); return RLC_OP_STATUS_OK; }
//----------------------------------------------------------------------------- rlc_union_t* rrc_rlc_add_rlc ( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, const logical_chan_id_t chan_idP, const rlc_mode_t rlc_modeP) { //----------------------------------------------------------------------------- hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; rlc_union_t *rlc_union_p = NULL; #ifdef Rel10 rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t lcid = 0; #endif #ifdef OAI_EMU CHECK_CTXT_ARGS(ctxt_pP) #endif if (MBMS_flagP == FALSE) { AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); } #ifdef Rel10 if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid]; //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0; //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0; //LG 2014-04-15rlc_mbms_rbid2lcid_eNB[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED; } else { lcid = rlc_mbms_ue_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lcid]; //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0; //LG 2014-04-15rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0; //LG 2014-04-15rlc_mbms_rbid2lcid_ue[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED; } key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); } else #endif { key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); } h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); if (h_rc == HASH_TABLE_OK) { LOG_W(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , already exist %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, (srb_flagP) ? "SRB" : "DRB"); AssertFatal(rlc_union_p->mode == rlc_modeP, "Error rrc_rlc_add_rlc , already exist but RLC mode differ"); return rlc_union_p; } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) { rlc_union_p = calloc(1, sizeof(rlc_union_t)); h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p); if (h_rc == HASH_TABLE_OK) { #ifdef Rel10 if (MBMS_flagP == TRUE) { LOG_I(RLC, PROTOCOL_CTXT_FMT" RLC service id %u session id %u rrc_rlc_add_rlc\n", PROTOCOL_CTXT_ARGS(ctxt_pP), mbms_id_p->service_id, mbms_id_p->session_id); } else #endif { LOG_I(RLC, PROTOCOL_CTXT_FMT" [%s %u] rrc_rlc_add_rlc %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, (srb_flagP) ? "SRB" : "DRB"); } rlc_union_p->mode = rlc_modeP; return rlc_union_p; } else { LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc FAILED %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, (srb_flagP) ? "SRB" : "DRB"); free(rlc_union_p); rlc_union_p = NULL; return NULL; } } else { LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , INTERNAL ERROR %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, (srb_flagP) ? "SRB" : "DRB"); } return NULL; }
//----------------------------------------------------------------------------- rlc_op_status_t rrc_rlc_remove_rlc ( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP) { //----------------------------------------------------------------------------- logical_chan_id_t lcid = 0; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; rlc_union_t *rlc_union_p = NULL; #ifdef Rel10 rlc_mbms_id_t *mbms_id_p = NULL; #endif #ifdef OAI_EMU CHECK_CTXT_ARGS(ctxt_pP) #endif #ifdef Rel10 if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid]; rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0; rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0; rlc_mbms_rbid2lcid_ue[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED; } else { lcid = rlc_mbms_ue_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lcid]; rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].service_id = 0; rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid].session_id = 0; rlc_mbms_rbid2lcid_ue[ctxt_pP->module_id][rb_idP] = RLC_LC_UNALLOCATED; } key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); } else #endif { key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); } AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); if (h_rc == HASH_TABLE_OK) { h_rc = hashtable_remove(rlc_coll_p, key); LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASED %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, (srb_flagP) ? "SRB" : "DRB"); } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) { LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASE : RLC NOT FOUND %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, (srb_flagP) ? "SRB" : "DRB"); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASE : INTERNAL ERROR %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, (srb_flagP) ? "SRB" : "DRB"); } return RLC_OP_STATUS_OK; }