/******************************************************************************* OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenAirInterface is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenAirInterface.The full GNU General Public License is included in this distribution in the file called "COPYING". If not, see . Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ /*! \file rrc_config.c * \brief rrc cinfiguration * \author Raymond Knopp and Navid Nikaein * \date 2011 * \version 1.0 * \company Eurecom * \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr */ #include "defs.h" #include "extern.h" #ifdef PHY_EMUL #include "SIMULATION/simulation_defs.h" extern EMULATION_VARS *Emul_vars; #endif extern CH_MAC_INST *CH_mac_inst; extern UE_MAC_INST *UE_mac_inst; #ifdef BIGPHYSAREA extern void *bigphys_malloc(int); #endif void rrc_init_ch_req(unsigned char Mod_id, rrm_init_ch_req_t *smsg) { uint16_t Index; MAC_CONFIG_REQ Mac_config_req; // MAC_MEAS_REQ Mac_meas_req; msg("-----------------------------------------------------------------------------------------------------------------\n"); printk("[RRC_CONFIG]OPENAIR RRC INIT CH %d...\n",Mod_id); Mac_config_req.Lchan_type = smsg->Lchan_desc_srb0.Lchan_t; memcpy(&Mac_config_req.Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&Mac_config_req.Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx Mac_config_req.UE_CH_index=0; Mac_config_req.Lchan_id.Index=(0 << RAB_SHIFT2) + BCCH; msg("Calling Lchan_config\n"); Index=Mac_rlc_xface->mac_config_req(Mod_id,ADD_LC,&Mac_config_req); msg("[OPENAIR][RRC][RRC_ON] NODE %d, Config BCCH %d done\n",CH_rrc_inst[Mod_id].Node_id,Index); CH_rrc_inst[Mod_id].Srb0.Srb_id = Index; memcpy(&CH_rrc_inst[Mod_id].Srb0.Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&CH_rrc_inst[Mod_id].Srb0.Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx rrc_config_buffer(&CH_rrc_inst[Mod_id].Srb0,BCCH,0); ((CH_BCCH_HEADER*)(&CH_rrc_inst[Mod_id].Srb0.Tx_buffer.Header[0]))->Rv_tb_idx=0; msg("[OPENAIR][RRC][RRC_ON] NODE %d, Config BCCH for TB_size %d\n",NODE_ID[Mod_id], CH_rrc_inst[Mod_id].Srb0.Lchan_desc[1].transport_block_size); CH_rrc_inst[Mod_id].Srb0.Tx_buffer.generate_fun=ch_rrc_generate_bcch; CH_rrc_inst[Mod_id].Srb0.Active=1; Mac_config_req.Lchan_type = smsg->Lchan_desc_srb1.Lchan_t; memcpy(&Mac_config_req.Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&Mac_config_req.Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx Mac_config_req.UE_CH_index=0; Mac_config_req.Lchan_id.Index=(0 << RAB_SHIFT2) + CCCH; // printk("Calling Lchan_config\n"); Index=Mac_rlc_xface->mac_config_req(Mod_id,ADD_LC,&Mac_config_req); msg("[OPENAIR][RRC][RRC_ON] NODE %d, Config BCCH %d done\n",CH_rrc_inst[Mod_id].Node_id,Index); CH_rrc_inst[Mod_id].Srb1.Srb_id = Index; memcpy(&CH_rrc_inst[Mod_id].Srb1.Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&CH_rrc_inst[Mod_id].Srb1.Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx rrc_config_buffer(&CH_rrc_inst[Mod_id].Srb1,CCCH,1); ((CH_CCCH_HEADER*)(&CH_rrc_inst[Mod_id].Srb1.Tx_buffer.Header[0]))->Rv_tb_idx=0; printk("[OPENAIR][RRC][RRC_ON] NODE %d, Config CCCH %d done, TB_size=%d,%d\n",NODE_ID[Mod_id],Index, CH_rrc_inst[Mod_id].Srb1.Tx_buffer.Tb_size,CH_rrc_inst[Mod_id].Srb1.Rx_buffer.Tb_size); CH_rrc_inst[Mod_id].Srb1.Tx_buffer.generate_fun=ch_rrc_generate_ccch; CH_rrc_inst[Mod_id].Srb1.Active=1; //CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0]=i; // CH_rrc_inst[Mod_id].Info.UE_list[0]=0; } void rrc_init_mr_req(unsigned char Mod_id, rrci_init_mr_req_t *smsg) { uint16_t Index; MAC_CONFIG_REQ Mac_config_req; // MAC_MEAS_REQ Mac_meas_req; msg("-----------------------------------------------------------------------------------------------------------------\n"); msg("[RRC_CONFIG]: Node %d: INIT MR REQUEST for CH %d\n",NODE_ID[Mod_id],smsg->CH_index); Mac_config_req.Lchan_type = smsg->Lchan_desc_srb0.Lchan_t; memcpy(&Mac_config_req.Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&Mac_config_req.Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx Mac_config_req.UE_CH_index=smsg->CH_index; Mac_config_req.Lchan_id.Index=(smsg->CH_index << RAB_SHIFT2) + BCCH; Index=Mac_rlc_xface->mac_config_req(Mod_id,ADD_LC,&Mac_config_req); msg("[OPENAIR][RRC][RRC_CONFIG] NODE %d, Config BCCH %d done\n",UE_rrc_inst[Mod_id-NB_CH_INST].Node_id,Index); UE_rrc_inst[Mod_id].Srb0[smsg->CH_index].Srb_id = Index; memcpy(& UE_rrc_inst[Mod_id-NB_CH_INST].Srb0[smsg->CH_index].Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(& UE_rrc_inst[Mod_id-NB_CH_INST].Srb0[smsg->CH_index].Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb0,LCHAN_DESC_SIZE); //0 rx, 1 tx rrc_config_buffer(&UE_rrc_inst[Mod_id-NB_CH_INST].Srb0[smsg->CH_index],BCCH,0); ((CH_BCCH_HEADER*)(&UE_rrc_inst[Mod_id-NB_CH_INST].Srb0[smsg->CH_index].Rx_buffer.Header[0]))->Rv_tb_idx=0; UE_rrc_inst[Mod_id-NB_CH_INST].Srb0[smsg->CH_index].Active=1; /* Mac_meas_req.Lchan_id.Index = Index; Mac_meas_req.UE_CH_index = i; Mac_meas_req.Meas_trigger = BCCH_MEAS_TRIGGER; Mac_meas_req.Mac_avg = BCCH_MEAS_AVG; Mac_meas_req.Rep_amount = 0; Mac_meas_req.Rep_interval = 1000; UE_rrc_inst[Mod_id].Srb0[i].Meas_entry=Mac_rlc_xface->mac_meas_req(Mod_id+NB_CH_INST,&Mac_meas_req); UE_rrc_inst[Mod_id].Srb0[i].Meas_entry->Status=RADIO_CONFIG_OK; UE_rrc_inst[Mod_id].Srb0[i].Meas_entry->Last_report_frame=Rrc_xface->Frame_index; UE_rrc_inst[Mod_id].Srb0[i].Meas_entry->Next_check_frame=Rrc_xface->Frame_index+1000; */ //printk("[OPENAIR][RRC][RRC_ON] NODE %d, Config CCCH %d done\n",NODE_ID[Mod_id],Index); // printk("check meas, LC_Index %d, Next %d, Last %d, Int %d \n",UE_rrc_inst[Mod_id].Srb0[i].Meas_entry->Mac_meas_req.Lchan_id.Index,UE_rrc_inst[Mod_id].Srb0[i].Meas_entry->Next_check_frame,UE_rrc_inst[Mod_id].Srb0[i].Meas_entry->Last_report_frame,UE_rrc_inst[Mod_id].Srb0[i].Meas_entry->Mac_meas_req.Rep_interval); Mac_config_req.Lchan_type = smsg->Lchan_desc_srb1.Lchan_t; memcpy(&Mac_config_req.Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&Mac_config_req.Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx Mac_config_req.UE_CH_index=smsg->CH_index; Mac_config_req.Lchan_id.Index=(smsg->CH_index << RAB_SHIFT2) + CCCH; Index=Mac_rlc_xface->mac_config_req(Mod_id,ADD_LC,&Mac_config_req); msg("[OPENAIR][RRC][RRC_CONFIG] NODE %d, Config CCCH %d done\n",NODE_ID[Mod_id],Index); UE_rrc_inst[Mod_id-NB_CH_INST].Srb1[smsg->CH_index].Srb_id = Index; memcpy(&UE_rrc_inst[Mod_id-NB_CH_INST].Srb1[smsg->CH_index].Lchan_desc[0],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&UE_rrc_inst[Mod_id-NB_CH_INST].Srb1[smsg->CH_index].Lchan_desc[1],(LCHAN_DESC*)&smsg->Lchan_desc_srb1,LCHAN_DESC_SIZE); //0 rx, 1 tx rrc_config_buffer(&UE_rrc_inst[Mod_id-NB_CH_INST].Srb1[smsg->CH_index],CCCH,1); ((CH_CCCH_HEADER*)(&UE_rrc_inst[Mod_id-NB_CH_INST].Srb1[smsg->CH_index].Rx_buffer.Header[0]))->Rv_tb_idx=0; UE_rrc_inst[Mod_id-NB_CH_INST].Srb1[smsg->CH_index].Active=1; /* Mac_meas_req.Lchan_id.Index = Index; // Mac_meas_req.UE_CH_index = i; Mac_meas_req.Meas_trigger = CCCH_MEAS_TRIGGER; Mac_meas_req.Mac_avg = CCCH_MEAS_AVG; Mac_meas_req.Rep_amount = 0; Mac_meas_req.Rep_interval = 1000; UE_rrc_inst[Mod_id].Srb1[i].Meas_entry=Mac_rlc_xface->mac_meas_req(Mod_id+NB_CH_INST,&Mac_meas_req); UE_rrc_inst[Mod_id].Srb1[i].Meas_entry->Status=RADIO_CONFIG_OK; UE_rrc_inst[Mod_id].Srb1[i].Meas_entry->Last_report_frame=Rrc_xface->Frame_index; UE_rrc_inst[Mod_id].Srb1[i].Meas_entry->Next_check_frame=Rrc_xface->Frame_index+1000; //printk("[OPENAIR][RRC][RRC_ON] NODE %d, Config CCCH %d done\n",NODE_ID[Mod_id],Index); */ } void rrc_config_req(Instance_t Mod_id, void *smsg, unsigned char Action,Transaction_t Trans_id) { MAC_CONFIG_REQ Mac_config_req; MAC_MEAS_REQ Mac_meas_req; unsigned short Idx,UE_index,In_idx; switch(Action) { case RRM_RB_ESTABLISH_REQ: { rrm_rb_establish_req_t *p = (rrm_rb_establish_req_t *) smsg ; msg("[RRC]CH %d: config req for CH L2_id %d to MR L2_id %d\n",NODE_ID[Mod_id],p->L2_id[0].L2_id[0],p->L2_id[1].L2_id[0]); UE_index=rrc_find_ue_index(Mod_id, p->L2_id[1]); if(UE_index > NB_CNX_CH) { msg("[FATAL ERROR] NO MORE UE_INDEX!!!!!\n"); return; } if(p->Lchan_desc.Lchan_t==DCCH) { Mac_config_req.Lchan_type = p->Lchan_desc.Lchan_t; Mac_config_req.UE_CH_index = UE_index; memcpy(&Mac_config_req.Lchan_desc[0],(LCHAN_DESC*)&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&Mac_config_req.Lchan_desc[1],(LCHAN_DESC*)&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx Mac_config_req.Lchan_id.Index=( UE_index << RAB_SHIFT2) + DCCH; Idx = Mac_rlc_xface->mac_config_req(Mod_id,ADD_LC,&Mac_config_req); CH_rrc_inst[Mod_id].Srb2[UE_index].Active = 1; CH_rrc_inst[Mod_id].Srb2[UE_index].Next_check_frame = Rrc_xface->Frame_index + 250; CH_rrc_inst[Mod_id].Srb2[UE_index].Status = NEED_RADIO_CONFIG;//RADIO CFG CH_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Srb_id = Idx; memcpy(&CH_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Lchan_desc[0],(LCHAN_DESC*)&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&CH_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Lchan_desc[1],(LCHAN_DESC*)&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx // CH_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Lchan_desc[0] = &DCCH_LCHAN_DESC; // CH_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Lchan_desc[1] = &DCCH_LCHAN_DESC; //CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Rb_info.Lchan_desc[0] = &msg->Lchan_desc; // CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Rb_info.Lchan_desc[1] = &msg-; //Configure a correponding measurement process // msg("[RRC]Inst %d: Programing RADIO CONFIG of DCCH LCHAN %d\n",Mod_id,Idx); //CH_rrc_inst[Mod_id].Nb_rb[UE_index]++; //msg("[OPENAIR][RRC] CALLING RLC CONFIG RADIO BEARER %d\n",Idx); Mac_rlc_xface->rrc_rlc_config_req(Mod_id,CONFIG_ACTION_ADD,Idx,SIGNALLING_RADIO_BEARER,Rlc_info_um); /* CH_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.CH_ip_addr_type=p->L3_info_t; if(p->L3_info_t == IPv4_ADDR){ memcpy(CH_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.CH_ip_addr,p->L3_info,4); } else memcpy(UE_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.CH_ip_addr,p->L3_info,16); */ // if(msg->Mac_rlc_meas_desc !=NULL){ CH_rrc_inst[Mod_id].Def_meas[UE_index]= &CH_mac_inst[Mod_id].Def_meas[UE_index]; CH_rrc_inst[Mod_id].Def_meas[UE_index]->Active = 1; CH_rrc_inst[Mod_id].Def_meas[UE_index]->Status = NEED_RADIO_CONFIG; CH_rrc_inst[Mod_id].Def_meas[UE_index]->Forg_fact=1; CH_rrc_inst[Mod_id].Def_meas[UE_index]->Rep_interval=50; CH_rrc_inst[Mod_id].Def_meas[UE_index]->Last_report_frame=Rrc_xface->Frame_index; CH_rrc_inst[Mod_id].Def_meas[UE_index]->Next_check_frame=Rrc_xface->Frame_index +200 ; // } } else { msg("RRC_config: Inst %d:, UE_index %d",Mod_id,UE_index); Mac_config_req.Lchan_type = p->Lchan_desc.Lchan_t; Mac_config_req.UE_CH_index = UE_index; memcpy(&Mac_config_req.Lchan_desc[0],&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&Mac_config_req.Lchan_desc[1],&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx In_idx=find_free_dtch_position(Mod_id,UE_index); Mac_config_req.Lchan_id.Index=(UE_index << RAB_SHIFT2) + DTCH + In_idx; Idx = Mac_rlc_xface->mac_config_req(Mod_id,ADD_LC,&Mac_config_req); CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Active = 1; CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Next_check_frame = Rrc_xface->Frame_index + 250; CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Status = NEED_RADIO_CONFIG;//RADIO CFG CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Rb_info.Rb_id = Idx; memcpy(&CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Rb_info.Lchan_desc[0],&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx memcpy(&CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Rb_info.Lchan_desc[1],&p->Lchan_desc,LCHAN_DESC_SIZE); //0 rx, 1 tx //Configure a correponding measurement process msg("[RRC]Inst %d: Programing RADIO CONFIG of DTCH LCHAN %d\n",Mod_id,Idx); //CH_rrc_inst[Mod_id].Nb_rb[UE_index]++; //msg("[OPENAIR][RRC] CALLING RLC CONFIG RADIO BEARER %d\n",Idx); // if(p->Mac_rlc_meas_desc !=NULL){ if(p->Lchan_desc.Lchan_t!=DTCH) { Mac_meas_req.Lchan_id.Index = Idx; Mac_meas_req.UE_CH_index = UE_index; Mac_meas_req.Meas_trigger = p->Mac_rlc_meas_desc.Meas_trigger; Mac_meas_req.Mac_avg = p->Mac_rlc_meas_desc.Mac_avg; Mac_meas_req.Rep_amount = p->Mac_rlc_meas_desc.Rep_amount; Mac_meas_req.Rep_interval = p->Mac_rlc_meas_desc.Rep_interval; CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Rb_info.Meas_entry=Mac_rlc_xface->mac_meas_req(Mod_id,&Mac_meas_req); CH_rrc_inst[Mod_id].Rab_meas[In_idx][UE_index].Status=NEED_RADIO_CONFIG; CH_rrc_inst[Mod_id].Rab_meas[In_idx][UE_index].Mac_meas_req.Lchan_id.Index=Idx; CH_rrc_inst[Mod_id].Rab_meas[In_idx][UE_index].Last_report_frame=Rrc_xface->Frame_index; CH_rrc_inst[Mod_id].Rab_meas[In_idx][UE_index].Next_check_frame=Rrc_xface->Frame_index+Mac_meas_req.Rep_interval; } if(p->Lchan_desc.Lchan_t==DTCH) { CH_rrc_inst[Mod_id].Rab[In_idx][UE_index].Status = RADIO_CONFIG_OK;//RADIO CFG Mac_rlc_xface->rrc_rlc_config_req(Mod_id,CONFIG_ACTION_ADD,Idx,RADIO_ACCESS_BEARER,Rlc_info_um); CH_rrc_inst[Mod_id].IP_addr_type = p->L3_info_t; if(CH_rrc_inst[Mod_id].IP_addr_type == IPv4_ADDR) { memcpy(CH_rrc_inst[Mod_id].IP_addr,p->L3_info,4); } else { memcpy(CH_rrc_inst[Mod_id].IP_addr,p->L3_info,16); } } else { Mac_rlc_xface->rrc_rlc_config_req(Mod_id,CONFIG_ACTION_ADD,Idx,RADIO_ACCESS_BEARER,Rlc_info_am_config); } } if(p->Lchan_desc.Lchan_t==DTCH) { send_msg(&S_rrc,msg_rrc_rb_establish_cfm(Mod_id,Idx,0,Trans_id)); } else { send_msg(&S_rrc,msg_rrc_rb_establish_cfm(Mod_id,Idx,1,Trans_id)); } } break; case RRM_RB_MODIFY_REQ: { //rrm_rb_modify_req_t *p = (rrm_rb_modify_req_t *) msg ; } case RRM_RB_RELEASE_REQ: { //rrm_rb_release_req_t *p = (rrm_rb_release_req_t *) msg ; } } }