/******************************************************************************* 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_2_rrm_msg.c \brief data formating for sending message over socket between RRC and RRM \author BURLOT Pascal \date 16/07/08 \par Historique: P.BURLOT 2009-01-20 bug fix (memeory leak) Macro changed : RRM_CALLOC() by RRM_CALLOC2() in msg_rrc_sensing_meas_ind() ******************************************************************************* */ #ifdef RRC_EMUL #include #include #include #include #include "L3_rrc_defs.h" #include "rrm_sock.h" #include "L3_rrc_interface.h" #include "rrc_rrm_msg.h" #include "rrm_util.h" #else #include "defs.h" #endif #ifdef TRACE //! Macro creant la chaine a partir du nom de la variable #define STRINGIZER(x) #x //! Tableau pour le mode trace faisant la translation entre le numero et le nom du message const char *Str_msg_rrc_rrm[NB_MSG_RRC_RRM] = { STRINGIZER(RRM_RB_ESTABLISH_REQ ), STRINGIZER(RRC_RB_ESTABLISH_RESP ), STRINGIZER(RRC_RB_ESTABLISH_CFM ), STRINGIZER(RRM_RB_MODIFY_REQ ), STRINGIZER(RRC_RB_MODIFY_RESP ), STRINGIZER(RRC_RB_MODIFY_CFM ), STRINGIZER(RRM_RB_RELEASE_REQ ), STRINGIZER(RRC_RB_RELEASE_RESP ), STRINGIZER(RRC_MR_ATTACH_IND ), STRINGIZER(RRM_SENSING_MEAS_REQ ), STRINGIZER(RRC_SENSING_MEAS_RESP ), STRINGIZER(RRC_CX_ESTABLISH_IND ), STRINGIZER(RRC_PHY_SYNCH_TO_MR_IND ), STRINGIZER(RRC_PHY_SYNCH_TO_CH_IND ), STRINGIZER(RRCI_CX_ESTABLISH_RESP ), STRINGIZER(RRC_SENSING_MEAS_IND ), STRINGIZER(RRM_SENSING_MEAS_RESP ), STRINGIZER(RRC_RB_MEAS_IND ), STRINGIZER(RRM_RB_MEAS_RESP ), STRINGIZER(RRM_INIT_CH_REQ ), STRINGIZER(RRCI_INIT_MR_REQ ) } ; #endif /*! ******************************************************************************* \brief This function initialize the message header \return any return value */ static void init_rrc_msg_head( msg_head_t *msg_head , //!< message header to initialize Instance_t inst , //!< Instance ID MSG_RRC_RRM_T msg_type , //!< type of message to initialize unsigned int size , //!< size of message Transaction_t Trans_id //!< transaction id associated to this message ) { if ( msg_head != NULL ) { msg_head->start = START_MSG ; msg_head->msg_type = 0xFF & msg_type ; msg_head->inst = inst ; msg_head->Trans_id = Trans_id ; msg_head->size = size; } } /*! ******************************************************************************* \brief La fonction formate en un message generique de reponse pour les fonctions : - rrc_rb_establish_resp(),rrc_rb_modify_resp(),rrc_rb_modify_resp(), - rrc_rb_release_resp() et rrc_sensing_meas_resp() . \return message formate */ msg_t mesg; msg_t *msg_rrc_generic_resp( Instance_t inst , //!< Instance ID MSG_RRC_RRM_T msg_type , //!< type of message Transaction_t Trans_id //!< Transaction ID ) { init_rrc_msg_head(&(mesg.head),inst, msg_type, 0 , Trans_id); mesg.data = NULL ; return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_rb_establish_resp(). \return message formate */ msg_t *msg_rrc_rb_establish_resp( Instance_t inst , //!< Instance ID Transaction_t Trans_id //!< Transaction ID ) { return msg_rrc_generic_resp( inst, RRC_RB_ESTABLISH_RESP, Trans_id) ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_rb_establish_cfm(). \return message formate */ rrc_rb_establish_cfm_t P_rb_est_cfm ;//= RRM_CALLOC(rrc_rb_establish_cfm_t , 1 ) ; msg_t *msg_rrc_rb_establish_cfm( Instance_t inst , //!< Instance ID RB_ID Rb_id , //!< Radio Bearer ID used by RRC RB_TYPE RB_type , //!< Radio Bearer Type Transaction_t Trans_id //!< Transaction ID ) { // msg_t mesg; init_rrc_msg_head(&(mesg.head),inst,RRC_RB_ESTABLISH_CFM, sizeof( rrc_rb_establish_cfm_t ) ,Trans_id); P_rb_est_cfm.Rb_id = Rb_id ; P_rb_est_cfm.RB_type = RB_type ; mesg.data = (char *) &P_rb_est_cfm ; return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_rb_modify_resp(). \return message formate */ msg_t *msg_rrc_rb_modify_resp( Instance_t inst , //!< Instance ID Transaction_t Trans_id //!< Transaction ID ) { return msg_rrc_generic_resp( inst,RRC_RB_MODIFY_RESP, Trans_id) ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_rb_modify_cfm(). \return message formate */ rrc_rb_modify_cfm_t P_rb_md_cfm; msg_t *msg_rrc_rb_modify_cfm( Instance_t inst , //!< Instance ID RB_ID Rb_id , //!< Radio Bearer ID used by RRC Transaction_t Trans_id //!< Transaction ID ) { // msg_t mesg; init_rrc_msg_head(&(mesg.head),inst,RRC_RB_MODIFY_CFM, sizeof( rrc_rb_modify_cfm_t ) ,Trans_id); P_rb_md_cfm.Rb_id = Rb_id ; mesg.data = (char *) &P_rb_md_cfm ; return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_rb_release_resp(). \return message formate */ msg_t *msg_rrc_rb_release_resp( Instance_t inst , //!< Instance ID Transaction_t Trans_id //!< Transaction ID ) { return msg_rrc_generic_resp( inst,RRC_RB_RELEASE_RESP, Trans_id) ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_MR_attach_ind(). \return message formate */ rrc_MR_attach_ind_t P_att_ind; msg_t * msg_rrc_MR_attach_ind( Instance_t inst , //!< Instance ID L2_ID L2_id ) { // msg_t mesg; init_rrc_msg_head(&(mesg.head),inst,RRC_MR_ATTACH_IND, sizeof( rrc_MR_attach_ind_t ) ,0); memcpy( P_att_ind.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; mesg.data = (char *) &P_att_ind ; return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_sensing_meas_resp(). \return message formate */ msg_t *msg_rrc_sensing_meas_resp( Instance_t inst , //!< Instance ID Transaction_t Trans_id //!< Transaction ID ) { return msg_rrc_generic_resp( inst,RRC_SENSING_MEAS_RESP, Trans_id) ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_cx_establish_ind(). \return message formate */ rrc_cx_establish_ind_t P_cx_est_ind; msg_t * msg_rrc_cx_establish_ind( Instance_t inst , //!< Instance ID L2_ID L2_id , //!< Layer 2 (MAC) ID Transaction_t Trans_id , //!< Transaction ID unsigned char *L3_info , //!< Optional L3 Information L3_INFO_T L3_info_t , //!< Type of L3 Information RB_ID DTCH_B_id , //!< RBID of broadcast IP service (MR only) RB_ID DTCH_id //!< RBID of default IP service (MR only) ) { //msg_t mesg; init_rrc_msg_head(&(mesg.head),inst,RRC_CX_ESTABLISH_IND, sizeof( rrc_cx_establish_ind_t ) ,Trans_id); memcpy( P_cx_est_ind.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; P_cx_est_ind.DTCH_B_id = DTCH_B_id ; P_cx_est_ind.DTCH_id = DTCH_id ; P_cx_est_ind.L3_info_t = L3_info_t ; if ( L3_info_t == IPv4_ADDR ) { memcpy( P_cx_est_ind.L3_info, L3_info, 4 ); } else if ( L3_info_t == IPv6_ADDR ) { memcpy( P_cx_est_ind.L3_info, L3_info, 16 ); } mesg.data = (char *) &P_cx_est_ind ; return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_phy_synch_to_MR_ind(). \return message formate */ rrc_phy_synch_to_MR_ind_t P_snc_mr; msg_t * msg_rrc_phy_synch_to_MR_ind( Instance_t inst , //!< Instance ID L2_ID L2_id ) { //msg_t smsg; init_rrc_msg_head(&(mesg.head),inst,RRC_PHY_SYNCH_TO_MR_IND, sizeof( rrc_phy_synch_to_MR_ind_t ) ,0); memcpy(&P_snc_mr.L2_id,(L2_ID*)&L2_id,sizeof(L2_ID)); mesg.data = (char *)&P_snc_mr ; msg("[msg_rrc_phy_synch_to_MR_ind] from Inst :%d\n",mesg.head.inst); return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_phy_synch_to_CH_ind(). \return message formate */ rrc_phy_synch_to_CH_ind_t P_snc_ch; msg_t * msg_rrc_phy_synch_to_CH_ind( Instance_t inst , //!< Instance ID unsigned int Ch_index , //!< Clusterhead index L2_ID L2_id ) { // msg_t smsg; init_rrc_msg_head(&(mesg.head),inst, RRC_PHY_SYNCH_TO_CH_IND, sizeof( rrc_phy_synch_to_CH_ind_t ) ,0); P_snc_ch.Ch_index = Ch_index ; memcpy(&P_snc_ch.L2_id,(L2_ID*)&L2_id,sizeof(L2_ID)); mesg.data = (char *) &P_snc_ch; msg("[msg_rrc_phy_synch_to_CH_ind] from Inst :%d\n",mesg.head.inst); return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_sensing_meas_ind(). \return message formate */ rrc_sensing_meas_ind_t P_sens_ind; msg_t * msg_rrc_sensing_meas_ind( Instance_t inst , //!< Instance ID L2_ID L2_id , //!< Layer 2 ID (MAC) of sensing node unsigned int NB_meas , //!< Layer 2 ID (MAC) of sensing node SENSING_MEAS_T *Sensing_meas , //!< Sensing Information Transaction_t Trans_id //!< Transaction ID ) { // msg_t mesg; unsigned int size = sizeof( rrc_sensing_meas_ind_t ) + (NB_meas-1) * sizeof(SENSING_MEAS_T) ; // Note : (NB_meas-1) car la première est incorporé dans rrc_sensing_meas_ind_t init_rrc_msg_head(&(mesg.head),inst, RRC_SENSING_MEAS_IND, size ,Trans_id); memcpy( P_sens_ind.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; if ( NB_meas > 0 ) { memcpy( P_sens_ind.Sensing_meas , Sensing_meas, NB_meas * sizeof(SENSING_MEAS_T) ) ; } P_sens_ind.NB_meas = NB_meas ; mesg.data = (char *) &P_sens_ind ; return &mesg ; } /*! ******************************************************************************* \brief La fonction formate en un message les parametres de la fonction rrc_rb_meas_ind(). \return message formate */ rrc_rb_meas_ind_t P_rb_meas; msg_t * msg_rrc_rb_meas_ind( Instance_t inst , //!< Instance ID RB_ID Rb_id , //!< Radio Bearer ID L2_ID L2_id , //!< Layer 2 (MAC) IDs for link MEAS_MODE Meas_mode , //!< Measurement mode (periodic or event-driven) MAC_RLC_MEAS_T *Mac_rlc_meas , //!< MAC/RLC measurements Transaction_t Trans_id //!< Transaction ID ) { //msg_t mesg; init_rrc_msg_head(&(mesg.head),inst, RRC_RB_MEAS_IND, sizeof( rrc_rb_meas_ind_t ) ,Trans_id); memcpy( P_rb_meas.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; memcpy( &(P_rb_meas.Mac_rlc_meas), Mac_rlc_meas, sizeof(L2_ID) ) ; P_rb_meas.Rb_id = Rb_id ; P_rb_meas.Meas_mode = Meas_mode ; mesg.data = (char *) &P_rb_meas; return &mesg ; } /*****************************************************************************/ rrc_init_scan_req_t P_init_scan; msg_t * msg_rrc_init_scan_req( Instance_t inst , //!< Instance ID L2_ID L2_id , //!< Layer 2 (MAC) IDs for link unsigned int Interv ) { //msg_t mesg; msg("RRCI: inst %d sendind rrc_init_scan_req from FC %d %d\n",inst,L2_id.L2_id[0],L2_id.L2_id[7]); init_rrc_msg_head(&(mesg.head),inst, RRC_INIT_SCAN_REQ, sizeof( rrc_init_scan_req_t ) ,0); memcpy( &P_init_scan.L2_id.L2_id[0], &L2_id.L2_id[0], sizeof(L2_ID) ) ; P_init_scan.interv=Interv; return &mesg ; } /*****************************************************************************/ rrc_update_sens_t P_update_sens; msg_t * msg_rrc_update_sens( Instance_t inst , //!< Instance ID Sens_ch_t *Sens, L2_ID L2_id, unsigned char NB_info ) { //msg_t mesg; init_rrc_msg_head(&(mesg.head),inst, RRC_UPDATE_SENS, sizeof( rrc_update_sens_t ) ,0); memcpy( &P_update_sens.L2_id.L2_id[0], &L2_id.L2_id[0], sizeof(L2_ID) ) ; memcpy( &P_update_sens.Sens_meas[0], (rrc_update_sens_t *)Sens, NB_info*sizeof(Sens_ch_t) ) ; P_update_sens.NB_info=NB_info; return &mesg ; } /*****************************************************************************/ rrc_end_scan_req_t P_end_scan; msg_t * msg_rrc_end_scan_req( Instance_t inst , //!< Instance ID unsigned char CH_index ) { //msg_t mesg; msg("RRC: send END_SCAN_REQ, INST %d\n",inst); init_rrc_msg_head(&(mesg.head),inst, RRC_END_SCAN_REQ, sizeof( rrc_end_scan_req_t ) ,0); P_update_sens.L2_id.L2_id[0]=CH_index; return &mesg ; }