//----------------------------------------------------------------------------- void rlc_um_cleanup (rlc_um_entity_t * const rlc_pP) { //----------------------------------------------------------------------------- int index; // TX SIDE list_free (&rlc_pP->pdus_to_mac_layer); if (rlc_pP->input_sdus) { for (index = 0; index < rlc_pP->size_input_sdus_buffer; index++) { if (rlc_pP->input_sdus[index]) { free_mem_block (rlc_pP->input_sdus[index]); } } free (rlc_pP->input_sdus); rlc_pP->input_sdus = NULL; } // RX SIDE list_free (&rlc_pP->pdus_from_mac_layer); if ((rlc_pP->output_sdu_in_construction)) { free_mem_block (rlc_pP->output_sdu_in_construction); } if (rlc_pP->dar_buffer) { for (index = 0; index < 1024; index++) { if (rlc_pP->dar_buffer[index]) { free_mem_block (rlc_pP->dar_buffer[index]); } } free (rlc_pP->dar_buffer); rlc_pP->dar_buffer = NULL; } memset(rlc_pP, 0, sizeof(rlc_um_entity_t)); }
//----------------------------------------------------------------------------- void rlc_um_cleanup ( rlc_um_entity_t * const rlc_pP) { int index; // TX SIDE list_free (&rlc_pP->pdus_to_mac_layer); pthread_mutex_destroy(&rlc_pP->lock_input_sdus); list_free (&rlc_pP->input_sdus); // RX SIDE list_free (&rlc_pP->pdus_from_mac_layer); if ((rlc_pP->output_sdu_in_construction)) { free_mem_block (rlc_pP->output_sdu_in_construction); } if (rlc_pP->dar_buffer) { for (index = 0; index < 1024; index++) { if (rlc_pP->dar_buffer[index]) { free_mem_block (rlc_pP->dar_buffer[index]); } } free (rlc_pP->dar_buffer); rlc_pP->dar_buffer = NULL; } pthread_mutex_destroy(&rlc_pP->lock_dar_buffer); memset(rlc_pP, 0, sizeof(rlc_um_entity_t)); }
//----------------------------------------------------------------------------- void rlc_tm_cleanup ( rlc_tm_entity_t * const rlcP ) { int index; // TX SIDE list_free (&rlcP->pdus_to_mac_layer); if (rlcP->input_sdus_alloc) { for (index = 0; index < rlcP->size_input_sdus_buffer; index++) { if (rlcP->input_sdus[index]) { free_mem_block (rlcP->input_sdus[index]); } } free_mem_block (rlcP->input_sdus_alloc); rlcP->input_sdus_alloc = NULL; } // RX SIDE if ((rlcP->output_sdu_in_construction)) { free_mem_block (rlcP->output_sdu_in_construction); } memset(rlcP, 0, sizeof(rlc_tm_entity_t)); }
//----------------------------------------------------------------------------- void send_rlc_tm_control_primitive (struct rlc_tm_entity *rlcP, module_id_t module_idP, mem_block_t *cprimitiveP) { //----------------------------------------------------------------------------- switch (((struct crlc_primitive *) cprimitiveP->data)->type) { case CRLC_CONFIG_REQ: rlcP->module_id = module_idP; switch (((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.e_r) { case RLC_E_R_ESTABLISHMENT: if (rlc_tm_fsm_notify_event (rlcP, RLC_TM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) { rlc_tm_set_configured_parameters (rlcP, cprimitiveP); // the order of the calling of procedures... rlc_tm_reset_state_variables (rlcP); // ...must not ... } break; case RLC_E_R_RELEASE: if (rlc_tm_fsm_notify_event (rlcP, RLC_TM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT)) { rlc_tm_free_all_resources (rlcP); } break; default: msg ("[RLC_TM][ERROR] send_rlc_tm_control_primitive(CRLC_CONFIG_REQ) unknown parameter E_R\n"); } break; default: msg ("[RLC_TM %p][ERROR] send_rlc_tm_control_primitive(UNKNOWN CPRIMITIVE)\n", rlcP); } free_mem_block (cprimitiveP); }
//----------------------------------------------------------------------------- void rlc_tm_no_segment (struct rlc_tm_entity *rlcP) { //----------------------------------------------------------------------------- mem_block_t *pdu; struct rlc_tm_tx_sdu_management *sdu_mngt; struct rlc_tm_tx_pdu_management *pdu_mngt; int discard_go_on; int nb_pdu_to_transmit; nb_pdu_to_transmit = rlcP->nb_pdu_requested_by_mac; pdu = NULL; if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_TIMER_BASED_NO_EXPLICIT)) { discard_go_on = 1; while ((rlcP->input_sdus[rlcP->current_sdu_index]) && discard_go_on) { if ((*rlcP->frame_tick_milliseconds - ((struct rlc_tm_tx_sdu_management *) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->sdu_creation_time) >= rlcP->timer_discard_init) { #ifdef DEBUG_RLC_TM_DISCARD_SDU msg("[RLC_TM %p] SDU DISCARDED TIMED OUT %ld ms ", rlcP, (*rlcP->frame_tick_milliseconds - ((struct rlc_tm_tx_sdu_management *) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->sdu_creation_time)); msg("BO %d, NB SDU %d\n", rlcP->buffer_occupancy, rlcP->nb_sdu); #endif rlcP->buffer_occupancy -= (((struct rlc_tm_tx_sdu_management *) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->sdu_size >> 3); rlcP->nb_sdu -= 1; free_mem_block (rlcP->input_sdus[rlcP->current_sdu_index]); rlcP->input_sdus[rlcP->current_sdu_index] = NULL; rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer; } else {
//----------------------------------------------------------------------------- void umts_timer_check_time_out (list2_t * atimer_listP, uint32_t current_frame_tick_millisecondsP) { //----------------------------------------------------------------------------- struct timer_unit *timer; mem_block_t *mem_unit; uint8_t time_out = 255; mem_unit = atimer_listP->head; // do it simple now. while ((mem_unit) && (time_out)) { timer = (struct timer_unit *) (mem_unit->data); if ((current_frame_tick_millisecondsP - timer->frame_tick_start) >= timer->frame_time_out) { mem_unit = list2_remove_head (atimer_listP); (*(timer->proc)) (timer->protocol, timer->timer_id); free_mem_block (mem_unit); mem_unit = atimer_listP->head; } else { time_out = 0; } } }
//----------------------------------------------------------------------------- tbs_size_t mac_rlc_serialize_tb (char* buffer_pP, list_t transport_blocksP) { //----------------------------------------------------------------------------- mem_block_t *tb_p; tbs_size_t tbs_size; tbs_size_t tb_size; tbs_size = 0; while (transport_blocksP.nb_elements > 0) { tb_p = list_remove_head (&transport_blocksP); if (tb_p != NULL) { tb_size = ((struct mac_tb_req *) (tb_p->data))->tb_size; #ifdef DEBUG_MAC_INTERFACE #if defined(TRACE_RLC_PAYLOAD) LOG_T(RLC, "[MAC-RLC] DUMP TX PDU(%d bytes):\n", tb_size); rlc_util_print_hex_octets(RLC, ((struct mac_tb_req *) (tb_p->data))->data_ptr, tb_size); #endif #endif memcpy(&buffer_pP[tbs_size], &((struct mac_tb_req *) (tb_p->data))->data_ptr[0], tb_size); tbs_size = tbs_size + tb_size; free_mem_block(tb_p); } } return tbs_size; }
//----------------------------------------------------------------------------- void rlc_am_free_in_sdu(rlc_am_entity_t *rlcP, u32_t frame, unsigned int index_in_bufferP) //----------------------------------------------------------------------------- { if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) { if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) { free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block); rlcP->input_sdus[index_in_bufferP].mem_block = NULL; rlcP->nb_sdu_no_segmented -= 1; rlcP->input_sdus[index_in_bufferP].sdu_remaining_size = 0; } rlcP->nb_sdu -= 1; memset(&rlcP->input_sdus[index_in_bufferP], 0, sizeof(rlc_am_tx_sdu_management_t)); rlcP->input_sdus[index_in_bufferP].flags.transmitted_successfully = 1; if (rlcP->current_sdu_index == index_in_bufferP) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; } while ((rlcP->current_sdu_index != rlcP->next_sdu_index) && (rlcP->input_sdus[rlcP->current_sdu_index].flags.transmitted_successfully == 1)) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; } } #ifdef TRACE_RLC_AM_FREE_SDU LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][FREE SDU] SDU INDEX %03d current_sdu_index=%d next_sdu_index=%d nb_sdu_no_segmented=%d\n", frame, rlcP->module_id, rlcP->rb_id, index_in_bufferP, rlcP->current_sdu_index, rlcP->next_sdu_index, rlcP->nb_sdu_no_segmented); #endif }
//----------------------------------------------------------------------------- void rlc_um_send_sdu (struct rlc_um_entity *rlcP) { //----------------------------------------------------------------------------- if ((rlcP->output_sdu_in_construction)) { #ifdef DEBUG_RLC_UM_SEND_SDU msg ("[RLC_UM][RB %d][SEND_SDU] %d bytes \n", rlcP->rb_id, rlcP->output_sdu_size_to_write); #endif if (rlcP->output_sdu_size_to_write > 0) { #ifdef DEBUG_RLC_STATS rlcP->rx_sdus += 1; #endif ((struct rlc_indication *) (rlcP->output_sdu_in_construction->data))->type = RLC_UM_DATA_IND; ((struct rlc_indication *) (rlcP->output_sdu_in_construction->data))->primitive.um_ind.data_size = rlcP->output_sdu_size_to_write; #ifdef BENCH_QOS_L2 fprintf (bench_l2, "[SDU DELIVERY] FRAME %d SIZE %d RB %d RLC-UM %p\n", mac_xface->frame, rlcP->output_sdu_size_to_write, rlcP->rb_id, rlcP); #endif rlcP->rlc_data_ind (rlcP->upper_layer, rlcP->output_sdu_in_construction, rlcP->rb_id); } else { #ifdef DEBUG_RLC_UM_SEND_SDU msg ("[RLC_UM][RB %d][SEND_SDU] ERROR SIZE 0\n", rlcP->rb_id, rlcP->output_sdu_size_to_write); #endif free_mem_block (rlcP->output_sdu_in_construction); } rlcP->output_sdu_in_construction = NULL; rlcP->output_sdu_size_to_write = 0; } }
//----------------------------------------------------------------------------- void rlc_am_cleanup( rlc_am_entity_t* const rlc_pP ) //----------------------------------------------------------------------------- { 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); if (rlc_pP->output_sdu_in_construction != NULL) { free_mem_block(rlc_pP->output_sdu_in_construction); rlc_pP->output_sdu_in_construction = NULL; } unsigned int i; if (rlc_pP->input_sdus != NULL) { for (i=0; i < RLC_AM_SDU_CONTROL_BUFFER_SIZE; i++) { if (rlc_pP->input_sdus[i].mem_block != NULL) { free_mem_block(rlc_pP->input_sdus[i].mem_block); rlc_pP->input_sdus[i].mem_block = NULL; } } free(rlc_pP->input_sdus); rlc_pP->input_sdus = NULL; } pthread_mutex_destroy(&rlc_pP->lock_input_sdus); if (rlc_pP->pdu_retrans_buffer != NULL) { for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) { if (rlc_pP->pdu_retrans_buffer[i].mem_block != NULL) { free_mem_block(rlc_pP->pdu_retrans_buffer[i].mem_block); rlc_pP->pdu_retrans_buffer[i].mem_block = NULL; } } free(rlc_pP->pdu_retrans_buffer); rlc_pP->pdu_retrans_buffer = NULL; } memset(rlc_pP, 0, sizeof(rlc_am_entity_t)); }
//----------------------------------------------------------------------------- void list_free (list_t * listP) { //----------------------------------------------------------------------------- mem_block_t *le; while ((le = list_remove_head (listP))) { free_mem_block (le); } }
//----------------------------------------------------------------------------- int rrc_rg_read_NT_FIFO (u8 *buffer, int count){ //----------------------------------------------------------------------------- int data_length; int Message_Id; int UE_Id; struct nas_rg_nt_element *p; int prim_length; int prim_type; if (count > 0) { #ifdef DEBUG_RRC_STATE msg ("[RRC_RG] Message Received from NAS - NT SAP: -%hx- \n", buffer[0]); #endif p = (struct nas_rg_nt_element *) buffer; prim_length = (int) (p->length); prim_type = (int) (p->type); #ifdef DEBUG_RRC_STATE msg ("[RRC_RG] Primitive Type %d,\t Primitive length %d \n", prim_type, prim_length); #endif //rrc_print_buffer ((char *)rcve_buffer, 100); switch (prim_type) { case PAGING_REQ: data_length = (u16) p->nasRGNTPrimitive.paging_req.nasDataLength; UE_Id = p->nasRGNTPrimitive.paging_req.UeId; protocol_bs->rrc.Mobile_List[UE_Id].paging_message_ptr = get_free_mem_block (data_length); protocol_bs->rrc.Mobile_List[UE_Id].paging_message_lgth = data_length; //get the associated data #ifndef RRC_NETLINK count += rtf_get (protocol_bs->rrc.rrc_rg_NT_fifo, (protocol_bs->rrc.Mobile_List[UE_Id].paging_message_ptr)->data, data_length); #else count += rrc_rg_read_data_from_nlh ((char *)(protocol_bs->rrc.Mobile_List[UE_Id].paging_message_ptr)->data, data_length, (int) (p->length)); #endif // memcpy((protocol_bs->rrc.Mobile_List[UE_Id].paging_message_ptr)->data, &(rcve_buffer[p->length]),data_length); #ifdef DEBUG_RRC_STATE //rrc_print_buffer ((char *)rcve_buffer, 100); msg ("[RRC_RG] PAGING_REQ primitive length: %d\n", (int) (p->length)); msg ("[RRC_RG] UE Id: %d\n", p->nasRGNTPrimitive.paging_req.UeId); msg ("[RRC_RG] Data length: %d\n", data_length); msg ("[RRC_RG] Data %s\n", (protocol_bs->rrc.Mobile_List[UE_Id].paging_message_ptr)->data); rrc_print_buffer ((char *) (protocol_bs->rrc.Mobile_List[UE_Id].paging_message_ptr)->data, data_length); #endif // Send paging to MS rrc_rg_msg_pagingt2 (UE_Id, &Message_Id); RRC_RG_O_O_SEND_DCCH_AM (UE_Id); free_mem_block (protocol_bs->rrc.Mobile_List[UE_Id].paging_message_ptr); break; default: msg ("[RRC_RG] Invalid message received on NT SAP\n"); rrc_print_buffer ((char *)buffer, count); count = -1; break; } } return count; }
//----------------------------------------------------------------------------- void rlc_am_data_req (void *rlcP, mem_block_t * sduP) { //----------------------------------------------------------------------------- struct rlc_am_entity *rlc = (struct rlc_am_entity *) rlcP; uint32_t mui; uint16_t data_offset; uint16_t data_size; uint8_t conf; if ((rlc->input_sdus[rlc->next_sdu_index] == NULL) && (((rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer) != rlc->current_sdu_index)) { rlc->stat_tx_pdcp_sdu += 1; rlc->input_sdus[rlc->next_sdu_index] = sduP; mui = ((struct rlc_am_data_req *) (sduP->data))->mui; data_offset = ((struct rlc_am_data_req *) (sduP->data))->data_offset; data_size = ((struct rlc_am_data_req *) (sduP->data))->data_size; conf = ((struct rlc_am_data_req *) (sduP->data))->conf; ((struct rlc_am_tx_sdu_management *) (sduP->data))->mui = mui; ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size = data_size; ((struct rlc_am_tx_sdu_management *) (sduP->data))->confirm = conf; rlc->buffer_occupancy += ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size; rlc->nb_sdu += 1; ((struct rlc_am_tx_sdu_management *) (sduP->data))->first_byte = &sduP->data[data_offset]; ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_remaining_size = ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_size; ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_segmented_size = 0; ((struct rlc_am_tx_sdu_management *) (sduP->data))->sdu_creation_time = *rlc->frame_tick_milliseconds; ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus = 0; ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_ack = 0; ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_time = 0; ((struct rlc_am_tx_sdu_management *) (sduP->data))->nb_pdus_internal_use = 0; ((struct rlc_am_tx_sdu_management *) (sduP->data))->segmented = 0; ((struct rlc_am_tx_sdu_management *) (sduP->data))->discarded = 0; ((struct rlc_am_tx_sdu_management *) (sduP->data))->li_index_for_discard = -1; ((struct rlc_am_tx_sdu_management *) (sduP->data))->no_new_sdu_segmented_in_last_pdu = 0; rlc->next_sdu_index = (rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer; #ifdef DEBUG_RLC_AM_DATA_REQUEST msg ("[RLC_AM][RB %d] RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d ", rlc->rb_id, data_size, rlc->nb_sdu, rlc->current_sdu_index, rlc->next_sdu_index, conf, mui); msg ("BO=%ld Bytes\n", rlc->buffer_occupancy); #endif } else { #ifdef DEBUG_RLC_AM_DATA_REQUEST msg ("[RLC_AM][RB %d] RLC_AM_DATA_REQ BUFFER FULL, NB SDU %d current_sdu_index=%d next_sdu_index=%d size_input_sdus_buffer=%d\n", rlc->rb_id, rlc->nb_sdu, rlc->current_sdu_index, rlc->next_sdu_index, rlc->size_input_sdus_buffer); #endif rlc->stat_tx_pdcp_sdu_discarded += 1; free_mem_block (sduP); } }
// called when segmentation is done //----------------------------------------------------------------------------- void rlc_am_free_in_sdu_data(rlc_am_entity_t *rlcP, unsigned int index_in_bufferP) //----------------------------------------------------------------------------- { if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) { if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) { free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block); rlcP->input_sdus[index_in_bufferP].mem_block = NULL; rlcP->input_sdus[index_in_bufferP].sdu_remaining_size = 0; rlcP->nb_sdu_no_segmented -= 1; } } }
//----------------------------------------------------------------------------- void rlc_tm_free_all_resources (struct rlc_tm_entity *rlcP) { //----------------------------------------------------------------------------- int index; list_free (&rlcP->pdus_to_mac_layer); list_free (&rlcP->pdus_from_mac_layer); if (rlcP->input_sdus_alloc) { for (index = 0; index < rlcP->size_input_sdus_buffer; index++) { if ((rlcP->input_sdus[index])) { free_mem_block (rlcP->input_sdus[index]); } } free_mem_block (rlcP->input_sdus_alloc); rlcP->input_sdus_alloc = NULL; } if ((rlcP->output_sdu_in_construction)) { free_mem_block (rlcP->output_sdu_in_construction); } }
//----------------------------------------------------------------------------- void rlc_um_data_req (void *rlcP, mem_block_t *sduP) { //----------------------------------------------------------------------------- rlc_um_entity_t *rlc = (rlc_um_entity_t *) rlcP; #ifndef USER_MODE unsigned long int rlc_um_time_us; int min, sec, usec; #endif #ifdef DEBUG_RLC_UM_DATA_REQUEST msg ("[RLC_UM][MOD %d][RB %d][FRAME %05d] RLC_UM_DATA_REQ size %d Bytes, BO %d , NB SDU %d current_sdu_index=%d next_sdu_index=%d\n", rlc->module_id, rlc->rb_id, mac_xface->frame, ((struct rlc_um_data_req *) (sduP->data))->data_size, rlc->buffer_occupancy, rlc->nb_sdu, rlc->current_sdu_index, rlc->next_sdu_index); /*#ifndef USER_MODE rlc_um_time_us = (unsigned long int)(rt_get_time_ns ()/(RTIME)1000); sec = (rlc_um_time_us/ 1000000); min = (sec / 60) % 60; sec = sec % 60; usec = rlc_um_time_us % 1000000; msg ("[RLC_UM_LITE][RB %d] at time %2d:%2d.%6d\n", rlc->rb_id, min, sec , usec); #endif*/ #endif if (rlc->input_sdus[rlc->next_sdu_index] == NULL) { rlc->input_sdus[rlc->next_sdu_index] = sduP; // IMPORTANT : do not change order of affectations ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_size = ((struct rlc_um_data_req *) (sduP->data))->data_size; rlc->buffer_occupancy += ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_size; rlc->nb_sdu += 1; ((struct rlc_um_tx_sdu_management *) (sduP->data))->first_byte = &sduP->data[sizeof (struct rlc_um_data_req_alloc)]; ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_remaining_size = ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_size; ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_segmented_size = 0; // LG ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_creation_time = *rlc->frame_tick_milliseconds; // LG ??? WHO WROTE THAT LINE ?((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_creation_time = 0; rlc->next_sdu_index = (rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer; } else { msg("[RLC_UM][MOD %d][RB %d][FRAME %05d] RLC-UM_DATA_REQ input buffer full SDU garbaged\n",rlc->module_id, rlc->rb_id, mac_xface->frame); free_mem_block (sduP); } }
//----------------------------------------------------------------------------- void umts_timer_delete_timer (list2_t * atimer_listP, void *timer_idP) { //----------------------------------------------------------------------------- mem_block_t *mem_unit; mem_unit = atimer_listP->head; while ((mem_unit)) { if (((struct timer_unit *) (mem_unit->data))->timer_id == timer_idP) { list2_remove_element (mem_unit, atimer_listP); free_mem_block (mem_unit); return; } mem_unit = mem_unit->next; } }
//#define RLC_UM_GENERATE_ERRORS //----------------------------------------------------------------------------- void rlc_um_receive (struct rlc_um_entity *rlcP, struct mac_data_ind data_indP) { //----------------------------------------------------------------------------- mem_block_t *tb; u8_t *first_byte; u16_t tb_size_in_bytes; while ((tb = list_remove_head (&data_indP.data))) { #ifdef DEBUG_RLC_STATS rlcP->rx_pdus += 1; #endif #ifdef DEBUG_RLC_UM_DISPLAY_TB_DATA msg ("[RLC_UM][MOD %d][RB %d][FRAME %05d] DUMP RX PDU(%d bytes):", rlcP->module_id, rlcP->rb_id, mac_xface->frame, ((struct mac_tb_ind *) (tb->data))->size); for (tb_size_in_bytes = 0; tb_size_in_bytes < ((struct mac_tb_ind *) (tb->data))->size; tb_size_in_bytes++) { msg ("%02X.", ((struct mac_tb_ind *) (tb->data))->data_ptr[tb_size_in_bytes]); } msg ("\n"); #endif #ifdef RLC_UM_GENERATE_ERRORS if (random() % 10 == 4) { ((struct mac_tb_ind *) (tb->data))->error_indication = 1; msg ("[RLC_UM][MOD %d][RB %d][FRAME %05d] RX PDU GENERATE ERROR", rlcP->module_id, rlcP->rb_id, mac_xface->frame); } #endif if (!(((struct mac_tb_ind *) (tb->data))->error_indication)) { first_byte = ((struct mac_tb_ind *) (tb->data))->data_ptr; tb_size_in_bytes = ((struct mac_tb_ind *) (tb->data))->size; if (tb_size_in_bytes > 0) { rlc_um_receive_process_dar (rlcP, tb, first_byte, tb_size_in_bytes); msg ("[RLC_UM][MOD %d][RB %d][FRAME %05d] VR(UR)=%03d VR(UX)=%03d VR(UH)=%03d\n", rlcP->module_id, rlcP->rb_id, mac_xface->frame, rlcP->vr_ur, rlcP->vr_ux, rlcP->vr_uh); } } else { #ifdef DEBUG_RLC_STATS rlcP->rx_pdus_in_error += 1; #endif #ifdef DEBUG_RLC_UM_RX msg ("[RLC_UM][MOD %d][RB %d][FRAME %05d] RX PDU WITH ERROR INDICATED BY LOWER LAYERS -> GARBAGE\n", rlcP->module_id, rlcP->rb_id, mac_xface->frame); #endif } free_mem_block (tb); } // end while }
//----------------------------------------------------------------------------- void rlc_um_send_sdu (struct rlc_um_entity *rlcP) { //----------------------------------------------------------------------------- /*#ifndef USER_MODE unsigned long int rlc_um_time_us; int min, sec, usec; #endif*/ if ((rlcP->output_sdu_in_construction)) { #ifdef DEBUG_RLC_UM_SEND_SDU msg ("[RLC_UM_LITE][MOD %d][RB %d][SEND_SDU] %d bytes frame %d\n", rlcP->module_id, rlcP->rb_id, rlcP->output_sdu_size_to_write, Mac_rlc_xface->frame); /*#ifndef USER_MODE rlc_um_time_us = (unsigned long int)(rt_get_time_ns ()/(RTIME)1000); sec = (rlc_um_time_us/ 1000000); min = (sec / 60) % 60; sec = sec % 60; usec = rlc_um_time_us % 1000000; msg ("[RLC_UM_LITE][RB %d] at time %2d:%2d.%6d\n", rlcP->rb_id, min, sec , usec); #endif*/ #endif if (rlcP->output_sdu_size_to_write > 0) { #ifdef DEBUG_RLC_STATS rlcP->rx_sdus += 1; #endif #ifdef BENCH_QOS_L2 fprintf (bench_l2, "[SDU DELIVERY] FRAME %d SIZE %d RB %d RLC-UM %p\n", Mac_rlc_xface->frame, rlcP->output_sdu_size_to_write, rlcP->rb_id, rlcP); #endif // msg("[RLC] DATA IND ON MOD_ID %d RB ID %d, size %d\n",rlcP->module_id, rlcP->rb_id,rlcP->output_sdu_size_to_write); rlc_data_ind (rlcP->module_id, rlcP->rb_id, rlcP->output_sdu_size_to_write, rlcP->output_sdu_in_construction, rlcP->data_plane); } else { #ifdef DEBUG_RLC_UM_SEND_SDU msg ("[RLC_UM_LITE][RB %d][SEND_SDU] ERROR SIZE <= 0\n", rlcP->rb_id); #endif msg ("[RLC_UM_LITE][RB %d][SEND_SDU] ERROR SIZE <= 0\n", rlcP->rb_id); msg("[RLC_UM_LITE] Freeing mem_block ...\n"); free_mem_block (rlcP->output_sdu_in_construction); } rlcP->output_sdu_in_construction = NULL; rlcP->output_sdu_size_to_write = 0; } }
//----------------------------------------------------------------------------- void umts_stop_all_timers_except (list2_t * atimer_listP, void (*procP) (void *, void *)) { //----------------------------------------------------------------------------- struct timer_unit *timer; mem_block_t *mem_unit; mem_block_t *mem_unit_to_delete; mem_unit = atimer_listP->head; while ((mem_unit)) { timer = (struct timer_unit *) (mem_unit->data); if (timer->proc != procP) { mem_unit_to_delete = mem_unit; mem_unit = mem_unit->next; list2_remove_element (mem_unit_to_delete, atimer_listP); free_mem_block (mem_unit_to_delete); } else { mem_unit = mem_unit->next; } } }
//------------------------------------------------------------------- void RRC_RG_SEND_AM_SRB3 (int msgId){ //------------------------------------------------------------------- // Temp 01/03 - msgId contains UE_Id char *tx_dcch_info; int data_length = 0; int retcode; // send message tx_dcch_info = (char *) protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr; data_length = protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length; if (data_length > 0) { //retcode = rb_tx_data_srb_rg (RRC_SRB3_ID + (msgId * maxRB), tx_dcch_info, data_length * 8, protocol_bs->rrc.next_MUI++, TRUE); retcode = rrc_rg_send_to_srb_rlc (msgId, RRC_SRB3_ID, tx_dcch_info, data_length); #ifdef DEBUG_RRC_STATE msg ("[RRC_RG][DATA-OUT] Message %s sent on DCCH-AM-SRB3, ret code= %d.\n", tx_dcch_info, retcode); #endif } // clear resources protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length = 0; // free(protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr); free_mem_block (protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.mem_block_ptr); }
//------------------------------------------------------------------- void RRC_RG_O_O_SEND_DCCH_UM (int msgId){ //------------------------------------------------------------------- // Temp 01/03 - msgId contains UE_Id char tx_dcch_info; int data_length = 0 ; int retcode; // prepare message tx_dcch_info = (char *) protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr; data_length = protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length; if (data_length > 0) { //retcode = rb_tx_data_srb_rg (RRC_SRB1_ID + (msgId * maxRB), tx_dcch_info, data_length * 8, 0, FALSE); //retcode = Mac_rlc_xface->rrc_rlc_data_req (RRC_MODULE_INST_ID, RRC_LCHAN_SRB1_ID, 0, RRC_RLC_CONFIRM_NO, data_length, tx_dcch_info); retcode = rrc_rg_send_to_srb_rlc (msgId, RRC_SRB1_ID, tx_dcch_info, data_length); #ifdef DEBUG_RRC_STATE msg ("[RRC_RG][FSM-OUT] Message %s sent on DCCH-UM, ret code= %d.\n", tx_dcch_info, retcode); #endif } // clear resources protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length = 0; //free(protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr); free_mem_block (protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.mem_block_ptr); }
//------------------------------------------------------------------- void RRC_RG_O_O_SEND_CCCH (int msgId){ //------------------------------------------------------------------- // Temp 01/03 - msgId contains UE_Id char *tx_ccch_info; int data_length = 0; int retcode; tx_ccch_info = (char *) protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr; data_length = protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length; if (data_length > 0) { //retcode = Mac_rlc_xface->rrc_rlc_data_req (RRC_MODULE_INST_ID, RRC_LCHAN_SRB0_ID, 0, RRC_RLC_CONFIRM_NO, data_length, tx_ccch_info); retcode = rrc_rg_send_to_srb_rlc (msgId, RRC_SRB0_ID, tx_ccch_info, data_length); #ifdef DEBUG_RRC_STATE msg ("[RRC_RG][FSM-OUT] Message sent on CCCH. SRB0 -- retcode = %d -- data length %d\n", retcode, data_length); //RC = 1 ==> OK //msg ("[RRC_RG][FSM-OUT] Message %s sent on CCCH. SRB0\n", tx_ccch_info); #endif } // clear resources protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length = 0; //free(protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr); free_mem_block (protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.mem_block_ptr); }
//------------------------------------------------------------------- void RRC_RG_O_O_SEND_DCCH_AM (int msgId){ //------------------------------------------------------------------- // Temp 01/03 - msgId contains UE_Id char *tx_dcch_info; int data_length = 0; int retcode; // send message tx_dcch_info = (char *) protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr; data_length = protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length; if (data_length > 0) { //retcode = rb_tx_data_srb_rg (RRC_SRB2_ID + (msgId * maxRB), tx_dcch_info, data_length * 8, protocol_bs->rrc.next_MUI++, TRUE); //retcode = Mac_rlc_xface->rrc_rlc_data_req (RRC_MODULE_INST_ID, RRC_LCHAN_SRB2_ID, protocol_bs->rrc.next_MUI++, 0, data_length, tx_dcch_info); retcode = rrc_rg_send_to_srb_rlc (msgId, RRC_SRB2_ID, tx_dcch_info, data_length); #ifdef DEBUG_RRC_STATE msg ("[RRC_RG][FSM-OUT] Message %s sent on DCCH-AM, MUI %d, ret code= %d.\n", tx_dcch_info, (protocol_bs->rrc.next_MUI)-1,retcode); rrc_print_buffer (tx_dcch_info, 15); #endif } // clear resources protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_length = 0; // free(protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.msg_ptr); free_mem_block (protocol_bs->rrc.Mobile_List[msgId].rg_msg_infos.mem_block_ptr); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int pdcp_fifo_flush_sdus () { //----------------------------------------------------------------------------- mem_block_t *sdu = list_get_head (&pdcp_sdu_list); int bytes_wrote = 0; int pdcp_nb_sdu_sent = 0; uint8_t cont = 1; int ret; while ((sdu) && (cont)) { #ifdef USER_MODE // asjust the instance id when passing sdu to IP ((pdcp_data_ind_header_t *)(sdu->data))->inst = (((pdcp_data_ind_header_t *)(sdu->data))->inst >= NB_eNB_INST) ? ((pdcp_data_ind_header_t *)(sdu->data))->inst - NB_eNB_INST +oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local :// UE ((pdcp_data_ind_header_t *)(sdu->data))->inst - oai_emulation.info.first_ue_local; // ENB #else ((pdcp_data_ind_header_t *)(sdu->data))->inst = 0; #endif #ifdef PDCP_DEBUG msg("[PDCP][INFO] PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", Mac_rlc_xface->frame, ((pdcp_data_ind_header_t *)(sdu->data))->inst, ((pdcp_data_ind_header_t *)(sdu->data))->data_size, ((pdcp_data_ind_header_t *)(sdu->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); } #ifndef USER_MODE bytes_wrote = rtf_put (PDCP2NAS_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 NAS_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh), &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), pdcp_output_header_bytes_to_write); nas_nlh->nlmsg_len = pdcp_output_header_bytes_to_write; #endif //LINUX #endif //NAS_NETLINK bytes_wrote = pdcp_output_header_bytes_to_write; #endif //USER_MODE #ifdef PDCP_DEBUG msg("[PDCP][INFO] TTI %d Sent %d Bytes of header to Nas_mesh\n", Mac_rlc_xface->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->data)->data_size; #ifndef USER_MODE bytes_wrote = rtf_put (PDCP2NAS_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); #else #ifdef NAS_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh)+sizeof(pdcp_data_ind_header_t), &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); nas_nlh->nlmsg_len += pdcp_output_sdu_bytes_to_write; ret = sendmsg(nas_sock_fd,&nas_msg,0); if (ret<0) { msg("[PDCP_FIFOS] sendmsg returns %d\n",ret); perror("error code:"); mac_xface->macphy_exit(""); break; } #endif // LINUX #endif //NAS_NETLINK bytes_wrote= pdcp_output_sdu_bytes_to_write; #endif // USER_MODE #ifdef PDCP_DEBUG msg("[PDCP][INFO] PDCP->IP TTI %d INST %d: Sent %d Bytes of data from rab %d to Nas_mesh\n", Mac_rlc_xface->frame, ((pdcp_data_ind_header_t *)(sdu->data))->inst, bytes_wrote, ((pdcp_data_ind_header_t *)(sdu->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 // msg("rb sent a sdu qos_sap %d\n",sapiP); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu); cont = 1; pdcp_nb_sdu_sent += 1; sdu = list_get_head (&pdcp_sdu_list); } } else { msg ("[PDCP] RADIO->IP SEND SDU CONGESTION!\n"); } } else { msg ("[PDCP] RADIO->IP SEND SDU CONGESTION!\n"); } } } else { // continue writing sdu #ifndef USER_MODE bytes_wrote = rtf_put (PDCP2NAS_FIFO, (uint8_t *) (&(sdu->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu->data)->data_size - pdcp_output_sdu_bytes_to_write])), pdcp_output_sdu_bytes_to_write); #else // USER_MODE bytes_wrote = pdcp_output_sdu_bytes_to_write; #endif // USER_MODE 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); cont = 1; pdcp_nb_sdu_sent += 1; sdu = list_get_head (&pdcp_sdu_list); // msg("rb sent a sdu from rab\n"); } } } } #ifndef USER_MODE if ((pdcp_nb_sdu_sent)) { if ((pdcp_2_nas_irq > 0)) { #ifdef PDCP_DEBUG msg("[PDCP][INFO] TTI %d : Trigger NAS RX interrupt\n", Mac_rlc_xface->frame); #endif //PDCP_DEBUG rt_pend_linux_srq (pdcp_2_nas_irq); } else { msg ("[PDCP] TTI %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n", Mac_rlc_xface->frame, pdcp_2_nas_irq); } } #endif //USER_MODE return pdcp_nb_sdu_sent; }
//----------------------------------------------------------------------------- void rlc_am_reassemble_pdu( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP, mem_block_t * const tb_pP) { int i,j; rlc_am_pdu_info_t* pdu_info = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU SN=%03d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), pdu_info->sn); #if TRACE_RLC_AM_RX_DECODE rlc_am_display_data_pdu_infos(ctxt_pP, rlc_pP, pdu_info); #endif if (pdu_info->e == RLC_E_FIXED_PART_DATA_FIELD_FOLLOW) { switch (pdu_info->fi) { case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=11 (00)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); // one complete SDU rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size); rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary //rlc_pP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=10 (01)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); // one beginning segment of SDU in PDU rlc_am_send_sdu(ctxt_pP, rlc_pP); // may be not necessary rlc_am_reassembly (ctxt_pP, rlc_pP,pdu_info->payload, pdu_info->payload_size); //rlc_pP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=01 (10)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); // one last segment of SDU //if (rlc_pP->reassembly_missing_sn_detected == 0) { rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size); rlc_am_send_sdu(ctxt_pP, rlc_pP); //} // else { clear sdu already done //rlc_pP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=00 (11)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); //if (rlc_pP->reassembly_missing_sn_detected == 0) { // one whole segment of SDU in PDU rlc_am_reassembly (ctxt_pP, rlc_pP, pdu_info->payload, pdu_info->payload_size); //} else { // rlc_pP->reassembly_missing_sn_detected = 1; // not necessary but for readability of the code //} break; #if USER_MODE default: assert(0 != 0); #endif } } else { switch (pdu_info->fi) { case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=11 (00) Li=", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); // N complete SDUs rlc_am_send_sdu(ctxt_pP, rlc_pP); j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]); rlc_am_send_sdu(ctxt_pP, rlc_pP); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size); rlc_am_send_sdu(ctxt_pP, rlc_pP); } //rlc_pP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=10 (01) Li=", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); // N complete SDUs + one segment of SDU in PDU rlc_am_send_sdu(ctxt_pP, rlc_pP); j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]); rlc_am_send_sdu(ctxt_pP, rlc_pP); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size); } //rlc_pP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=01 (10) Li=", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); // one last segment of SDU + N complete SDUs in PDU j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]); rlc_am_send_sdu(ctxt_pP, rlc_pP); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size); rlc_am_send_sdu(ctxt_pP, rlc_pP); } //rlc_pP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU FI=00 (11) Li=", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->li_list[i]); rlc_am_send_sdu(ctxt_pP, rlc_pP); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size); } else { #if USER_MODE //assert (5!=5); #endif } //rlc_pP->reassembly_missing_sn_detected = 0; break; #if USER_MODE default: assert(1 != 1); #endif } } free_mem_block(tb_pP); }
//----------------------------------------------------------------------------- void rlc_am_reassemble_pdu(rlc_am_entity_t* rlcP, u32_t frame, u8_t eNB_flag, mem_block_t* tbP) { //----------------------------------------------------------------------------- int i,j; rlc_am_pdu_info_t* pdu_info = &((rlc_am_rx_pdu_management_t*)(tbP->data))->pdu_info; #ifdef TRACE_RLC_AM_REASSEMBLY LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU SN=%03d\n", frame, rlcP->module_id, rlcP->rb_id, pdu_info->sn); rlc_am_display_data_pdu_infos(rlcP, frame, pdu_info); #endif if (pdu_info->e == RLC_E_FIXED_PART_DATA_FIELD_FOLLOW) { switch (pdu_info->fi) { case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=11 (00)\n", frame, rlcP->module_id, rlcP->rb_id); #endif // one complete SDU rlc_am_send_sdu(rlcP,frame,eNB_flag); // may be not necessary rlc_am_reassembly (pdu_info->payload, pdu_info->payload_size, rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); // may be not necessary //rlcP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=10 (01)\n", frame, rlcP->module_id, rlcP->rb_id); #endif // one beginning segment of SDU in PDU rlc_am_send_sdu(rlcP,frame,eNB_flag); // may be not necessary rlc_am_reassembly (pdu_info->payload, pdu_info->payload_size, rlcP,frame); //rlcP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=01 (10)\n", frame, rlcP->module_id, rlcP->rb_id); #endif // one last segment of SDU //if (rlcP->reassembly_missing_sn_detected == 0) { rlc_am_reassembly (pdu_info->payload, pdu_info->payload_size, rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); //} // else { clear sdu already done //rlcP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU NO E_LI FI=00 (11)\n", frame, rlcP->module_id, rlcP->rb_id); #endif //if (rlcP->reassembly_missing_sn_detected == 0) { // one whole segment of SDU in PDU rlc_am_reassembly (pdu_info->payload, pdu_info->payload_size, rlcP,frame); //} else { // rlcP->reassembly_missing_sn_detected = 1; // not necessary but for readability of the code //} break; #ifdef USER_MODE default: assert(0 != 0); #endif } } else { switch (pdu_info->fi) { case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU FI=11 (00) Li=", frame, rlcP->module_id, rlcP->rb_id); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); #endif // N complete SDUs rlc_am_send_sdu(rlcP,frame,eNB_flag); j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (&pdu_info->payload[j], pdu_info->li_list[i], rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (&pdu_info->payload[j], pdu_info->hidden_size, rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); } //rlcP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU FI=10 (01) Li=", frame, rlcP->module_id, rlcP->rb_id); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); #endif // N complete SDUs + one segment of SDU in PDU rlc_am_send_sdu(rlcP,frame,eNB_flag); j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (&pdu_info->payload[j], pdu_info->li_list[i], rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (&pdu_info->payload[j], pdu_info->hidden_size, rlcP, frame); } //rlcP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU FI=01 (10) Li=", frame, rlcP->module_id, rlcP->rb_id); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); #endif // one last segment of SDU + N complete SDUs in PDU j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (&pdu_info->payload[j], pdu_info->li_list[i], rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (&pdu_info->payload[j], pdu_info->hidden_size, rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); } //rlcP->reassembly_missing_sn_detected = 0; break; case RLC_FI_1ST_BYTE_DATA_IS_NOT_1ST_BYTE_SDU_LAST_BYTE_DATA_IS_NOT_LAST_BYTE_SDU: #ifdef TRACE_RLC_AM_RX_DECODE LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PDU] TRY REASSEMBLY PDU FI=00 (11) Li=", frame, rlcP->module_id, rlcP->rb_id); for (i=0; i < pdu_info->num_li; i++) { LOG_D(RLC, "%d ",pdu_info->li_list[i]); } LOG_D(RLC, "\n"); //msg(" remaining size %d\n",size); #endif j = 0; for (i = 0; i < pdu_info->num_li; i++) { rlc_am_reassembly (&pdu_info->payload[j], pdu_info->li_list[i], rlcP,frame); rlc_am_send_sdu(rlcP,frame,eNB_flag); j = j + pdu_info->li_list[i]; } if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (&pdu_info->payload[j], pdu_info->hidden_size, rlcP,frame); } else { #ifdef USER_MODE //assert (5!=5); #endif } //rlcP->reassembly_missing_sn_detected = 0; break; #ifdef USER_MODE default: assert(1 != 1); #endif } } free_mem_block(tbP); }
//----------------------------------------------------------------------------- // Read data in DC FIFO int rrc_rg_read_DCin_FIFO (int UE_Id, u8 *buffer, int count){ //----------------------------------------------------------------------------- //int maxlen = NAS_MAX_LENGTH; int Message_Id; int data_length; //u8 rcve_buffer[maxlen]; struct nas_rg_dc_element *p; int prim_length; int prim_type; #ifdef ALLOW_MBMS_PROTOCOL int i; #endif if (count > 0) { #ifdef DEBUG_RRC_STATE msg ("[RRC_RG] Message Received from NAS: -%hx- for UE %d\n", buffer[0], UE_Id); #endif p = (struct nas_rg_dc_element *) buffer; prim_length = (int) (p->length); prim_type = (int) (p->type); #ifdef DEBUG_RRC_STATE msg ("[RRC_RG] Primitive Type %d,\t Primitive length %d \n", prim_type, prim_length); #endif //get the rest of the primitive //count += rtf_get (protocol_bs->rrc.rrc_rg_DCIn_fifo[UE_Id], &(rcve_buffer[NAS_TL_SIZE]), prim_length - NAS_TL_SIZE); //switch (rcve_buffer[0]) { switch (prim_type) { case CONN_ESTABLISH_CNF: if (protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref == (int) (p->nasRGDCPrimitive.conn_establish_conf.localConnectionRef)) { protocol_bs->rrc.establishment_cause = p->nasRGDCPrimitive.conn_establish_conf.status; //Temp FFS //protocol_bs->rrc.Mobile_List[UE_Id].rb_id = (int)(p->nasRGDCPrimitive.conn_establish_conf.num_RBs); #ifdef DEBUG_RRC_STATE msg ("[RRC_RG] primitive length: %d\t", (int) (p->length)); msg ("Local Connection reference: %d\t", p->nasRGDCPrimitive.conn_establish_conf.localConnectionRef); msg ("Establishment status: %d\n", (int) (protocol_bs->rrc.establishment_cause)); #endif rrc_rg_fsm_control (UE_Id, NAS_CONN_CNF); } break; case DATA_TRANSFER_REQ: if (protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref == (int) (p->nasRGDCPrimitive.data_transfer_req.localConnectionRef)) { data_length = (u16) p->nasRGDCPrimitive.data_transfer_req.nasDataLength; protocol_bs->rrc.Mobile_List[UE_Id].dl_nas_message_ptr = get_free_mem_block (data_length); protocol_bs->rrc.Mobile_List[UE_Id].dl_nas_message_lgth = data_length; //get the associated data #ifndef RRC_NETLINK count += rtf_get (protocol_bs->rrc.rrc_rg_DCIn_fifo[UE_Id], (protocol_bs->rrc.Mobile_List[UE_Id].dl_nas_message_ptr)->data, data_length); // memcpy((protocol_bs->rrc.Mobile_List[UE_Id].dl_nas_message_ptr)->data,&(rcve_buffer[p->length]),data_length); #else count += rrc_rg_read_data_from_nlh ((char *)(protocol_bs->rrc.Mobile_List[UE_Id].dl_nas_message_ptr)->data, data_length, (int) (p->length)); #endif #ifdef DEBUG_RRC_STATE rrc_print_buffer ((char *)buffer, count); msg ("[RRC_RG] DATA_TRANSFER_REQ primitive length: %d\n", (int) (p->length)); msg ("[RRC_RG] Local Connection reference: %d\n", p->nasRGDCPrimitive.data_transfer_req.localConnectionRef); msg ("[RRC_RG] Priority (not used yet): %d\n", p->nasRGDCPrimitive.data_transfer_req.priority); msg ("[RRC_RG] Data length: %d\n", data_length); rrc_print_buffer ((char *) (protocol_bs->rrc.Mobile_List[UE_Id].dl_nas_message_ptr)->data, data_length); #endif rrc_rg_msg_dlXfer (UE_Id, &Message_Id); RRC_RG_SEND_AM_SRB3 (UE_Id); free_mem_block (protocol_bs->rrc.Mobile_List[UE_Id].dl_nas_message_ptr); } break; case RB_ESTABLISH_REQ: if (protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref == (int) (p->nasRGDCPrimitive.rb_establish_req.localConnectionRef)) { #ifdef DEBUG_RRC_STATE rrc_print_buffer ((char *)buffer, count); msg ("[RRC_RG] RB_ESTABLISH_REQ primitive length: %d\n", (int) (p->length)); msg ("[RRC_RG] Local Connection reference: %d\n", p->nasRGDCPrimitive.rb_establish_req.localConnectionRef); msg ("[RRC_RG] RB Id: %d ", p->nasRGDCPrimitive.rb_establish_req.rbId); msg (" QoS Class: %d", p->nasRGDCPrimitive.rb_establish_req.QoSclass); msg (" IP DSCP: %d\n", p->nasRGDCPrimitive.rb_establish_req.dscp); #endif protocol_bs->rrc.Mobile_List[UE_Id].requested_rbId = p->nasRGDCPrimitive.rb_establish_req.rbId; protocol_bs->rrc.Mobile_List[UE_Id].requested_MTrbId = protocol_bs->rrc.Mobile_List[UE_Id].requested_rbId - (UE_Id * maxRB); protocol_bs->rrc.Mobile_List[UE_Id].requested_QoSclass = p->nasRGDCPrimitive.rb_establish_req.QoSclass; protocol_bs->rrc.Mobile_List[UE_Id].requested_dscp = p->nasRGDCPrimitive.rb_establish_req.dscp; if ((p->nasRGDCPrimitive.rb_establish_req.QoSclass >= 1) || (p->nasRGDCPrimitive.rb_establish_req.QoSclass <= RRC_QOS_LAST)) { rrc_rg_fsm_control (UE_Id, NAS_RB_ESTAB); }else{ RRC_RG_O_O_NAS_RB_Failure (UE_Id); } } break; case RB_RELEASE_REQ: if (protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref == (int) (p->nasRGDCPrimitive.rb_release_req.localConnectionRef)) { #ifdef DEBUG_RRC_STATE rrc_print_buffer ((char *)buffer, count); msg ("[RRC_RG] RB_RELEASE_REQ primitive length: %d\n", (int) (p->length)); msg ("[RRC_RG] Local Connection reference: %d\n", p->nasRGDCPrimitive.rb_release_req.localConnectionRef); msg ("[RRC_RG] RB Id: %d \n", p->nasRGDCPrimitive.rb_release_req.rbId); #endif protocol_bs->rrc.Mobile_List[UE_Id].requested_rbId = p->nasRGDCPrimitive.rb_establish_req.rbId; protocol_bs->rrc.Mobile_List[UE_Id].requested_MTrbId = protocol_bs->rrc.Mobile_List[UE_Id].requested_rbId - (UE_Id * maxRB); rrc_rg_fsm_control (UE_Id, NAS_RB_RELEASE); } break; #ifdef ALLOW_MBMS_PROTOCOL case MBMS_UE_NOTIFY_REQ: if (protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref == (int)(p->nasRGDCPrimitive.mbms_ue_notify_req.localConnectionRef)){ //Copy primitive information into the control block p_rg_mbms->nas_ueID = (int)(p->nasRGDCPrimitive.mbms_ue_notify_req.localConnectionRef); for (i = 0; i<MAX_MBMS_SERVICES; i++){ p_rg_mbms->nas_joinedServices[i] = p->nasRGDCPrimitive.mbms_ue_notify_req.joined_services[i].mbms_serviceId; p_rg_mbms->nas_leftServices[i] = p->nasRGDCPrimitive.mbms_ue_notify_req.left_services[i].mbms_serviceId; } #ifdef DEBUG_RRC_STATE rrc_print_buffer((char *)buffer,count); msg("[RRC_RG][MBMS] MBMS_UE_NOTIFY_REQ primitive length: %d\n",(int)(p->length)); msg("[RRC_RG][MBMS] Local Connection reference: %d\n",p->nasRGDCPrimitive.mbms_ue_notify_req.localConnectionRef); // msg("[RRC_RG][MBMS] Lists of joined services and left services are not shown \n"); #endif // rrc_rg_mbms_NAS_Notification_rx(UE_Id); //send notify to this MT rrc_rg_mbms_NAS_Notification_rx(); //send notify to this MT } break; #endif // end MBMS // Next message to be transferred to GC FIFO. case ENB_MEASUREMENT_REQ: // TEMP : CELL_ID coordination to be checked //if (protocol_bs->rrc.rg_cell_id == (int)(p->nasRGDCPrimitive.eNBmeasurement_req.cell_id)){ protocol_bs->rrc.eNB_measures_flag = 1; #ifdef DEBUG_RRC_STATE rrc_print_buffer((char *)buffer,count); msg("[RRC_RG] ENB_MEASUREMENT_REQ primitive length: %d\n",(int)(p->length)); msg("[RRC_RG] ENB measurement started for Cell_ID: %d\n",p->nasRGDCPrimitive.eNBmeasurement_req.cell_id); #endif //} break; default: msg ("[RRC_RG] Invalid message received in DC SAP\n"); rrc_print_buffer ((char *)buffer, count); count = -1; break; } } return count; return 0; }
BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rab_id, sdu_size_t sdu_buffer_size, \ unsigned char* sdu_buffer) #endif { //----------------------------------------------------------------------------- #ifdef PDCP_UNIT_TEST pdcp_t* pdcp = test_pdcp_entity; #else pdcp_t* pdcp = &pdcp_array[module_id][rab_id]; #endif mem_block_t* pdcp_pdu = NULL; u16 pdcp_pdu_size = sdu_buffer_size + PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE; LOG_I(PDCP, "Data request notification for PDCP entity with module ID %d and radio bearer ID %d pdu size %d\n", module_id, rab_id,pdcp_pdu_size); if (sdu_buffer_size == 0) { LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n"); return FALSE; } /* * XXX MAX_IP_PACKET_SIZE is 4096, shouldn't this be MAX SDU size, which is 8188 bytes? */ if (sdu_buffer_size > MAX_IP_PACKET_SIZE) { LOG_W(PDCP, "Requested SDU size (%d) is bigger than that can be handled by PDCP!\n", sdu_buffer_size); // XXX What does following call do? mac_xface->macphy_exit(""); } /* * Allocate a new block for the new PDU (i.e. PDU header and SDU payload) */ LOG_D(PDCP, "Asking for a new mem_block of size %d\n", pdcp_pdu_size); pdcp_pdu = get_free_mem_block(pdcp_pdu_size); if (pdcp_pdu != NULL) { /* * Create a Data PDU with header and append data * * Place User Plane PDCP Data PDU header first */ pdcp_user_plane_data_pdu_header_with_long_sn pdu_header; pdu_header.dc = PDCP_DATA_PDU; pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp); /* * Validate incoming sequence number, there might be a problem with PDCP initialization */ if (pdu_header.sn > pdcp_calculate_max_seq_num_for_given_size(pdcp->seq_num_size)) { LOG_E(PDCP, "Generated sequence number (%lu) is greater than a sequence number could ever be!\n", pdu_header.sn); LOG_E(PDCP, "There must be a problem with PDCP initialization, ignoring this PDU...\n"); free_mem_block(pdcp_pdu); return FALSE; } LOG_I(PDCP, "Sequence number %d is assigned to current PDU\n", pdu_header.sn); /* * Fill PDU buffer with the struct's fields */ if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char*)pdcp_pdu->data, &pdu_header) == FALSE) { LOG_W(PDCP, "Cannot fill PDU buffer with relevant header fields!\n"); return FALSE; } /* Then append data... */ memcpy(&pdcp_pdu->data[PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE], sdu_buffer, sdu_buffer_size); /* Print octets of outgoing data in hexadecimal form */ LOG_D(PDCP, "Following content will be sent over RLC (PDCP PDU header is the first two bytes)\n"); util_print_hex_octets(PDCP, (unsigned char*)pdcp_pdu->data, pdcp_pdu_size); #ifdef PDCP_UNIT_TEST /* * Here we add PDU to the list and return to test code without * handing it off to RLC */ list_add_tail_eurecom(pdcp_pdu, test_list); return TRUE; #else /* * Ask sublayer to transmit data and check return value * to see if RLC succeeded */ rlc_op_status_t rlc_status = rlc_data_req(module_id, frame, eNB_flag, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pdcp_pdu_size, pdcp_pdu); switch (rlc_status) { case RLC_OP_STATUS_OK: LOG_I(PDCP, "Data sending request over RLC succeeded!\n"); break; case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); return FALSE; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); return FALSE; case RLC_OP_STATUS_OUT_OF_RESSOURCES: LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); return FALSE; default: LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); return FALSE; } /* * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK * so we return TRUE afterwards */ if (eNB_flag == 1) { Pdcp_stats_tx[module_id][(rab_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_id & RAB_OFFSET)-DTCH]++; Pdcp_stats_tx_bytes[module_id][(rab_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_id & RAB_OFFSET)-DTCH] += sdu_buffer_size; } else {
//----------------------------------------------------------------------------- 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; }