Commit ab04e0e4 authored by Javier Morgade's avatar Javier Morgade

M2AP 3GPP TS 36.443 interface implemented:

	1.MCE (Multicast Control Entity) entity developed (new dedicated task developed: TASK_MCE_APP)
	2.eNB side M2 interface procedures (new dedicated task developed: TASK_M2AP_ENB)
	3.MCE side M2 interface procedures (new dedicated task developed: TASK_M2AP_MCE)
	4.ASN1 bindings for m2ap-14.0.0.asn1 implemented and tested
	5.MCE 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 3992eb9e
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 m2ap_MCE.h
* \brief m2ap tasks for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include <stdint.h>
/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M2AP_MCE_H_
#define M2AP_MCE_H_
#include "m2ap_MCE_defs.h"
int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M2C);
void *m2ap_MCE_task(void *arg);
int is_m2ap_MCE_enabled(void);
#endif /* M2AP_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 m2ap_MCE_defs.h
* \brief m2ap 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 "m2ap_ids.h" //looks X2AP specific for HO
#include "m2ap_timers.h"
#ifndef M2AP_MCE_DEFS_H_
#define M2AP_MCE_DEFS_H_
#define M2AP_MCE_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
M2AP_MCE_STATE_DISCONNECTED = 0x0,
/* State waiting for m2 Setup response message if the target MCE accepts or
* M2 Setup failure if rejects the MCE.
*/
M2AP_MCE_STATE_WAITING = 0x1,
/* The MCE is successfully connected to another MCE. */
M2AP_MCE_STATE_CONNECTED = 0x2,
/* M2AP is ready, and the MCE is successfully connected to another MCE. */
M2AP_MCE_STATE_READY = 0x3,
M2AP_MCE_STATE_OVERLOAD = 0x4,
M2AP_MCE_STATE_RESETTING = 0x5,
/* Max number of states available */
M2AP_MCE_STATE_MAX,
} m2ap_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 m2ap_MCE_instance_s;
/* This structure describes association of a MCE to another MCE */
typedef struct m2ap_MCE_data_s {
/* MCE descriptors tree, ordered by sctp assoc id */
RB_ENTRY(m2ap_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). */
//m2ap_load_state_t overload_state;
/* Current MCE->MCE M2AP association state */
m2ap_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/M2AP */
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 m2ap_MCE_instance_s *m2ap_MCE_instance;
} m2ap_MCE_data_t;
typedef struct m2ap_MCE_instance_s {
/* used in simulation to store multiple MCE instances*/
STAILQ_ENTRY(m2ap_MCE_instance_s) m2ap_MCE_entries;
/* Number of target MCEs requested by MCE (tree size) */
uint32_t m2_target_mce_nb;
/* Number of target MCEs for which association is pending */
uint32_t m2_target_mce_pending_nb;
/* Number of target MCE successfully associated to MCE */
uint32_t m2_target_mce_associated_nb;
/* Tree of M2AP MCE associations ordered by association ID */
RB_HEAD(m2ap_mce_map, m2ap_MCE_data_s) m2ap_mce_head;
/* Tree of UE ordered by MCE_ue_m2ap_id's */
// RB_HEAD(m2ap_ue_map, m2ap_MCE_ue_context_s) m2ap_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_mce_m2_ip_address[M2AP_MAX_NB_MCE_IP_ADDRESS];
uint8_t nb_m2;
net_ip_address_t mce_m2_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t mce_port_for_M2C;
int multi_sd;
m2ap_id_manager id_manager;
m2ap_timers_t timers;
} m2ap_MCE_instance_t;
typedef struct {
/* List of served MCEs
* Only used for virtual mode
*/
STAILQ_HEAD(m2ap_MCE_instances_head_s, m2ap_MCE_instance_s) m2ap_MCE_instances_head;
/* Nb of registered MCEs */
uint8_t nb_registered_MCEs;
/* Generate a unique connexion id used between M2AP and SCTP */
uint16_t global_cnx_id;
} m2ap_MCE_internal_data_t;
int m2ap_MCE_compare_assoc_id(struct m2ap_MCE_data_s *p1, struct m2ap_MCE_data_s *p2);
/* Generate the tree management functions */
struct m2ap_MCE_map;
struct m2ap_MCE_data_s;
RB_PROTOTYPE(m2ap_MCE_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
#endif /* M2AP_MCE_DEFS_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 m2ap_MCE_generate_messages.h
* \brief m2ap procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_GENERATE_MESSAGES_H_
#define M2AP_MCE_GENERATE_MESSAGES_H_
#include "m2ap_MCE_defs.h"
#include "m2ap_common.h"
int m2ap_MCE_generate_m2_setup_request(m2ap_MCE_instance_t *instance_p,
m2ap_MCE_data_t *m2ap_MCE_data_p);
int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_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_MCE_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value);
//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id);
//
//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause);
#endif /* M2AP_MCE_GENERATE_MESSAGES_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_MCE_handler.c
* \brief m2ap handler procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "m2ap_common.h"
#include "m2ap_MCE_defs.h"
#include "m2ap_MCE_handler.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
//#include "m2ap_MCE_management_procedures.h"
#include "m2ap_MCE_generate_messages.h"
#include "m2ap_MCE_interface_management.h"
//#include "m2ap_eNB_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m2ap_message_decoded_callback m2ap_MCE_messages_callback[][3] = {
{ 0, MCE_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */
{ 0, MCE_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */
{ 0, MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE, 0 }, /* MBMSSchedulingInformation */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ MCE_handle_M2_SETUP_REQUEST, 0, 0 }, /* M2 Setup */
{ 0, 0, 0 }, /* eNBConfigurationUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ 0, 0, 0 }, /* privateMessage */
{ 0, 0, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MBMSServiceCounting */
{ 0, 0, 0 }, /* MBMSServiceCountingResultReport */
{ 0, 0, 0 } /* MBMSOverloadNotification */
};
static char *m2ap_direction2String(int m2ap_dir) {
static char *m2ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m2ap_direction_String[m2ap_dir]);
}
int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M2AP_M2AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (m2ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M2AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_MCE_messages_callback) / (3 * sizeof(
m2ap_MCE_message_decoded_callback))
|| (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M2AP, "[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_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m2ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M2AP, "Calling handler with instance %d\n",instance);
ret = (*m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_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 MCE
* \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 m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
//int m2ap_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 m2ap_MCE_interface_management.h
* \brief m2ap interface management for MCE
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M2AP_MCE_INTERFACE_MANAGEMENT_H_
#define M2AP_MCE_INTERFACE_MANAGEMENT_H_
/*
* MBMS Session start
*/
int MCE_send_MBMS_SESSION_START_REQUEST(instance_t instance/*,
uint32_t assoc_id*/,m2ap_session_start_req_t* m2ap_session_start_req);
int MCE_handle_MBMS_SESSION_START_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MBMS_SESSION_START_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* MBMS Session stop
*/
int MCE_send_MBMS_SESSION_STOP_REQUEST(instance_t instance,
m2ap_session_stop_req_t* m2ap_session_stop_req);
int MCE_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* MBMS Scheduling Information
*/
int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance,
/*uint32_t assoc_id,*/ m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information );
int MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Reset
*/
int MCE_send_RESET(instance_t instance, m2ap_reset_t * m2ap_reset);
int MCE_handle_RESET_ACKKNOWLEDGE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_RESET(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_RESET_ACKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge);
/*
* M2AP Setup
*/
int MCE_handle_M2_SETUP_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_M2_SETUP_RESPONSE(instance_t instance,/*uint32_t assoc_id,*/ m2ap_setup_resp_t *m2ap_setup_resp);
int MCE_send_M2_SETUP_FAILURE(instance_t instance, /*uint32_t assoc_id*/ m2ap_setup_failure_t * m2ap_setup_failure);
/*
* MCE Configuration Update
*/
int MCE_send_MCE_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP);
int MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* ENB Configuration Update
*/
int MCE_handle_ENB_CONFIGURATION_UPDATE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
m2ap_enb_configuration_update_failure_t *m2ap_enb_configuration_update_failure);
int MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
m2ap_enb_configuration_update_ack_t *m2ap_enb_configuration_update_ack);
/*
* Error Indication
*/
int MCE_handle_ERROR_INDICATION(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_ERROR_INDICATION(instance_t instance, M2AP_ErrorIndication_t *ErrorIndication);
/*
* Session Update Request
*/
int MCE_send_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, m2ap_mbms_session_update_req_t * m2ap_mbms_session_update_req);
int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Service Counting Request
*/
int MCE_send_MBMS_SERVICE_COUNTING_REQUEST(instance_t instance, module_id_t du_mod_idP);
int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Service Counting Results Report
*/
int MCE_handle_MBMS_SESSION_COUNTING_RESULTS_REPORT(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Overload Notification
*/
int MCE_handle_MBMS_OVERLOAD_NOTIFICATION(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
#endif /* M2AP_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 m2ap_MCE_management_procedures.c
* \brief m2ap 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 "m2ap_common.h"
#include "m2ap_MCE_defs.h"
#include "m2ap_MCE.h"
#define M2AP_DEBUG_LIST
#ifdef M2AP_DEBUG_LIST
# define M2AP_MCE_LIST_OUT(x, args...) M2AP_DEBUG("[MCE]%*s"x"\n", 4*indent, "", ##args)
#else
# define M2AP_MCE_LIST_OUT(x, args...)
#endif
static int indent = 0;
m2ap_MCE_internal_data_t m2ap_MCE_internal_data;
RB_GENERATE(m2ap_mce_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
int m2ap_MCE_compare_assoc_id(
struct m2ap_MCE_data_s *p1, struct m2ap_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 m2ap_MCE_fetch_add_global_cnx_id(void)
{
return ++m2ap_MCE_internal_data.global_cnx_id;
}
void m2ap_MCE_prepare_internal_data(void)
{
memset(&m2ap_MCE_internal_data, 0, sizeof(m2ap_MCE_internal_data));
STAILQ_INIT(&m2ap_MCE_internal_data.m2ap_MCE_instances_head);
}
void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p)
{
DevAssert(new_instance_p != NULL);
STAILQ_INSERT_TAIL(&m2ap_MCE_internal_data.m2ap_MCE_instances_head,
new_instance_p, m2ap_MCE_entries);
}
void dump_mce_tree_m2(m2ap_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_mce_tree_m2(t->entry.rbe_left);
dump_mce_tree_m2(t->entry.rbe_right);
}
void dump_mce_trees_m2(void)
{
m2ap_MCE_instance_t *zz;
STAILQ_FOREACH(zz, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
m2ap_MCE_entries) {
printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
dump_mce_tree_m2(zz->m2ap_mce_head.rbh_root);
printf("---------------------------------------------\n");
}
}
struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id)
{
struct m2ap_MCE_data_s temp;
struct m2ap_MCE_data_s *found;
printf("m2ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
dump_mce_trees_m2();
memset(&temp, 0, sizeof(struct m2ap_MCE_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
m2ap_MCE_entries) {
found = RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp);
if (found != NULL) {
return found;
}
}
} else {
return RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp);
}
return NULL;
}
m2ap_MCE_instance_t *m2ap_MCE_get_instance(instance_t instance)
{
m2ap_MCE_instance_t *temp = NULL;
STAILQ_FOREACH(temp, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
m2ap_MCE_entries) {
if (temp->instance == instance) {
/* Matching occurence */
return temp;
}
}
return NULL;
}
/// utility functions
void m2ap_dump_MCE (m2ap_MCE_data_t * MCE_ref);
void
m2ap_dump_MCE_list (void) {
m2ap_MCE_instance_t *inst = NULL;
struct m2ap_MCE_data_s *found = NULL;
struct m2ap_MCE_data_s temp;
memset(&temp, 0, sizeof(struct m2ap_MCE_data_s));
STAILQ_FOREACH (inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
found = RB_FIND(m2ap_mce_map, &inst->m2ap_mce_head, &temp);
m2ap_dump_MCE (found);
}
}
void m2ap_dump_MCE (m2ap_MCE_data_t * MCE_ref) {
if (MCE_ref == NULL) {
return;
}
M2AP_MCE_LIST_OUT ("");
M2AP_MCE_LIST_OUT ("MCE name: %s", MCE_ref->MCE_name == NULL ? "not present" : MCE_ref->MCE_name);
M2AP_MCE_LIST_OUT ("MCE STATE: %07x", MCE_ref->state);
M2AP_MCE_LIST_OUT ("MCE ID: %07x", MCE_ref->MCE_id);
indent++;
M2AP_MCE_LIST_OUT ("SCTP cnx id: %d", MCE_ref->cnx_id);
M2AP_MCE_LIST_OUT ("SCTP assoc id: %d", MCE_ref->assoc_id);
M2AP_MCE_LIST_OUT ("SCTP instreams: %d", MCE_ref->in_streams);
M2AP_MCE_LIST_OUT ("SCTP outstreams: %d", MCE_ref->out_streams);
indent--;
}
m2ap_MCE_data_t * m2ap_is_MCE_pci_in_list (const uint32_t pci)
{
m2ap_MCE_instance_t *inst;
struct m2ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) {
for (int i = 0; i<elm->num_cc; i++) {
if (elm->Nid_cell[i] == pci) {
return elm;
}
}
}
}
return NULL;
}
m2ap_MCE_data_t * m2ap_is_MCE_id_in_list (const uint32_t MCE_id)
{
m2ap_MCE_instance_t *inst;
struct m2ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) {
if (elm->MCE_id == MCE_id)
return elm;
}
}
return NULL;
}
m2ap_MCE_data_t * m2ap_is_MCE_assoc_id_in_list (const uint32_t sctp_assoc_id)
{
m2ap_MCE_instance_t *inst;
struct m2ap_MCE_data_s *found;
struct m2ap_MCE_data_s temp;
temp.assoc_id = sctp_assoc_id;
temp.cnx_id = -1;
STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
found = RB_FIND(m2ap_mce_map, &inst->m2ap_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 m2ap_eNB_management_procedures.h
* \brief m2ap tasks for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_MANAGEMENT_PROCEDURES_H_
#define M2AP_MCE_MANAGEMENT_PROCEDURES_H
void m2ap_MCE_prepare_internal_data(void);
void dump_trees_m2(void);
void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p);
m2ap_MCE_instance_t *m2ap_MCE_get_instance(uint8_t mod_id);
uint16_t m2ap_MCE_fetch_add_global_cnx_id(void);
void m2ap_MCE_prepare_internal_data(void);
m2ap_MCE_data_t* m2ap_is_MCE_id_in_list(uint32_t MCE_id);
m2ap_MCE_data_t* m2ap_is_MCE_assoc_id_in_list(uint32_t sctp_assoc_id);
m2ap_MCE_data_t* m2ap_is_MCE_pci_in_list (const uint32_t pci);
struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id);
#endif /* M2AP_MCE_MANAGEMENT_PROCEDURES_H_ */
...@@ -41,13 +41,6 @@ ...@@ -41,13 +41,6 @@
#ifndef M2AP_COMMON_H_ #ifndef M2AP_COMMON_H_
#define M2AP_COMMON_H_ #define M2AP_COMMON_H_
/*! \file m2ap_common.h
* \brief m2ap procedures for both eNB and MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation /** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
* @ingroup _ref_implementation_ * @ingroup _ref_implementation_
* @{ * @{
......
/*
* 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_decoder.c
* \brief m2ap decoder procedures
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include "assertions.h"
#include "intertask_interface.h"
#include "m2ap_common.h"
#include "m2ap_decoder.h"
static int m2ap_decode_initiating_message(M2AP_M2AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.initiatingMessage.procedureCode) {
case M2AP_ProcedureCode_id_sessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_sessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_m2Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
// case M2AP_ProcedureCode_id_handoverPreparation:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_initiating_message!\n");
// break;
//
// case M2AP_ProcedureCode_id_uEContextRelease:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_initiating_message!\n");
// break;
//
// case M2AP_ProcedureCode_id_handoverCancel:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_initiating_message!\n");
// break;
//
default:
M2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
return -1;
}
return 0;
}
static int m2ap_decode_successful_outcome(M2AP_M2AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.successfulOutcome.procedureCode) {
case M2AP_ProcedureCode_id_sessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_successfuloutcome_message!\n");
break;
case M2AP_ProcedureCode_id_sessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
break;
case M2AP_ProcedureCode_id_m2Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
break;
case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
break;
// case M2AP_ProcedureCode_id_handoverPreparation:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_successfuloutcome_message!\n");
// break;
//
default:
M2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
(int)pdu->choice.successfulOutcome.procedureCode);
return -1;
}
return 0;
}
static int m2ap_decode_unsuccessful_outcome(M2AP_M2AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.unsuccessfulOutcome.procedureCode) {
case M2AP_ProcedureCode_id_sessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_sessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_m2Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
default:
M2AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
(int)pdu->choice.unsuccessfulOutcome.procedureCode);
return -1;
}
return 0;
}
int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
{
asn_dec_rval_t dec_ret;
DevAssert(buffer != NULL);
dec_ret = aper_decode(NULL,
&asn_DEF_M2AP_M2AP_PDU,
(void **)&pdu,
buffer,
length,
0,
0);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, pdu);
}
if (dec_ret.code != RC_OK) {
M2AP_ERROR("Failed to decode pdu\n");
return -1;
}
switch(pdu->present) {
case M2AP_M2AP_PDU_PR_initiatingMessage:
return m2ap_decode_initiating_message(pdu);
case M2AP_M2AP_PDU_PR_successfulOutcome:
return m2ap_decode_successful_outcome(pdu);
case M2AP_M2AP_PDU_PR_unsuccessfulOutcome:
return m2ap_decode_unsuccessful_outcome(pdu);
default:
M2AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present);
break;
}
return -1;
}
/*
* 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_decoder.h
* \brief m2ap decoder procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_DECODER_H_
#define M2AP_DECODER_H_
int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
__attribute__ ((warn_unused_result));
#endif /* M2AP_DECODER_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_default_values.h
* \brief default values for m2ap procedures
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M2AP_DEFAULT_VALUES_H_
#define M2AP_DEFAULT_VALUES_H_
#define ENB_TAC (1)
#define ENB_MCC (208)
#define ENB_MNC (92)
#define ENB_NAME "Eurecom ENB"
#define ENB_NAME_FORMAT (ENB_NAME" %u")
#define M2AP_PORT_NUMBER (36443)
#define M2AP_SCTP_PPID (43)
#endif /* M2AP_DEFAULT_VALUES_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 m2ap_eNB.h
* \brief m2ap 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 _m2ap_impl_ M2AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M2AP_ENB_H_
#define M2AP_ENB_H_
#include "m2ap_eNB_defs.h"
int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M2C);
void *m2ap_eNB_task(void *arg);
int is_m2ap_eNB_enabled(void);
#endif /* M2AP_ENB_H_ */
/**
* @}
*/
This diff is collapsed.
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 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_ */
/*
* 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_handler.c
* \brief m2ap 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 "m2ap_common.h"
#include "m2ap_eNB_defs.h"
#include "m2ap_eNB_handler.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
#include "m2ap_eNB_management_procedures.h"
#include "m2ap_eNB_generate_messages.h"
//#include "m2ap_MCE_interface_management.h"
#include "m2ap_eNB_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m2ap_eNB_message_decoded_callback m2ap_eNB_messages_callback[][3] = {
{ eNB_handle_MBMS_SESSION_START_REQUEST, 0, 0 }, /* MBMSSessionStart */
{ eNB_handle_MBMS_SESSION_STOP_REQUEST, 0, 0 }, /* MBMSSessionStop */
{ eNB_handle_MBMS_SCHEDULING_INFORMATION, 0, 0 }, /* MBMSSchedulingInformation */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ 0,eNB_handle_M2_SETUP_RESPONSE,eNB_handle_M2_SETUP_FAILURE }, /* M2 Setup */
{ 0, 0, 0 }, /* eNBConfigurationUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ 0, 0, 0 }, /* privateMessage */
{ 0, 0, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MBMSServiceCounting */
{ 0, 0, 0 }, /* MBMSServiceCountingResultReport */
{ 0, 0, 0 } /* MBMSOverloadNotification */
};
static char *m2ap_direction2String(int m2ap_dir) {
static char *m2ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m2ap_direction_String[m2ap_dir]);
}
int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M2AP_M2AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (m2ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M2AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_eNB_messages_callback) / (3 * sizeof(
m2ap_message_decoded_callback))
|| (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M2AP, "[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_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m2ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M2AP, "Calling handler with instance %d\n",instance);
ret = (*m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return ret;
}
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