/* Cell Update */ void rrc_ue_msg_cellUpdate(int *Message_Id){ //----------------------------------------------------------------------------- int status = P_SUCCESS; UL_CCCH_Message * ul_ccch_msg; mem_block_t *p; // Temp : Hard coded values protocol_ms->rrc.am_RLC_ErrorIndicationRb2_3or4 = FALSE; protocol_ms->rrc.am_RLC_ErrorIndicationRb5orAbove = FALSE; protocol_ms->rrc.cellUpdateCause = re_enteredServiceArea; // prepare encoding *Message_Id = ++ protocol_ms->rrc.ue_msg_infos.msg_Id; protocol_ms->rrc.ue_msg_infos.msg_length = MSG_HEAD_LGTH + sizeof(CellUpdate); // Temp - Test/Messages //ul_ccch_msg = malloc (protocol_ms->rrc.ue_msg_infos.msg_length); //memset (ul_ccch_msg, 0, protocol_ms->rrc.ue_msg_infos.msg_length); // //protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_ccch_msg; p = get_free_mem_block(protocol_ms->rrc.ue_msg_infos.msg_length); ul_ccch_msg = (struct UL_CCCH_Message *)p->data; // protocol_ms->rrc.ue_msg_infos.mem_block_ptr = p; protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_ccch_msg; // Encode ul_ccch_msg->integrityCheckInfo = 123; ul_ccch_msg->message.type = UL_CCCH_cellUpdate; status = rrc_PEREnc_CellUpdate ((CellUpdate*) &(ul_ccch_msg->message.content)); #ifdef DEBUG_RRC_STATE msg("\n[RRC_MSG] Cell Update - status : %d\n", status); msg("\n[RRC_MSG] Cell Update - length : %d\n", protocol_ms->rrc.ue_msg_infos.msg_length); rrc_print_buffer((char*)protocol_ms->rrc.ue_msg_infos.msg_ptr,protocol_ms->rrc.ue_msg_infos.msg_length); #endif }
//------------------------------------------------------------------- void RRC_RG_O_O_NAS_MBMS_RB_ESTAB_CNF (void){ //------------------------------------------------------------------- #ifdef MBMS_INTEGRATION_MODE // int rb_id; // int qos_class; // This is hard-coded to go in DC-SAP of MT 0, to avoid introducing an uplink GC-SAP in RG int UE_Id = 0; struct nas_rg_if_element *msgToBuild; mem_block_t *p = get_free_mem_block (sizeof (struct nas_rg_if_element)); protocol_bs->rrc.NASMessageToXmit = p; // Temp - will later enqueue at bottom of list //Set pointer to newly allocated structure and fills it msgToBuild = (struct nas_rg_if_element *) p->data; msgToBuild->prim_length = NAS_TL_SIZE + sizeof (struct NASMBMSBearerEstablishConf); msgToBuild->xmit_fifo = protocol_bs->rrc.rrc_rg_DCOut_fifo[UE_Id]; msgToBuild->nasRgPrimitive.dc_sap_prim.type = MBMS_BEARER_ESTABLISH_CNF; msgToBuild->nasRgPrimitive.dc_sap_prim.length = msgToBuild->prim_length; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.mbms_establish_cnf.rbId = p_rg_mbms->nas_rbId; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.mbms_establish_cnf.sapId = p_rg_mbms->nas_sapId; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.mbms_establish_cnf.status = p_rg_mbms->nas_status; #ifdef DEBUG_RRC_STATE msg ("[RRC-RG][MBMS][FSM-OUT] MBMS_BEARER_ESTABLISH_CNF primitive sent to NAS, for mobile %d.\n", UE_Id); #endif #endif }
//Output of primitives to NAS //------------------------------------------------------------------- void RRC_RG_O_O_NAS_CONN_ESTAB_IND (int UE_Id){ //------------------------------------------------------------------- struct nas_rg_if_element *msgToBuild; int j; mem_block_t *p = get_free_mem_block (sizeof (struct nas_rg_if_element)); protocol_bs->rrc.NASMessageToXmit = p; //Set pointer to newly allocated structure and fills it msgToBuild = (struct nas_rg_if_element *) p->data; msgToBuild->prim_length = NAS_TL_SIZE + sizeof (struct NASConnEstablishInd); msgToBuild->xmit_fifo = protocol_bs->rrc.rrc_rg_DCOut_fifo[UE_Id]; msgToBuild->nasRgPrimitive.dc_sap_prim.type = CONN_ESTABLISH_IND; msgToBuild->nasRgPrimitive.dc_sap_prim.length = msgToBuild->prim_length; // Initial setting of local connection reference - still TBD msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.conn_establish_ind.localConnectionRef = protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref; for (j = 0; j < 14; j++) msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.conn_establish_ind.InterfaceIMEI[j] = protocol_bs->rrc.Mobile_List[UE_Id].IMEI[j]; #ifdef DEBUG_RRC_STATE msg ("[RRC_RG][FSM-OUT] CONN Indication Message sent to NAS, for mobile %d.\n", UE_Id); msg ("[RRC] RG NAS PRIMITIVE ENCODE, length Id %d.\n", msgToBuild->prim_length); // msg("[RRC_DEBUG] Pointer p %p , Control Block %p.\n",p, protocol_bs->rrc.NASMessageToXmit); #endif }
//----------------------------------------------------------------------------- void rlc_tm_set_configured_parameters (struct rlc_tm_entity *rlcP, mem_block_t *cprimitiveP) { //----------------------------------------------------------------------------- // timers rlcP->timer_discard_init = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.timer_discard; // protocol_parameters rlcP->sdu_discard_mode = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.sdu_discard_mode; rlcP->segmentation_indication = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.segmentation_indication; rlcP->delivery_of_erroneous_sdu = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.delivery_of_erroneous_sdu; // SPARE : not 3GPP rlcP->frame_tick_milliseconds = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.frame_tick_milliseconds; rlcP->size_input_sdus_buffer = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.size_input_sdus_buffer; rlcP->rb_id = ((struct crlc_primitive *) cprimitiveP->data)->primitive.c_config_req.parameters.tm_parameters.rb_id; if ((rlcP->input_sdus_alloc == NULL) && (rlcP->size_input_sdus_buffer > 0)) { rlcP->input_sdus_alloc = get_free_mem_block (rlcP->size_input_sdus_buffer * sizeof (void *)); rlcP->input_sdus = (mem_block_t **) (rlcP->input_sdus_alloc->data); memset (rlcP->input_sdus, 0, rlcP->size_input_sdus_buffer * sizeof (void *)); } if (rlcP->segmentation_indication == RLC_TM_SEGMENTATION_ALLOWED) { rlcP->segmentation = rlc_tm_segment; rlcP->rx = rlc_tm_rx_segment; } else { rlcP->segmentation = rlc_tm_no_segment; rlcP->rx = rlc_tm_rx_no_segment; } }
//----------------------------------------------------------------------------- void config_req_rlc_tm (struct rlc_tm_entity *rlcP, module_id_t module_idP, rlc_tm_info_t * config_tmP, rb_id_t rb_idP, rb_type_t rb_typeP) { //----------------------------------------------------------------------------- mem_block_t *mb; mb = get_free_mem_block (sizeof (struct crlc_primitive)); ((struct crlc_primitive *) mb->data)->type = CRLC_CONFIG_REQ; ((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.e_r = RLC_E_R_ESTABLISHMENT; ((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.timer_discard = config_tmP->timer_discard; ((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.sdu_discard_mode = config_tmP->sdu_discard_mode; #warning frame_tick_milliseconds #ifdef NODE_RG //((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.frame_tick_milliseconds = &protocol_bs->frame_tick_milliseconds; #else //((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.frame_tick_milliseconds = &protocol_ms->frame_tick_milliseconds; #endif ((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.segmentation_indication = config_tmP->segmentation_indication; ((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.delivery_of_erroneous_sdu = config_tmP->delivery_of_erroneous_sdu; ((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.size_input_sdus_buffer = 128; ((struct crlc_primitive *) mb->data)->primitive.c_config_req.parameters.tm_parameters.rb_id = rb_idP; send_rlc_tm_control_primitive (rlcP, module_idP, mb); if (rb_typeP != SIGNALLING_RADIO_BEARER) { rlcP->data_plane = 1; } else { rlcP->data_plane = 0; } }
//----------------------------------------------------------------------------- void rlc_tm_init ( const protocol_ctxt_t* const ctxt_pP, rlc_tm_entity_t * const rlcP ) { int saved_allocation = rlcP->allocation; memset (rlcP, 0, sizeof (struct rlc_tm_entity)); rlcP->allocation = saved_allocation; // TX SIDE list_init (&rlcP->pdus_to_mac_layer, NULL); rlcP->protocol_state = RLC_NULL_STATE; rlcP->nb_sdu = 0; rlcP->next_sdu_index = 0; rlcP->current_sdu_index = 0; rlcP->output_sdu_size_to_write = 0; rlcP->buffer_occupancy = 0; // SPARE : not 3GPP rlcP->size_input_sdus_buffer = 16; if ((rlcP->input_sdus_alloc == NULL) && (rlcP->size_input_sdus_buffer > 0)) { rlcP->input_sdus_alloc = get_free_mem_block (rlcP->size_input_sdus_buffer * sizeof (void *)); rlcP->input_sdus = (mem_block_t **) (rlcP->input_sdus_alloc->data); memset (rlcP->input_sdus, 0, rlcP->size_input_sdus_buffer * sizeof (void *)); } }
//----------------------------------------------------------------------------- void rrc_ue_msg_measrep(int *Message_Id){ //----------------------------------------------------------------------------- int status = P_SUCCESS; UL_DCCH_Message * ul_dcch_msg; mem_block_t *p; // prepare encoding *Message_Id = ++ protocol_ms->rrc.ue_msg_infos.msg_Id; protocol_ms->rrc.ue_msg_infos.msg_length = MSG_HEAD_LGTH + sizeof(MeasurementReport); // Temp - Test/Messages // ul_dcch_msg = malloc (protocol_ms->rrc.ue_msg_infos.msg_length); // memset (ul_dcch_msg, 0, protocol_ms->rrc.ue_msg_infos.msg_length); // // protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_dcch_msg; p = get_free_mem_block(protocol_ms->rrc.ue_msg_infos.msg_length); ul_dcch_msg = (struct UL_DCCH_Message *)p->data; // protocol_ms->rrc.ue_msg_infos.mem_block_ptr = p; protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_dcch_msg; // Encode ul_dcch_msg->integrityCheckInfo = 123; ul_dcch_msg->message.type = UL_DCCH_measurementReport; status = rrc_PEREnc_MeasurementReport((MeasurementReport*) &(ul_dcch_msg->message.content)); #ifdef DEBUG_RRC_STATE msg("\n[RRC_MSG] Measurement Report - status : %d - length : %d\n", status, protocol_ms->rrc.ue_msg_infos.msg_length); rrc_print_buffer((char*)protocol_ms->rrc.ue_msg_infos.msg_ptr,protocol_ms->rrc.ue_msg_infos.msg_length); #endif }
/* RRC Connection Setup Complete */ void rrc_ue_msg_connsucompl(int *Message_Id){ //----------------------------------------------------------------------------- int status = P_SUCCESS; UL_DCCH_Message * ul_dcch_msg; mem_block_t *p; // prepare encoding *Message_Id = ++ protocol_ms->rrc.ue_msg_infos.msg_Id; protocol_ms->rrc.ue_msg_infos.msg_length = MSG_HEAD_LGTH + sizeof(RRCConnectionSetupComplete); // Temp - Test/Messages // ul_dcch_msg = malloc (protocol_ms->rrc.ue_msg_infos.msg_length); // memset (ul_dcch_msg, 0, protocol_ms->rrc.ue_msg_infos.msg_length); // // // protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_dcch_msg; p = get_free_mem_block(protocol_ms->rrc.ue_msg_infos.msg_length); ul_dcch_msg = (struct UL_DCCH_Message *)p->data; // protocol_ms->rrc.ue_msg_infos.mem_block_ptr = p; protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_dcch_msg; // Encode ul_dcch_msg->integrityCheckInfo = 0; // No check with RRC Connection Setup Complete ul_dcch_msg->message.type = UL_DCCH_rrcConnectionSetupComplete; status = rrc_PEREnc_RRCConnectionSetupComplete((RRCConnectionSetupComplete*) &(ul_dcch_msg->message.content)); #ifdef DEBUG_RRC_STATE msg("\n[RRC_MSG] Connection Setup Compl - status : %d - length : %d\n", status, protocol_ms->rrc.ue_msg_infos.msg_length); rrc_print_buffer((char*)protocol_ms->rrc.ue_msg_infos.msg_ptr,protocol_ms->rrc.ue_msg_infos.msg_length); #endif }
//----------------------------------------------------------------------------- void rlc_um_reassembly (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP, uint8_t * src_pP, int32_t lengthP) { //----------------------------------------------------------------------------- sdu_size_t sdu_max_size; LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT"[REASSEMBLY] reassembly() %d bytes %d bytes already reassemblied\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), lengthP, rlc_pP->output_sdu_size_to_write); if (lengthP <= 0) { return; } if ((rlc_pP->is_data_plane)) { sdu_max_size = RLC_SDU_MAX_SIZE_DATA_PLANE; } else { sdu_max_size = RLC_SDU_MAX_SIZE_CONTROL_PLANE; } if (rlc_pP->output_sdu_in_construction == NULL) { // msg("[RLC_UM_LITE] Getting mem_block ...\n"); rlc_pP->output_sdu_in_construction = get_free_mem_block (sdu_max_size); rlc_pP->output_sdu_size_to_write = 0; } if ((rlc_pP->output_sdu_in_construction)) { // check if no overflow in size if ((rlc_pP->output_sdu_size_to_write + lengthP) <= sdu_max_size) { memcpy (&rlc_pP->output_sdu_in_construction->data[rlc_pP->output_sdu_size_to_write], src_pP, lengthP); rlc_pP->output_sdu_size_to_write += lengthP; #ifdef TRACE_RLC_UM_DISPLAY_ASCII_DATA rlc_pP->output_sdu_in_construction->data[rlc_pP->output_sdu_size_to_write] = 0; LOG_T(RLC, PROTOCOL_RLC_UM_CTXT_FMT"[REASSEMBLY] DATA :", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP)); rlc_util_print_hex_octets(RLC, (unsigned char*)rlc_pP->output_sdu_in_construction->data, rlc_pP->output_sdu_size_to_write); #endif } else { #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) AssertFatal(0, PROTOCOL_RLC_UM_CTXT_FMT" RLC_UM_DATA_IND, SDU TOO BIG, DROPPED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP)); #endif LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT"[REASSEMBLY] [max_sdu size %d] ERROR SDU SIZE OVERFLOW SDU GARBAGED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), sdu_max_size); // erase SDU rlc_pP->output_sdu_size_to_write = 0; } } else { LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT"[REASSEMBLY]ERROR OUTPUT SDU IS NULL\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP)); #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) AssertFatal(0, PROTOCOL_RLC_UM_CTXT_FMT" RLC_UM_DATA_IND, SDU DROPPED, OUT OF MEMORY\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP)); #endif } }
//----------------------------------------------------------------------------- mem_block_t * umts_add_timer_list_up (list2_t * atimer_listP, void (*procP) (void *, void *), void *protocolP, void *timer_idP, uint32_t frame_time_outP, uint32_t current_frame_tick_millisecondsP) { //----------------------------------------------------------------------------- struct mem_block_t *mb; struct timer_unit *timer; mem_block_t *mem_unit; int32_t remaining_time; uint8_t inserted = 0; mb = get_free_mem_block (sizeof (struct timer_unit)); ((struct timer_unit *) (mb->data))->proc = procP; ((struct timer_unit *) (mb->data))->protocol = protocolP; ((struct timer_unit *) (mb->data))->timer_id = timer_idP; ((struct timer_unit *) (mb->data))->frame_time_out = frame_time_outP; ((struct timer_unit *) (mb->data))->frame_tick_start = current_frame_tick_millisecondsP; // insert the timer in list in ascending order mem_unit = atimer_listP->head; while ((mem_unit) && (!inserted)) { timer = (struct timer_unit *) (mem_unit->data); remaining_time = timer->frame_time_out - current_frame_tick_millisecondsP + timer->frame_tick_start; // not timed out if ((remaining_time > 0) && (frame_time_outP < remaining_time)) { inserted = 255; if (mem_unit == atimer_listP->head) { #ifdef DEBUG_TIMER msg ("[TIMER][CREATION] added timer_id %p at head time out %d current time %d proc %p \n", timer_idP, frame_time_outP, current_frame_tick_millisecondsP, *procP); #endif list2_add_head (mb, atimer_listP); } else { #ifdef DEBUG_TIMER msg ("[TIMER][CREATION] inserted timer_id %p time out %d current time %d proc %p \n", timer_idP, frame_time_outP, current_frame_tick_millisecondsP, *procP); #endif mb->previous = mem_unit->previous; mb->next = mem_unit; mem_unit->previous->next = mb; mem_unit->previous = mb; } } else { mem_unit = mem_unit->next; } } if (!inserted) { #ifdef DEBUG_TIMER msg ("[TIMER][CREATION] added timer_id %p at tail time out %d current time %d proc %p \n", timer_idP, frame_time_outP, current_frame_tick_millisecondsP, *procP); #endif list2_add_tail (mb, atimer_listP); } return mb; }
//----------------------------------------------------------------------------- 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 configure_pdcp_req (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP) { //----------------------------------------------------------------------------- mem_block *mb; mb = get_free_mem_block (sizeof (struct cpdcp_primitive)); ((struct cpdcp_primitive *) mb->data)->type = CPDCP_CONFIG_REQ; ((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_sap = rlcP; ((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_type_sap = rlc_sap_typeP; ((struct cpdcp_primitive *) mb->data)->primitive.config_req.header_compression_type = header_compression_typeP; send_pdcp_control_primitive (pdcpP, mb); }
//----------------------------------------------------------------------------- struct mac_data_ind mac_rlc_deserialize_tb ( char *buffer_pP, const tb_size_t tb_sizeP, num_tb_t num_tbP, crc_t *crcs_pP) { //----------------------------------------------------------------------------- struct mac_data_ind data_ind; mem_block_t* tb_p; num_tb_t nb_tb_read; tbs_size_t tbs_size; nb_tb_read = 0; tbs_size = 0; list_init(&data_ind.data, NULL); while (num_tbP > 0) { tb_p = get_free_mem_block(sizeof (mac_rlc_max_rx_header_size_t) + tb_sizeP); if (tb_p != NULL) { ((struct mac_tb_ind *) (tb_p->data))->first_bit = 0; ((struct mac_tb_ind *) (tb_p->data))->data_ptr = (uint8_t*)&tb_p->data[sizeof (mac_rlc_max_rx_header_size_t)]; ((struct mac_tb_ind *) (tb_p->data))->size = tb_sizeP; if (crcs_pP) { ((struct mac_tb_ind *) (tb_p->data))->error_indication = crcs_pP[nb_tb_read]; } else { ((struct mac_tb_ind *) (tb_p->data))->error_indication = 0; } memcpy(((struct mac_tb_ind *) (tb_p->data))->data_ptr, &buffer_pP[tbs_size], tb_sizeP); #ifdef DEBUG_MAC_INTERFACE #if defined(TRACE_RLC_PAYLOAD) LOG_T(RLC, "[MAC-RLC] DUMP RX PDU(%d bytes):\n", tb_sizeP); rlc_util_print_hex_octets(RLC, ((struct mac_tb_ind *) (tb_p->data))->data_ptr, tb_sizeP); #endif #endif nb_tb_read = nb_tb_read + 1; tbs_size = tbs_size + tb_sizeP; list_add_tail_eurecom(tb_p, &data_ind.data); } num_tbP = num_tbP - 1; } data_ind.no_tb = nb_tb_read; data_ind.tb_size = tb_sizeP << 3; return data_ind; }
//----------------------------------------------------------------------------- void rrc_rg_fill_Seg2 (PERParms * pParms){ //----------------------------------------------------------------------------- FirstSegment *pSegment; #ifdef DEBUG_RRC_BROADCAST_DETAILS msg ("[RRC_BCH-RG] Fill First Segment. \n"); #endif // Temp malloc for test //pSegment = malloc(sizeof(FirstSegment)); protocol_bs->rrc.rg_bch_blocks.tSegment = get_free_mem_block (sizeof (FirstSegment)); pSegment = (FirstSegment *) protocol_bs->rrc.rg_bch_blocks.tSegment->data; // protocol_bs->rrc.rg_bch_blocks.currSI_BCH.payload.segment.firstSegment = pSegment; pSegment->sib_Type = protocol_bs->rrc.rg_bch_blocks.curr_block_type; if ((protocol_bs->rrc.rg_bch_blocks.curr_block_length % LSIBfixed) == 0) pSegment->seg_Count = (protocol_bs->rrc.rg_bch_blocks.curr_block_length / LSIBfixed); else pSegment->seg_Count = (protocol_bs->rrc.rg_bch_blocks.curr_block_length / LSIBfixed) + 1; protocol_bs->rrc.rg_bch_blocks.curr_segment_index = 0; pParms->data_size = protocol_bs->rrc.rg_bch_blocks.curr_block_length; pParms->data_offset = 0; pSegment->sib_Data_fixed.numbits = 0; switch (protocol_bs->rrc.rg_bch_blocks.curr_block_type) { case masterInformationBlock: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currMIB); break; case systemInformationBlockType1: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB1); break; // SIB2 is never segmented case systemInformationBlockType5: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB5); break; case systemInformationBlockType14: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB14); break; case systemInformationBlockType18: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB18); break; default: pParms->data = 0; #ifdef DEBUG_RRC_BROADCAST msg ("[RRC_BCH-RG] Error rrc_rg_fill_Seg2 - switch default \n"); #endif } protocol_bs->rrc.rg_bch_blocks.curr_block_index += LSIBfixed; }
//----------------------------------------------------------------------------- void rrc_rg_fill_Seg11 (PERParms * pParms){ //----------------------------------------------------------------------------- LastSegment *pSegment; char *pTemp = NULL; #ifdef DEBUG_RRC_BROADCAST_DETAILS msg ("[RRC_BCH-RG] Fill Last Segment. \n"); #endif // Temp malloc for test //pSegment = malloc(sizeof(LastSegment)); protocol_bs->rrc.rg_bch_blocks.tSegment = get_free_mem_block (sizeof (LastSegment)); pSegment = (LastSegment *) protocol_bs->rrc.rg_bch_blocks.tSegment->data; // protocol_bs->rrc.rg_bch_blocks.currSI_BCH.payload.segment.lastSegment = pSegment; pSegment->sib_Type = protocol_bs->rrc.rg_bch_blocks.curr_block_type; protocol_bs->rrc.rg_bch_blocks.curr_segment_index += 1; pSegment->segmentIndex = protocol_bs->rrc.rg_bch_blocks.curr_segment_index; pSegment->sib_Data_fixed.numbits = 0; pParms->data_offset = protocol_bs->rrc.rg_bch_blocks.curr_block_index; switch (protocol_bs->rrc.rg_bch_blocks.curr_block_type) { case masterInformationBlock: pTemp = (char *) (&(protocol_bs->rrc.rg_bch_blocks.encoded_currMIB)) + protocol_bs->rrc.rg_bch_blocks.curr_block_index; break; case systemInformationBlockType1: pTemp = (char *) (&(protocol_bs->rrc.rg_bch_blocks.encoded_currSIB1)) + protocol_bs->rrc.rg_bch_blocks.curr_block_index; break; // SIB2 is never segmented case systemInformationBlockType5: pTemp = (char *) (&(protocol_bs->rrc.rg_bch_blocks.encoded_currSIB5)) + protocol_bs->rrc.rg_bch_blocks.curr_block_index; break; case systemInformationBlockType14: pTemp = (char *) (&(protocol_bs->rrc.rg_bch_blocks.encoded_currSIB14)) + protocol_bs->rrc.rg_bch_blocks.curr_block_index; break; case systemInformationBlockType18: pTemp = (char *) (&(protocol_bs->rrc.rg_bch_blocks.encoded_currSIB18)) + protocol_bs->rrc.rg_bch_blocks.curr_block_index; break; default: pParms->data = 0; #ifdef DEBUG_RRC_BROADCAST msg ("[RRC_BCH-RG] Error rrc_rg_fill_Seg11 - switch default \n"); #endif } pParms->data = (ENCODEDBLOCK *) pTemp; protocol_bs->rrc.rg_bch_blocks.curr_block_type = NO_BLOCK; protocol_bs->rrc.rg_bch_blocks.curr_block_index = 0; }
//----------------------------------------------------------------------------- void rlc_um_reassembly (uint8_t * srcP, int32_t lengthP, struct rlc_um_entity *rlcP) { //----------------------------------------------------------------------------- int sdu_max_size; #ifdef DEBUG_RLC_UM_DISPLAY_ASCII_DATA int index; #endif #ifdef DEBUG_RLC_UM_REASSEMBLY msg ("[RLC_UM_LITE][MOD %d][RB %d][REASSEMBLY] reassembly() %d bytes\n", rlcP->module_id, rlcP->rb_id, lengthP); #endif if ((rlcP->data_plane)) { sdu_max_size = RLC_SDU_MAX_SIZE_DATA_PLANE; } else { sdu_max_size = RLC_SDU_MAX_SIZE_CONTROL_PLANE; } if (rlcP->output_sdu_in_construction == NULL) { // msg("[RLC_UM_LITE] Getting mem_block ...\n"); rlcP->output_sdu_in_construction = get_free_mem_block (sdu_max_size); rlcP->output_sdu_size_to_write = 0; } if ((rlcP->output_sdu_in_construction)) { #ifdef DEBUG_RLC_UM_DISPLAY_ASCII_DATA msg ("[RLC_UM_LITE][RB %d][REASSEMBLY] DATA :", rlcP->rb_id); for (index = 0; index < lengthP; index++) { msg ("%02X.", srcP[index]); } msg ("\n"); #endif // check if no overflow in size if ((rlcP->output_sdu_size_to_write + lengthP) <= sdu_max_size) { memcpy (&rlcP->output_sdu_in_construction->data[rlcP->output_sdu_size_to_write], srcP, lengthP); rlcP->output_sdu_size_to_write += lengthP; } else { msg ("[RLC_UM_LITE][RB %d][REASSEMBLY] ERROR SDU SIZE OVERFLOW SDU GARBAGED\n", rlcP->rb_id); // erase SDU rlcP->output_sdu_size_to_write = 0; } } else { msg ("[RLC_UM_LITE][RB %d][REASSEMBLY] ERROR OUTPUT SDU IS NULL\n", rlcP->rb_id); } }
//------------------------------------------------------------------- void RRC_RG_O_O_NAS_CONN_LOSS_IND (int UE_Id){ //------------------------------------------------------------------- struct nas_rg_if_element *msgToBuild; mem_block_t *p = get_free_mem_block (sizeof (struct nas_rg_if_element)); protocol_bs->rrc.NASMessageToXmit = p; // Temp - will later enqueue at bottom of list //Set pointer to newly allocated structure and fills it msgToBuild = (struct nas_rg_if_element *) p->data; msgToBuild->prim_length = NAS_TL_SIZE + sizeof (struct NASConnLossInd); msgToBuild->xmit_fifo = protocol_bs->rrc.rrc_rg_DCOut_fifo[UE_Id]; msgToBuild->nasRgPrimitive.dc_sap_prim.type = CONN_LOSS_IND; msgToBuild->nasRgPrimitive.dc_sap_prim.length = msgToBuild->prim_length; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.conn_loss_ind.localConnectionRef = protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref; #ifdef DEBUG_RRC_STATE msg ("[RRC][FSM-OUT] CONN LOSS IND primitive sent to NAS, length %d.\n", msgToBuild->prim_length); #endif }
//----------------------------------------------------------------------------- void rrc_rg_fill_Seg10 (PERParms * pParms){ //----------------------------------------------------------------------------- CompleteSIB *pSegment; #ifdef DEBUG_RRC_BROADCAST_DETAILS msg ("[RRC_BCH-RG] Fill Complete SIB. \n"); #endif // Temp malloc for test //pSegment = malloc(sizeof(CompleteSIB)); protocol_bs->rrc.rg_bch_blocks.tSegment = get_free_mem_block (sizeof (CompleteSIB)); pSegment = (CompleteSIB *) protocol_bs->rrc.rg_bch_blocks.tSegment->data; // protocol_bs->rrc.rg_bch_blocks.currSI_BCH.payload.segment.completeSIB = pSegment; pSegment->sib_Type = protocol_bs->rrc.rg_bch_blocks.curr_block_type; pSegment->sib_Data_fixed.numbits = 0; switch (protocol_bs->rrc.rg_bch_blocks.curr_block_type) { case masterInformationBlock: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currMIB); break; case systemInformationBlockType1: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB1); break; case systemInformationBlockType2: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB2); break; case systemInformationBlockType5: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB5); break; case systemInformationBlockType14: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB14); break; case systemInformationBlockType18: pParms->data = (ENCODEDBLOCK *) & (protocol_bs->rrc.rg_bch_blocks.encoded_currSIB18); break; default: pParms->data = 0; //log error message #ifdef DEBUG_RRC_BROADCAST msg ("[RRC_BCH-RG] Error rrc_rg_fill_Seg10 - switch default \n"); #endif } protocol_bs->rrc.rg_bch_blocks.curr_block_type = NO_BLOCK; }
//----------------------------------------------------------------------------- void rlc_am_reassembly ( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP, uint8_t * src_pP, const int32_t lengthP) //----------------------------------------------------------------------------- { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PAYLOAD] reassembly() %d bytes\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), lengthP); if (rlc_pP->output_sdu_in_construction == NULL) { rlc_pP->output_sdu_in_construction = get_free_mem_block (RLC_SDU_MAX_SIZE); rlc_pP->output_sdu_size_to_write = 0; assert(rlc_pP->output_sdu_in_construction != NULL); } if (rlc_pP->output_sdu_in_construction != NULL) { // check if no overflow in size if ((rlc_pP->output_sdu_size_to_write + lengthP) <= RLC_SDU_MAX_SIZE) { memcpy (&rlc_pP->output_sdu_in_construction->data[rlc_pP->output_sdu_size_to_write], src_pP, lengthP); rlc_pP->output_sdu_size_to_write += lengthP; } else { LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PAYLOAD] ERROR SDU SIZE OVERFLOW SDU GARBAGED\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) AssertFatal(0, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_IND, SDU SIZE OVERFLOW SDU GARBAGED\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); #endif // erase SDU rlc_pP->output_sdu_size_to_write = 0; } } else { LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PAYLOAD] ERROR OUTPUT SDU IS NULL\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) AssertFatal(0, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_IND, SDU DROPPED, OUT OF MEMORY\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); #endif } }
//----------------------------------------------------------------------------- void rlc_am_reassembly (u8_t * srcP, s32_t lengthP, rlc_am_entity_t *rlcP, u32_t frame) //----------------------------------------------------------------------------- { #ifdef TRACE_RLC_AM_DISPLAY_HEX_DATA int index; #endif #ifdef TRACE_RLC_AM_REASSEMBLY LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PAYLOAD] reassembly() %d bytes\n", frame, rlcP->module_id, rlcP->rb_id, lengthP); #endif if (rlcP->output_sdu_in_construction == NULL) { rlcP->output_sdu_in_construction = get_free_mem_block (RLC_SDU_MAX_SIZE); rlcP->output_sdu_size_to_write = 0; assert(rlcP->output_sdu_in_construction != NULL); } if (rlcP->output_sdu_in_construction != NULL) { #ifdef TRACE_RLC_AM_DISPLAY_HEX_DATA LOG_T(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PAYLOAD] DATA :", frame, rlcP->module_id, rlcP->rb_id); for (index = 0; index < lengthP; index++) { LOG_T(RLC, "%02X.", srcP[index]); } msg ("\n"); #endif // check if no overflow in size if ((rlcP->output_sdu_size_to_write + lengthP) <= RLC_SDU_MAX_SIZE) { memcpy (&rlcP->output_sdu_in_construction->data[rlcP->output_sdu_size_to_write], srcP, lengthP); #ifdef TRACE_RLC_AM_DISPLAY_ASCII_DATA rlcP->output_sdu_in_construction->data[rlcP->output_sdu_size_to_write + lengthP] = 0; LOG_T(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PAYLOAD] DATA :", frame, rlcP->module_id, rlcP->rb_id); LOG_T(RLC, "%s\n", &rlcP->output_sdu_in_construction->data[rlcP->output_sdu_size_to_write]); #endif rlcP->output_sdu_size_to_write += lengthP; } else { LOG_E(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PAYLOAD] ERROR SDU SIZE OVERFLOW SDU GARBAGED\n", frame, rlcP->module_id, rlcP->rb_id); // erase SDU rlcP->output_sdu_size_to_write = 0; } } else { LOG_E(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][REASSEMBLY PAYLOAD] ERROR OUTPUT SDU IS NULL\n", frame, rlcP->module_id, rlcP->rb_id); } }
//------------------------------------------------------------------- void RRC_RG_O_O_NAS_RB_ESTAB_CNF (int UE_Id){ //------------------------------------------------------------------- struct nas_rg_if_element *msgToBuild; mem_block_t *p = get_free_mem_block (sizeof (struct nas_rg_if_element)); protocol_bs->rrc.NASMessageToXmit = p; // Temp - will later enqueue at bottom of list //Set pointer to newly allocated structure and fills it msgToBuild = (struct nas_rg_if_element *) p->data; msgToBuild->prim_length = NAS_TL_SIZE + sizeof (struct NASrbEstablishConf); msgToBuild->xmit_fifo = protocol_bs->rrc.rrc_rg_DCOut_fifo[UE_Id]; msgToBuild->nasRgPrimitive.dc_sap_prim.type = RB_ESTABLISH_CNF; msgToBuild->nasRgPrimitive.dc_sap_prim.length = msgToBuild->prim_length; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.rb_establish_conf.localConnectionRef = protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.rb_establish_conf.rbId = protocol_bs->rrc.Mobile_List[UE_Id].requested_rbId; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.rb_establish_conf.sapId = protocol_bs->rrc.Mobile_List[UE_Id].requested_sapid; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.rb_establish_conf.status = ACCEPTED; #ifdef DEBUG_RRC_STATE msg ("[RRC_RG][FSM-OUT] RB_ESTABLISH_Cnf primitive sent to NAS, for mobile %d, RB %u.\n", UE_Id, protocol_bs->rrc.Mobile_List[UE_Id].requested_rbId); #endif }
//----------------------------------------------------------------------------- rlc_op_status_t rrc_rlc_data_req ( const protocol_ctxt_t* const ctxt_pP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_sizeP, char* sduP) { //----------------------------------------------------------------------------- mem_block_t* sdu; sdu = get_free_mem_block(sdu_sizeP); if (sdu != NULL) { memcpy (sdu->data, sduP, sdu_sizeP); return rlc_data_req(ctxt_pP, SRB_FLAG_YES, MBMS_flagP, rb_idP, muiP, confirmP, sdu_sizeP, sdu); } else { return RLC_OP_STATUS_INTERNAL_ERROR; } }
//----------------------------------------------------------------------------- rlc_op_status_t rrc_rlc_data_req ( const module_id_t enb_mod_idP, const module_id_t ue_mod_idP, const frame_t frameP, const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_sizeP, char* sduP) { //----------------------------------------------------------------------------- mem_block_t* sdu; sdu = get_free_mem_block(sdu_sizeP); if (sdu != NULL) { memcpy (sdu->data, sduP, sdu_sizeP); return rlc_data_req(enb_mod_idP, ue_mod_idP, frameP, enb_flagP, SRB_FLAG_YES, MBMS_flagP, rb_idP, muiP, confirmP, sdu_sizeP, sdu); } else { return RLC_OP_STATUS_INTERNAL_ERROR; } }
//----------------------------------------------------------------------------- void pdcp_data_req (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, char* sduP) { //----------------------------------------------------------------------------- mem_block_t *new_sdu = NULL; int i; if ((data_sizeP > 0)) { if(data_sizeP > MAX_IP_PACKET_SIZE){ msg("[PDCP] REQ FOR SIZE %d !!!Abort\n",data_sizeP); mac_xface->macphy_exit(""); } new_sdu = get_free_mem_block (data_sizeP); if (new_sdu) { #ifdef PDCP_DATA_REQ_DEBUG msg("[PDCP] TTI %d, INST %d: PDCP_DATA_REQ size %d RAB %d:\n",Mac_rlc_xface->frame,module_idP,data_sizeP,rab_idP); // for (i=0;i<20;i++) // msg("%02X.",((unsigned char*)sduP)[i]); // msg("\n"); #endif PDCP_DATA_REQ_DEBUG // PROCESS OF DECOMPRESSION HERE: memcpy (&new_sdu->data[0], sduP, data_sizeP); rlc_data_req(module_idP, rab_idP, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, data_sizeP, new_sdu); if(Mac_rlc_xface->Is_cluster_head[module_idP]==1){ Pdcp_stats_tx[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]++; Pdcp_stats_tx_bytes[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]+=data_sizeP; } else{ Pdcp_stats_tx[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]++; Pdcp_stats_tx_bytes[module_idP][(rab_idP & RAB_OFFSET2 )>> RAB_SHIFT2][(rab_idP & RAB_OFFSET)-DTCH]+=data_sizeP; } } else {
//----------------------------------------------------------------------------- void rlc_um_reassembly (u8_t * srcP, u16_t lengthP, struct rlc_um_entity *rlcP) { //----------------------------------------------------------------------------- int sdu_max_size; #ifdef DEBUG_RLC_UM_DISPLAY_ASCII_DATA int index; #endif #ifdef DEBUG_RLC_UM_REASSEMBLY msg ("[RLC_UM][RB %d][REASSEMBLY] reassembly() %d bytes\n", rlcP->rb_id, lengthP); #endif if ((rlcP->data_plane)) { sdu_max_size = RLC_SDU_MAX_SIZE_DATA_PLANE; } else { sdu_max_size = RLC_SDU_MAX_SIZE_CONTROL_PLANE; } if (rlcP->output_sdu_in_construction == NULL) { rlcP->output_sdu_in_construction = get_free_mem_block (sdu_max_size + sizeof (struct rlc_indication)); rlcP->output_sdu_size_to_write = 0; } if ((rlcP->output_sdu_in_construction)) { #ifdef DEBUG_RLC_UM_DISPLAY_ASCII_DATA msg ("[RLC_UM][RB %d][REASSEMBLY] DATA :", rlcP->rb_id); for (index = 0; index < lengthP; index++) { msg ("%02X-", srcP[index]); } msg ("\n"); #endif memcpy (&rlcP->output_sdu_in_construction->data[rlcP->output_sdu_size_to_write + sizeof (struct rlc_indication)], srcP, lengthP); rlcP->output_sdu_size_to_write += lengthP; } else { msg ("[RLC_UM][RB %d][REASSEMBLY] ERROR OUTPUT SDU IS NULL\n", rlcP->rb_id); } }
//------------------------------------------------------------------- void RRC_RG_O_NAS_ENB_MEASUREMENT_IND (void){ //------------------------------------------------------------------- int UE_Id = 0; int num_connected_UEs; int ix; struct nas_rg_if_element *msgToBuild; mem_block_t *p = get_free_mem_block (sizeof (struct nas_rg_if_element)); protocol_bs->rrc.NASMessageToXmit = p; // Temp - will later enqueue at bottom of list //Set pointer to newly allocated structure and fills it msgToBuild = (struct nas_rg_if_element *) p->data; msgToBuild->prim_length = NAS_TL_SIZE + sizeof (struct NASEnbMeasureInd); msgToBuild->xmit_fifo = protocol_bs->rrc.rrc_rg_DCOut_fifo[UE_Id]; msgToBuild->nasRgPrimitive.dc_sap_prim.type = ENB_MEASUREMENT_IND; msgToBuild->nasRgPrimitive.dc_sap_prim.length = msgToBuild->prim_length; // comment or uncomment next lines according to test #ifdef RRC_ENABLE_REAL_ENB_MESURES num_connected_UEs = protocol_bs->rrc.num_connected_UEs; #else num_connected_UEs =2; #endif msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.cell_id = protocol_bs->rrc.rg_cell_id; // next values are temp hard coded, to be replaced by real values msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.num_UEs = num_connected_UEs; for (ix=0; ix<num_connected_UEs; ix++){ msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].rlcBufferOccupancy = rrc_rg_ENbMeas_get_rlcBufferOccupancy(ix); msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].scheduledPRB = rrc_rg_ENbMeas_get_scheduledPRB(ix); msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].totalDataVolume = rrc_rg_ENbMeas_get_totalDataVolume(ix); } msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.totalNumPRBs = rrc_rg_ENbMeas_get_totalNumPRBs(); #ifdef DEBUG_RRC_STATE msg ("[RRC][DATA-OUT] ENB_MEASUREMENT_IND primitive ready to send to NAS, length %d.\n", msgToBuild->prim_length); #endif }
//------------------------------------------------------------------- void RRC_RG_MBMS_O_UE_NOTIFY_CNF(void){ //------------------------------------------------------------------- #ifdef MBMS_INTEGRATION_MODE struct nas_rg_if_element *msgToBuild; mem_block_t *p = get_free_mem_block(sizeof (struct nas_rg_if_element)); protocol_bs->rrc.NASMessageToXmit = p; // Temp - will later enqueue at bottom of list //Set pointer to newly allocated structure and fills it msgToBuild = (struct nas_rg_if_element *) p->data; msgToBuild->prim_length = NAS_TL_SIZE + sizeof(struct NASMBMSUENotifyCnf); msgToBuild->xmit_fifo = protocol_bs->rrc.rrc_rg_DCOut_fifo[p_rg_mbms->nas_ueID]; msgToBuild->nasRgPrimitive.dc_sap_prim.type = MBMS_UE_NOTIFY_CNF; msgToBuild->nasRgPrimitive.dc_sap_prim.length = msgToBuild->prim_length; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.mbms_ue_notify_cnf.localConnectionRef = protocol_bs->rrc.Mobile_List[p_rg_mbms->nas_ueID].local_connection_ref; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.mbms_ue_notify_cnf.mbmsStatus = ACCEPTED; //Temp - hard coded #ifdef DEBUG_RRC_STATE msg("[RRC-RG][MBMS] MBMS_UE_NOTIFY_CNF primitive sent to NAS, length %d.\n", msgToBuild->prim_length); #endif #endif #ifdef MBMS_TEST_MODE msg("[RRC-RG][MBMS] MBMS_UE_NOTIFY_CNF primitive sent to NAS.\n"); #endif }
//Other functions, not related with Esterel //------------------------------------------------------------------- void RRC_RG_O_NAS_DATA_IND (int UE_Id){ //------------------------------------------------------------------- struct nas_rg_if_element *msgToBuild; char *pdata; mem_block_t *p = get_free_mem_block (sizeof (struct nas_rg_if_element) + RRC_NAS_MAX_SIZE); protocol_bs->rrc.NASMessageToXmit = p; // Temp - will later enqueue at bottom of list //Set pointer to newly allocated structure and fills it msgToBuild = (struct nas_rg_if_element *) p->data; msgToBuild->prim_length = NAS_TL_SIZE + sizeof (struct NASDataInd); #ifdef DEBUG_RRC_STATE msg ("[RRC][DATA-OUT] DATA_TRANSFER_IND, length #1 %d.\n", msgToBuild->prim_length); #endif msgToBuild->xmit_fifo = protocol_bs->rrc.rrc_rg_DCOut_fifo[UE_Id]; msgToBuild->nasRgPrimitive.dc_sap_prim.type = DATA_TRANSFER_IND; msgToBuild->nasRgPrimitive.dc_sap_prim.length = msgToBuild->prim_length; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.data_transfer_ind.localConnectionRef = protocol_bs->rrc.Mobile_List[UE_Id].local_connection_ref; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.data_transfer_ind.priority = protocol_bs->rrc.current_SFN; msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.data_transfer_ind.nasDataLength = protocol_bs->rrc.Mobile_List[UE_Id].ul_nas_message_lgth; pdata = (char *) &(msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.data_transfer_ind.nasDataLength); pdata += 2; memcpy (pdata, protocol_bs->rrc.Mobile_List[UE_Id].ul_nas_message_ptr, protocol_bs->rrc.Mobile_List[UE_Id].ul_nas_message_lgth); #ifdef DEBUG_RRC_DETAILS rrc_print_buffer (pdata - 2, 20); //msg ("[RRC][DATA-OUT] DATA_TRANSFER_IND, length #1.0 %d.\n", msgToBuild->prim_length); #endif msgToBuild->prim_length += (int) protocol_bs->rrc.Mobile_List[UE_Id].ul_nas_message_lgth; #ifdef DEBUG_RRC_DETAILS //msg ("[RRC][DATA-OUT] DATA_TRANSFER_IND, length #1.1 %d.\n", protocol_bs->rrc.Mobile_List[UE_Id].ul_nas_message_lgth); msg ("[RRC][DATA-OUT] DATA_TRANSFER_IND, length #2 %d.\n", msgToBuild->prim_length); #endif #ifdef DEBUG_RRC_STATE msg ("[RRC][DATA-OUT] DATA_TRANSFER_IND primitive ready to send to NAS, length %d.\n", msgToBuild->prim_length); #endif }
//----------------------------------------------------------------------------- void rrc_ue_msg_ueCapInfo(int *Message_Id){ //----------------------------------------------------------------------------- int status = P_SUCCESS; UL_DCCH_Message * ul_dcch_msg; mem_block_t *p; // prepare encoding *Message_Id = ++ protocol_ms->rrc.ue_msg_infos.msg_Id; protocol_ms->rrc.ue_msg_infos.msg_length = MSG_HEAD_LGTH + sizeof(UECapabilityInformation); p = get_free_mem_block(protocol_ms->rrc.ue_msg_infos.msg_length); ul_dcch_msg = (struct UL_DCCH_Message *)p->data; //Reference to the memory block protocol_ms->rrc.ue_msg_infos.mem_block_ptr = p; protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_dcch_msg; // Encode ul_dcch_msg->integrityCheckInfo = 123; ul_dcch_msg->message.type = UL_DCCH_ueCapabilityInformation; status = rrc_PEREnc_UECapabilityInformation ((UECapabilityInformation*) &(ul_dcch_msg->message.content)); #ifdef DEBUG_RRC_STATE msg("\n[RRC_MSG] UE Capability Information - status : %d - length : %d\n", status, protocol_ms->rrc.ue_msg_infos.msg_length); msg("[RRC_MSG] Kernel Release = %d, ", EURECOM_KERNEL_RELEASE_INDICATOR_DEFAULT); msg("Access Stratum Release = "); switch(ACCESS_STRATUM_RELEASE_INDICATOR_DEFAULT){ case ACCESS_STRATUM_RELEASE_INDICATOR_REL_4: msg("REL-4\n"); break; case ACCESS_STRATUM_RELEASE_INDICATOR_REL_5: msg("REL-5\n"); break; case ACCESS_STRATUM_RELEASE_INDICATOR_REL_6: msg("REL-6\n"); break; default: msg("Unrecognized!\n"); } rrc_print_buffer((char*)protocol_ms->rrc.ue_msg_infos.msg_ptr,protocol_ms->rrc.ue_msg_infos.msg_length); #endif }
/* RRC Connection Request */ void rrc_ue_msg_connreq(int *Message_Id){ //----------------------------------------------------------------------------- int status = P_SUCCESS; UL_CCCH_Message * ul_ccch_msg; mem_block_t *p; if (!protocol_ms->rrc.establishment_cause) protocol_ms->rrc.establishment_cause = registration; else protocol_ms->rrc.establishment_cause = callRe_establishment; protocol_ms->rrc.prot_error_indicator = noError; // prepare encoding *Message_Id = ++ protocol_ms->rrc.ue_msg_infos.msg_Id; protocol_ms->rrc.ue_msg_infos.msg_length = MSG_HEAD_LGTH + sizeof(RRCConnectionRequest); // Temp - Test/Messages // ul_ccch_msg = malloc (protocol_ms->rrc.ue_msg_infos.msg_length); // memset (ul_ccch_msg, 0, protocol_ms->rrc.ue_msg_infos.msg_length); // // // protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_ccch_msg; p = get_free_mem_block(protocol_ms->rrc.ue_msg_infos.msg_length); ul_ccch_msg = (struct UL_CCCH_Message *)p->data; // protocol_ms->rrc.ue_msg_infos.mem_block_ptr = p; protocol_ms->rrc.ue_msg_infos.msg_ptr = ul_ccch_msg; // Encode ul_ccch_msg->integrityCheckInfo = 0; // No check with RRC Connection Request ul_ccch_msg->message.type = UL_CCCH_rrcConnectionRequest; status = rrc_PEREnc_RRCConnectionRequest((RRCConnectionRequest*) &(ul_ccch_msg->message.content)); #ifdef DEBUG_RRC_STATE msg("\n[RRC_MSG] Connection Request - status : %d\n", status); msg("\n[RRC_MSG] Connection Request - length : %d\n", protocol_ms->rrc.ue_msg_infos.msg_length); rrc_print_buffer((char*)protocol_ms->rrc.ue_msg_infos.msg_ptr,protocol_ms->rrc.ue_msg_infos.msg_length); #endif }