Commit 365527d4 authored by Javier Morgade's avatar Javier Morgade

M3AP 3GPP TS 36.444 interface implemented:

        1.MME entity developed to handle M3 side (new dedicated task developed: TASK_MME_APP) (these procedures should be moved to OPENAIR-CN ... just implemented to easy the E-UTRAN MBMS stuff development)
        2.MCE side M3 interface procedures (new dedicated task developed: TASK_M3AP_MCE)
        3.MME side M3 interface procedures (new dedicated task developed: TASK_M2AP_MME) (these procedures should be moved to OPENAIR-CN ... just implemented to easy the E-UTRAN MBMS stuff development)
        4.ASN1 bindings for m3ap-14.0.0.asn1 implemented and tested
        5.MME config parameters

	ACKNOWLEDGEMENT:
 	1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS"
 	2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu)
Signed-off-by: default avatarJavier Morgade <javier.morgade@ieee.org>
parent ab04e0e4
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_eNB.h
* \brief m3ap tasks for eNB
* \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr>
* \date 2018
* \version 1.0
*/
#include <stdio.h>
#include <stdint.h>
/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M3AP_MCE_H_
#define M3AP_MCE_H_
#include "m3ap_MCE_defs.h"
int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mce_port_for_M3C);
void *m3ap_MCE_task(void *arg);
int is_m3ap_MCE_enabled(void);
#endif /* M3AP_H_ */
/**
* @}
*/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_defs.h
* \brief m3ap struct definitions for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "queue.h"
#include "tree.h"
#include "sctp_eNB_defs.h"
#include "m3ap_ids.h" //looks X2AP specific for HO
#include "m3ap_timers.h"
#ifndef M3AP_MCE_DEFS_H_
#define M3AP_MCE_DEFS_H_
#define M3AP_MCE_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
M3AP_MCE_STATE_DISCONNECTED = 0x0,
/* State waiting for m2 Setup response message if the target MCE accepts or
* M3 Setup failure if rejects the MCE.
*/
M3AP_MCE_STATE_WAITING = 0x1,
/* The MCE is successfully connected to another MCE. */
M3AP_MCE_STATE_CONNECTED = 0x2,
/* M3AP is ready, and the MCE is successfully connected to another MCE. */
M3AP_MCE_STATE_READY = 0x3,
M3AP_MCE_STATE_OVERLOAD = 0x4,
M3AP_MCE_STATE_RESETTING = 0x5,
/* Max number of states available */
M3AP_MCE_STATE_MAX,
} m3ap_MCE_state_t;
/* Served PLMN identity element */
/*struct plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
STAILQ_ENTRY(plmn_identity_s) next;
};*/
/* Served group id element */
/*struct served_group_id_s {
uint16_t mce_group_id;
STAILQ_ENTRY(served_group_id_s) next;
};*/
/* Served enn code for a particular MCE */
/*struct mce_code_s {
uint8_t mce_code;
STAILQ_ENTRY(mce_code_s) next;
};*/
struct m3ap_MCE_instance_s;
/* This structure describes association of a MCE to another MCE */
typedef struct m3ap_MCE_data_s {
/* MCE descriptors tree, ordered by sctp assoc id */
RB_ENTRY(m3ap_MCE_data_s) entry;
/* This is the optional name provided by the MME */
char *MCE_name;
/* target MCE ID */
uint32_t MCE_id;
/* Current MCE load information (if any). */
//m3ap_load_state_t overload_state;
/* Current MCE->MCE M3AP association state */
m3ap_MCE_state_t state;
/* Next usable stream for UE signalling */
int32_t nextstream;
/* Number of input/ouput streams */
uint16_t in_streams;
uint16_t out_streams;
/* Connexion id used between SCTP/M3AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Nid cells */
uint32_t Nid_cell[MAX_NUM_CCs];
int num_cc;
/* Only meaningfull in virtual mode */
struct m3ap_MCE_instance_s *m3ap_MCE_instance;
} m3ap_MCE_data_t;
typedef struct m3ap_MCE_instance_s {
/* used in simulation to store multiple MCE instances*/
STAILQ_ENTRY(m3ap_MCE_instance_s) m3ap_MCE_entries;
/* Number of target MCEs requested by MCE (tree size) */
uint32_t m3_target_mme_nb;
/* Number of target MCEs for which association is pending */
uint32_t m3_target_mme_pending_nb;
/* Number of target MCE successfully associated to MCE */
uint32_t m3_target_mme_associated_nb;
/* Tree of M3AP MCE associations ordered by association ID */
RB_HEAD(m3ap_mce_map, m3ap_MCE_data_s) m3ap_mce_head;
/* Tree of UE ordered by MCE_ue_m3ap_id's */
// RB_HEAD(m3ap_ue_map, m3ap_MCE_ue_context_s) m3ap_ue_head;
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
instance_t instance;
/* Displayable name of MCE */
char *MCE_name;
/* Unique MCE_id to identify the MCE within EPC.
* In our case the MCE is a macro MCE so the id will be 20 bits long.
* For Home MCE id, this field should be 28 bits long.
*/
uint32_t MCE_id;
/* The type of the cell */
cell_type_t cell_type;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* CC params */
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MCE_IP_ADDRESS];
uint8_t nb_m3;
net_ip_address_t mme_m3_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t mce_port_for_M3C;
int multi_sd;
m3ap_id_manager id_manager;
m3ap_timers_t timers;
} m3ap_MCE_instance_t;
typedef struct {
/* List of served MCEs
* Only used for virtual mode
*/
STAILQ_HEAD(m3ap_MCE_instances_head_s, m3ap_MCE_instance_s) m3ap_MCE_instances_head;
/* Nb of registered MCEs */
uint8_t nb_registered_MCEs;
/* Generate a unique connexion id used between M3AP and SCTP */
uint16_t global_cnx_id;
} m3ap_MCE_internal_data_t;
int m3ap_MCE_compare_assoc_id(struct m3ap_MCE_data_s *p1, struct m3ap_MCE_data_s *p2);
/* Generate the tree management functions */
struct m3ap_MCE_map;
struct m3ap_MCE_data_s;
RB_PROTOTYPE(m3ap_MCE_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id);
#endif /* M3AP_MCE_DEFS_H_ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_eNB_generate_messages.h
* \brief m2ap procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_ENB_GENERATE_MESSAGES_H_
#define M2AP_ENB_GENERATE_MESSAGES_H_
#include "m2ap_eNB_defs.h"
#include "m2ap_common.h"
int m2ap_eNB_generate_m2_setup_request(m2ap_eNB_instance_t *instance_p,
m2ap_eNB_data_t *m2ap_eNB_data_p);
int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p);
/*int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
uint32_t assoc_id,
M2AP_Cause_PR cause_type,
long cause_value,
long time_to_wait);*/
int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value);
//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id);
//
//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause);
#endif /* M2AP_ENB_GENERATE_MESSAGES_H_ */
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_eNB_handler.c
* \brief m3ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "m3ap_common.h"
#include "m3ap_MCE_defs.h"
#include "m3ap_handler.h"
#include "m3ap_decoder.h"
#include "m3ap_ids.h"
//#include "m3ap_MCE_management_procedures.h"
#include "m3ap_MCE_generate_messages.h"
//#include "m3ap_MME_interface_management.h"
#include "m3ap_MCE_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m3ap_MCE_message_decoded_callback m3ap_MCE_messages_callback[][3] = {
{ MCE_handle_MBMS_SESSION_START_REQUEST, 0, 0 }, /* MBMSSessionStart */
{ MCE_handle_MBMS_SESSION_STOP_REQUEST, 0, 0 }, /* MBMSSessionStop */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ 0, 0, 0 }, /* ??? */
{ MCE_handle_MBMS_SESSION_UPDATE_REQUEST, 0, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ 0, MCE_handle_M3_SETUP_RESPONSE, 0 } /* M3 Setup */
};
static char *m3ap_direction2String(int m3ap_dir) {
static char *m3ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m3ap_direction_String[m3ap_dir]);
}
int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M3AP_M3AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (m3ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M3AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_MCE_messages_callback) / (3 * sizeof(
m3ap_message_decoded_callback))
|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M3AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M3AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m3ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M3AP, "Calling handler with instance %d\n",instance);
ret = (*m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu);
return ret;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m2ap_handler.h
* \brief m2ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_HANDLERS_H_
#define M2AP_MCE_HANDLERS_H_
#include "m2ap_MCE_defs.h"
//void m3ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
//int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
//const uint8_t * const data, const uint32_t data_length);
int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
#endif /* M2AP_MCE_HANDLERS_H_ */
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_interface_management.h
* \brief m3ap interface management for MCE
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M3AP_MCE_INTERFACE_MANAGEMENT_H_
#define M3AP_MCE_INTERFACE_MANAGEMENT_H_
/*
* Session Start
*/
int MCE_handle_MBMS_SESSION_START_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp);
int MCE_send_MBMS_SESSION_START_FAILURE(instance_t instance, m3ap_session_start_failure_t * m3ap_session_start_failure);
/*
* Session Stop
*/
int MCE_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* Session Update
*/
int MCE_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m3ap_mbms_session_update_resp_t * m3ap_mbms_session_update_resp);
int MCE_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m3ap_mbms_session_update_failure_t * m3ap_mbms_session_update_failure);
int MCE_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp);
/*
* Reset
*/
int MCE_handle_RESET(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_send_RESET_ACKKNOWLEDGE(instance_t instance, M3AP_ResetAcknowledge_t *ResetAcknowledge);
int MCE_send_RESET(instance_t instance, M3AP_Reset_t *Reset);
int MCE_handle_RESET_ACKNOWLEDGE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* M3AP Setup
*/
int MCE_send_M3_SETUP_REQUEST( m3ap_MCE_instance_t *instance_p, m3ap_MCE_data_t *m3ap_MCE_data_p);
int MCE_handle_M3_SETUP_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
int MCE_handle_M3_SETUP_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
/*
* Error Indication
*/
int MCE_send_ERROR_INDICATION(instance_t instance, M3AP_M3AP_PDU_t *pdu_p);
int MCE_handle_ERROR_INDICATION(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M3AP_M3AP_PDU_t *pdu);
#endif /* M3AP_MCE_INTERFACE_MANAGEMENT_H_ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_management_procedures.c
* \brief m3ap tasks for MCE
* \author Javier Morgade <javier.morade@ieee.org>
* \date 2018
* \version 1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "intertask_interface.h"
#include "assertions.h"
#include "conversions.h"
#include "m3ap_common.h"
#include "m3ap_MCE_defs.h"
#include "m3ap_MCE.h"
#define M3AP_DEBUG_LIST
#ifdef M3AP_DEBUG_LIST
# define M3AP_MCE_LIST_OUT(x, args...) M3AP_DEBUG("[MCE]%*s"x"\n", 4*indent, "", ##args)
#else
# define M3AP_MCE_LIST_OUT(x, args...)
#endif
static int indent = 0;
m3ap_MCE_internal_data_t m3ap_MCE_internal_data;
RB_GENERATE(m3ap_mce_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id);
int m3ap_MCE_compare_assoc_id(
struct m3ap_MCE_data_s *p1, struct m3ap_MCE_data_s *p2)
{
if (p1->assoc_id == -1) {
if (p1->cnx_id < p2->cnx_id) {
return -1;
}
if (p1->cnx_id > p2->cnx_id) {
return 1;
}
} else {
if (p1->assoc_id < p2->assoc_id) {
return -1;
}
if (p1->assoc_id > p2->assoc_id) {
return 1;
}
}
/* Matching reference */
return 0;
}
uint16_t m3ap_MCE_fetch_add_global_cnx_id(void)
{
return ++m3ap_MCE_internal_data.global_cnx_id;
}
void m3ap_MCE_prepare_internal_data(void)
{
memset(&m3ap_MCE_internal_data, 0, sizeof(m3ap_MCE_internal_data));
STAILQ_INIT(&m3ap_MCE_internal_data.m3ap_MCE_instances_head);
}
void m3ap_MCE_insert_new_instance(m3ap_MCE_instance_t *new_instance_p)
{
DevAssert(new_instance_p != NULL);
STAILQ_INSERT_TAIL(&m3ap_MCE_internal_data.m3ap_MCE_instances_head,
new_instance_p, m3ap_MCE_entries);
}
void dump_tree_m3(m3ap_MCE_data_t *t)
{
if (t == NULL) return;
printf("-----------------------\n");
printf("MCE id %d %s\n", t->MCE_id, t->MCE_name);
printf("state %d\n", t->state);
printf("nextstream %d\n", t->nextstream);
printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams);
printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id);
dump_tree_m3(t->entry.rbe_left);
dump_tree_m3(t->entry.rbe_right);
}
void dump_trees_m3(void)
{
m3ap_MCE_instance_t *zz;
STAILQ_FOREACH(zz, &m3ap_MCE_internal_data.m3ap_MCE_instances_head,
m3ap_MCE_entries) {
printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
dump_tree_m3(zz->m3ap_mce_head.rbh_root);
printf("---------------------------------------------\n");
}
}
struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id)
{
struct m3ap_MCE_data_s temp;
struct m3ap_MCE_data_s *found;
printf("m3ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
dump_trees_m3();
memset(&temp, 0, sizeof(struct m3ap_MCE_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &m3ap_MCE_internal_data.m3ap_MCE_instances_head,
m3ap_MCE_entries) {
found = RB_FIND(m3ap_mce_map, &instance_p->m3ap_mce_head, &temp);
if (found != NULL) {
return found;
}
}
} else {
return RB_FIND(m3ap_mce_map, &instance_p->m3ap_mce_head, &temp);
}
return NULL;
}
m3ap_MCE_instance_t *m3ap_MCE_get_instance(instance_t instance)
{
m3ap_MCE_instance_t *temp = NULL;
STAILQ_FOREACH(temp, &m3ap_MCE_internal_data.m3ap_MCE_instances_head,
m3ap_MCE_entries) {
if (temp->instance == instance) {
/* Matching occurence */
return temp;
}
}
return NULL;
}
/// utility functions
void m3ap_dump_MCE (m3ap_MCE_data_t * MCE_ref);
void
m3ap_dump_MCE_list (void) {
m3ap_MCE_instance_t *inst = NULL;
struct m3ap_MCE_data_s *found = NULL;
struct m3ap_MCE_data_s temp;
memset(&temp, 0, sizeof(struct m3ap_MCE_data_s));
STAILQ_FOREACH (inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
found = RB_FIND(m3ap_mce_map, &inst->m3ap_mce_head, &temp);
m3ap_dump_MCE (found);
}
}
void m3ap_dump_MCE (m3ap_MCE_data_t * MCE_ref) {
if (MCE_ref == NULL) {
return;
}
M3AP_MCE_LIST_OUT ("");
M3AP_MCE_LIST_OUT ("MCE name: %s", MCE_ref->MCE_name == NULL ? "not present" : MCE_ref->MCE_name);
M3AP_MCE_LIST_OUT ("MCE STATE: %07x", MCE_ref->state);
M3AP_MCE_LIST_OUT ("MCE ID: %07x", MCE_ref->MCE_id);
indent++;
M3AP_MCE_LIST_OUT ("SCTP cnx id: %d", MCE_ref->cnx_id);
M3AP_MCE_LIST_OUT ("SCTP assoc id: %d", MCE_ref->assoc_id);
M3AP_MCE_LIST_OUT ("SCTP instreams: %d", MCE_ref->in_streams);
M3AP_MCE_LIST_OUT ("SCTP outstreams: %d", MCE_ref->out_streams);
indent--;
}
m3ap_MCE_data_t * m3ap_is_MCE_pci_in_list (const uint32_t pci)
{
m3ap_MCE_instance_t *inst;
struct m3ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
RB_FOREACH(elm, m3ap_mce_map, &inst->m3ap_mce_head) {
for (int i = 0; i<elm->num_cc; i++) {
if (elm->Nid_cell[i] == pci) {
return elm;
}
}
}
}
return NULL;
}
m3ap_MCE_data_t * m3ap_is_MCE_id_in_list (const uint32_t MCE_id)
{
m3ap_MCE_instance_t *inst;
struct m3ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
RB_FOREACH(elm, m3ap_mce_map, &inst->m3ap_mce_head) {
if (elm->MCE_id == MCE_id)
return elm;
}
}
return NULL;
}
m3ap_MCE_data_t * m3ap_is_MCE_assoc_id_in_list (const uint32_t sctp_assoc_id)
{
m3ap_MCE_instance_t *inst;
struct m3ap_MCE_data_s *found;
struct m3ap_MCE_data_s temp;
temp.assoc_id = sctp_assoc_id;
temp.cnx_id = -1;
STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) {
found = RB_FIND(m3ap_mce_map, &inst->m3ap_mce_head, &temp);
if (found != NULL){
if (found->assoc_id == sctp_assoc_id) {
return found;
}
}
}
return NULL;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MCE_management_procedures.h
* \brief m3ap tasks for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M3AP_MCE_MANAGEMENT_PROCEDURES_H_
#define M3AP_MCE_MANAGEMENT_PROCEDURES_H
void m3ap_MCE_prepare_internal_data(void);
void dump_trees_m3(void);
void m3ap_MCE_insert_new_instance(m3ap_MCE_instance_t *new_instance_p);
m3ap_MCE_instance_t *m3ap_MCE_get_instance(uint8_t mod_id);
uint16_t m3ap_MCE_fetch_add_global_cnx_id(void);
m3ap_MCE_data_t* m3ap_is_MCE_id_in_list(uint32_t MCE_id);
m3ap_MCE_data_t* m3ap_is_MCE_assoc_id_in_list(uint32_t sctp_assoc_id);
m3ap_MCE_data_t* m3ap_is_MCE_pci_in_list (const uint32_t pci);
struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id);
#endif /* M3AP_MCE_MANAGEMENT_PROCEDURES_H_ */
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MME.h
* \brief m3ap tasks for MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include <stdint.h>
/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M3AP_MME_H_
#define M3AP_MME_H_
#include "m3ap_MME_defs.h"
int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M3C);
void *m3ap_MME_task(void *arg);
int is_m3ap_MME_enabled(void);
#endif /* M3AP_MCE_H_ */
/**
* @}
*/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file m3ap_MME_defs.h
* \brief m2ap struct definitions for MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "queue.h"
#include "tree.h"
#include "sctp_eNB_defs.h"
#include "m3ap_ids.h" //looks X2AP specific for HO
#include "m3ap_timers.h"
#ifndef M3AP_MME_DEFS_H_
#define M3AP_MME_DEFS_H_
#define M3AP_MME_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
M3AP_MME_STATE_DISCONNECTED = 0x0,
/* State waiting for m2 Setup response message if the target MME accepts or
* M2 Setup failure if rejects the MME.
*/
M3AP_MME_STATE_WAITING = 0x1,
/* The MME is successfully connected to another MME. */
M3AP_MME_STATE_CONNECTED = 0x2,
/* M3AP is ready, and the MME is successfully connected to another MME. */
M3AP_MME_STATE_READY = 0x3,
M3AP_MME_STATE_OVERLOAD = 0x4,
M3AP_MME_STATE_RESETTING = 0x5,
/* Max number of states available */
M3AP_MME_STATE_MAX,
} m3ap_MME_state_t;
/* Served PLMN identity element */
/*struct plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
STAILQ_ENTRY(plmn_identity_s) next;
};*/
/* Served group id element */
/*struct served_group_id_s {
uint16_t mce_group_id;
STAILQ_ENTRY(served_group_id_s) next;
};*/
/* Served enn code for a particular MME */
/*struct mce_code_s {
uint8_t mce_code;
STAILQ_ENTRY(mce_code_s) next;
};*/
struct m3ap_MME_instance_s;
/* This structure describes association of a MME to another MME */
typedef struct m3ap_MME_data_s {
/* MME descriptors tree, ordered by sctp assoc id */
RB_ENTRY(m3ap_MME_data_s) entry;
/* This is the optional name provided by the MME */
char *MME_name;
/* target MME ID */
uint32_t MME_id;
/* Current MME load information (if any). */
//m3ap_load_state_t overload_state;
/* Current MME->MME M3AP association state */
m3ap_MME_state_t state;
/* Next usable stream for UE signalling */
int32_t nextstream;
/* Number of input/ouput streams */
uint16_t in_streams;
uint16_t out_streams;
/* Connexion id used between SCTP/M3AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Nid cells */
uint32_t Nid_cell[MAX_NUM_CCs];
int num_cc;
/* Only meaningfull in virtual mode */
struct m3ap_MME_instance_s *m3ap_MME_instance;
} m3ap_MME_data_t;
typedef struct m3ap_MME_instance_s {
/* used in simulation to store multiple MME instances*/
STAILQ_ENTRY(m3ap_MME_instance_s) m3ap_MME_entries;
/* Number of target MMEs requested by MME (tree size) */
uint32_t m2_target_mce_nb;
/* Number of target MMEs for which association is pending */
uint32_t m2_target_mce_pending_nb;
/* Number of target MME successfully associated to MME */
uint32_t m2_target_mce_associated_nb;
/* Tree of M3AP MME associations ordered by association ID */
RB_HEAD(m3ap_mme_map, m3ap_MME_data_s) m3ap_mme_head;
/* Tree of UE ordered by MME_ue_m3ap_id's */
// RB_HEAD(m3ap_ue_map, m3ap_MME_ue_context_s) m3ap_ue_head;
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
instance_t instance;
/* Displayable name of MME */
char *MME_name;
/* Unique MME_id to identify the MME within EPC.
* In our case the MME is a macro MME so the id will be 20 bits long.
* For Home MME id, this field should be 28 bits long.
*/
uint32_t MME_id;
/* The type of the cell */
cell_type_t cell_type;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* CC params */
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MME_IP_ADDRESS];
uint8_t nb_m3;
net_ip_address_t mme_m3_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t mme_port_for_M3C;
int multi_sd;
m3ap_id_manager id_manager;
m3ap_timers_t timers;
} m3ap_MME_instance_t;
typedef struct {
/* List of served MMEs
* Only used for virtual mode
*/
STAILQ_HEAD(m3ap_MME_instances_head_s, m3ap_MME_instance_s) m3ap_MME_instances_head;
/* Nb of registered MMEs */
uint8_t nb_registered_MMEs;
/* Generate a unique connexion id used between M3AP and SCTP */
uint16_t global_cnx_id;
} m3ap_MME_internal_data_t;
int m3ap_MME_compare_assoc_id(struct m3ap_MME_data_s *p1, struct m3ap_MME_data_s *p2);
/* Generate the tree management functions */
struct m3ap_MME_map;
struct m3ap_MME_data_s;
RB_PROTOTYPE(m3ap_MME_map, m3ap_MME_data_s, entry, m3ap_MME_compare_assoc_id);
#endif /* M3AP_MME_DEFS_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
/*! \file m3ap_common.c /*! \file m3ap_common.c
* \brief m3ap procedures for both MCE and MME * \brief m3ap procedures for both eNB and MCE
* \author Javier Morgade <javier.morgade@ieee.org> * \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019 * \date 2019
* \version 0.1 * \version 0.1
......
...@@ -38,14 +38,6 @@ ...@@ -38,14 +38,6 @@
#ifndef M3AP_COMMON_H_ #ifndef M3AP_COMMON_H_
#define M3AP_COMMON_H_ #define M3AP_COMMON_H_
/*! \file m3ap_common.h
* \brief m3ap procedures for both MCE and MME
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation /** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation
* @ingroup _ref_implementation_ * @ingroup _ref_implementation_
* @{ * @{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment