Remove big race condition, remove name "callback" on what is not a callback
This commit is contained in:
@@ -303,7 +303,7 @@ typedef struct f1ap_initial_ul_rrc_message_s {
|
||||
uint16_t crnti;
|
||||
uint8_t *rrc_container;
|
||||
int rrc_container_length;
|
||||
char *du2cu_rrc_container;
|
||||
char du2cu_rrc_container[100];
|
||||
int du2cu_rrc_container_length;
|
||||
} f1ap_initial_ul_rrc_message_t;
|
||||
|
||||
|
||||
@@ -407,14 +407,16 @@
|
||||
if (mandatory) DevAssert(ie != NULL); \
|
||||
} while(0)
|
||||
|
||||
/** \brief Function callback prototype.
|
||||
/** \brief Function array prototype.
|
||||
**/
|
||||
typedef int (*f1ap_message_decoded_callback)(
|
||||
typedef int (*f1ap_message_processing_t)(
|
||||
instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *message_p
|
||||
);
|
||||
int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
|
||||
const uint8_t *const data, const uint32_t data_length);
|
||||
|
||||
typedef struct f1ap_cudu_ue_inst_s {
|
||||
// used for eNB stats generation
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
*/
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_handlers.h"
|
||||
#include "f1ap_cu_interface_management.h"
|
||||
#include "f1ap_cu_rrc_message_transfer.h"
|
||||
#include "f1ap_cu_ue_context_management.h"
|
||||
|
||||
@@ -324,7 +324,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
{
|
||||
/* qoS_Characteristics */
|
||||
{
|
||||
int some_decide_qoS_characteristics = 1; // BK: Need Check
|
||||
int some_decide_qoS_characteristics = 0; // BK: Need Check
|
||||
|
||||
if (some_decide_qoS_characteristics) {
|
||||
DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
|
||||
@@ -433,7 +433,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
{
|
||||
/* qoS_Characteristics */
|
||||
{
|
||||
int some_decide_qoS_characteristics = 1; // BK: Need Check
|
||||
int some_decide_qoS_characteristics = 0; // BK: Need Check
|
||||
F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics;
|
||||
|
||||
if (some_decide_qoS_characteristics) {
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
*/
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_handlers.h"
|
||||
#include "f1ap_du_interface_management.h"
|
||||
#include "f1ap_du_ue_context_management.h"
|
||||
#include "f1ap_du_rrc_message_transfer.h"
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
*/
|
||||
|
||||
#include "f1ap_common.h"
|
||||
#include "f1ap_handlers.h"
|
||||
#include "f1ap_decoder.h"
|
||||
#include "f1ap_cu_interface_management.h"
|
||||
#include "f1ap_du_interface_management.h"
|
||||
@@ -41,7 +40,7 @@
|
||||
#include "f1ap_du_ue_context_management.h"
|
||||
|
||||
/* Handlers matrix. Only f1 related procedure present here */
|
||||
f1ap_message_decoded_callback f1ap_messages_callback[][3] = {
|
||||
f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
||||
|
||||
|
||||
{ 0, 0, 0 }, /* Reset */
|
||||
@@ -92,8 +91,8 @@ int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
|
||||
}
|
||||
|
||||
/* Checking procedure Code and direction of message */
|
||||
if (pdu.choice.initiatingMessage->procedureCode >= sizeof(f1ap_messages_callback) / (3 * sizeof(
|
||||
f1ap_message_decoded_callback))
|
||||
if (pdu.choice.initiatingMessage->procedureCode >= sizeof(f1ap_message_processing_t) / (3 * sizeof(
|
||||
f1ap_message_processing_t))
|
||||
|| (pdu.present > F1AP_F1AP_PDU_PR_unsuccessfulOutcome)) {
|
||||
LOG_E(F1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
|
||||
assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present);
|
||||
@@ -101,21 +100,19 @@ int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* No handler present.
|
||||
* This can mean not implemented or no procedure for eNB (wrong direction).
|
||||
*/
|
||||
if (f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
|
||||
|
||||
if (f1ap_messages_processing[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
|
||||
// No handler present. This can mean not implemented or no procedure for eNB (wrong direction).
|
||||
LOG_E(F1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
|
||||
assoc_id, pdu.choice.initiatingMessage->procedureCode,
|
||||
f1ap_direction2String(pdu.present - 1));
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
return -1;
|
||||
ret=-1;
|
||||
} else {
|
||||
/* Calling the right handler */
|
||||
LOG_I(F1AP, "Calling handler with instance %ld\n",instance);
|
||||
ret = (*f1ap_messages_processing[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])
|
||||
(instance, assoc_id, stream, &pdu);
|
||||
}
|
||||
|
||||
/* Calling the right handler */
|
||||
LOG_I(F1AP, "Calling handler with instance %ld\n",instance);
|
||||
ret = (*f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])
|
||||
(instance, assoc_id, stream, &pdu);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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 f1ap_handlers.h
|
||||
* \brief f1ap messages handlers
|
||||
* \author EURECOM/NTUST
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef F1AP_HANDLERS_H_
|
||||
#define F1AP_HANDLERS_H_
|
||||
|
||||
int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
|
||||
const uint8_t *const data, const uint32_t data_length);
|
||||
|
||||
#endif /* F1AP_HANDLERS_H_ */
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* 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 rrc_UE_ral.c
|
||||
* \brief rrc procedures for handling RAL messages
|
||||
* \author Lionel GAUTHIER
|
||||
* \date 2013
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: lionel.gauthier@eurecom.fr
|
||||
*/
|
||||
#define RRC_UE
|
||||
#define RRC_UE_RAL_C
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "rrc_UE_ral.h"
|
||||
#include "assertions.h"
|
||||
#include "collection/hashtable/obj_hashtable.h"
|
||||
#include "RRC/LTE/defs.h"
|
||||
#include "RRC/LTE/extern.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_ue_ral_delete_all_thresholds_type(unsigned int mod_idP, ral_link_param_type_t *param_type_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
hashtable_rc_t rc;
|
||||
rrc_ral_threshold_key_t *key;
|
||||
rrc_ral_threshold_key_t *keys = NULL;
|
||||
unsigned int num_keys = 0;
|
||||
int return_code = 0;
|
||||
rc = obj_hashtable_get_keys(UE_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&keys, &num_keys);
|
||||
|
||||
if (rc == HASH_TABLE_OK) {
|
||||
key = keys;
|
||||
|
||||
while (num_keys > 0) {
|
||||
if (memcmp(&key->link_param_type, param_type_pP, sizeof(ral_link_param_type_t)) == 0) {
|
||||
rc = obj_hashtable_remove (UE_rrc_inst[mod_idP].ral_meas_thresholds, key, sizeof(rrc_ral_threshold_key_t));
|
||||
|
||||
if (rc != HASH_TABLE_OK) {
|
||||
return_code = -1;
|
||||
}
|
||||
}
|
||||
|
||||
key = &key[1];
|
||||
num_keys--;
|
||||
}
|
||||
} else {
|
||||
return_code = -1;
|
||||
}
|
||||
|
||||
if (keys != NULL) {
|
||||
free(keys);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_ue_ral_delete_threshold(unsigned int mod_idP, ral_link_param_type_t *param_type_pP, ral_threshold_t *threshold_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
hashtable_rc_t rc;
|
||||
rrc_ral_threshold_key_t ref_key;
|
||||
memcpy(&ref_key.link_param_type, param_type_pP, sizeof(ral_link_param_type_t));
|
||||
memcpy(&ref_key.threshold, threshold_pP, sizeof(ral_threshold_t));
|
||||
rc = obj_hashtable_remove (UE_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&ref_key, sizeof(rrc_ral_threshold_key_t));
|
||||
|
||||
if (rc == HASH_TABLE_OK) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_ue_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageDef *msg_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ral_transaction_id_t transaction_id = 0;
|
||||
rrc_ral_configure_threshold_req_t *configure_threshold_req_p = NULL;
|
||||
ral_link_cfg_param_t *link_cfg_param_p = NULL;
|
||||
ral_threshold_t *threshold_p = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
unsigned int ix_param = 0;
|
||||
unsigned int ix_thresholds = 0;
|
||||
DevAssert(msg_pP != NULL);
|
||||
LOG_I(RRC, "[UE %d] Received %s\n", mod_idP, ITTI_MSG_NAME (msg_pP));
|
||||
configure_threshold_req_p = &RRC_RAL_CONFIGURE_THRESHOLD_REQ(msg_pP);
|
||||
transaction_id = configure_threshold_req_p->transaction_id;
|
||||
|
||||
for (ix_param = 0; ix_param < configure_threshold_req_p->num_link_cfg_params; ix_param++) {
|
||||
link_cfg_param_p = &configure_threshold_req_p->link_cfg_params[ix_param];
|
||||
|
||||
switch (link_cfg_param_p->th_action) {
|
||||
case RAL_TH_ACTION_SET_NORMAL_THRESHOLD:
|
||||
case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD:
|
||||
switch (link_cfg_param_p->link_param_type.choice) {
|
||||
case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
|
||||
switch (link_cfg_param_p->link_param_type._union.link_param_gen) {
|
||||
case RAL_LINK_PARAM_GEN_DATA_RATE:
|
||||
case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH:
|
||||
case RAL_LINK_PARAM_GEN_SINR:
|
||||
case RAL_LINK_PARAM_GEN_THROUGHPUT:
|
||||
case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_TYPE_CHOICE_QOS:
|
||||
switch (link_cfg_param_p->link_param_type._union.link_param_qos) {
|
||||
case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED:
|
||||
case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS:
|
||||
case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS:
|
||||
case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS:
|
||||
case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY:
|
||||
case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
|
||||
switch (link_cfg_param_p->link_param_type._union.link_param_lte) {
|
||||
// group by dest task id
|
||||
case RAL_LINK_PARAM_LTE_UE_RSRP:
|
||||
case RAL_LINK_PARAM_LTE_UE_RSRQ:
|
||||
case RAL_LINK_PARAM_LTE_UE_CQI:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_LTE_AVAILABLE_BW:
|
||||
case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE:
|
||||
case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS:
|
||||
case RAL_LINK_PARAM_LTE_PACKET_DELAY:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES:
|
||||
case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY:
|
||||
case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY:
|
||||
case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS:
|
||||
case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW:
|
||||
#warning "TO DO MIH LTE LINK PARAMS IN RRC UE"
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) {
|
||||
threshold_p = &link_cfg_param_p->thresholds[ix_thresholds];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RAL_TH_ACTION_CANCEL_THRESHOLD:
|
||||
|
||||
// IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228):
|
||||
// When “Cancel threshold” is selected and no thresholds are specified, then all
|
||||
// currently configured thresholds for the given LINK_PARAM_TYPE are cancelled.
|
||||
if (link_cfg_param_p->num_thresholds == 0) {
|
||||
rrc_ue_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type);
|
||||
} else {
|
||||
//
|
||||
// When “Cancel threshold” is selected and thresholds are specified only those
|
||||
// configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was
|
||||
// specified are cancelled.
|
||||
for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) {
|
||||
threshold_p = &link_cfg_param_p->thresholds[ix_thresholds];
|
||||
rrc_ue_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ with RAL_TH_ACTION_CANCEL_THRESHOLD\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* 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 rrc_eNB_ral.c
|
||||
* \brief rrc procedures for handling RAL messages
|
||||
* \author Lionel GAUTHIER
|
||||
* \date 2013
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: lionel.gauthier@eurecom.fr
|
||||
*/
|
||||
#define RRC_ENB
|
||||
#define RRC_ENB_RAL_C
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "rrc_eNB_ral.h"
|
||||
#include "assertions.h"
|
||||
#include "collection/hashtable/obj_hashtable.h"
|
||||
#include "RRC/LTE/defs.h"
|
||||
#include "RRC/LTE/extern.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_enb_ral_delete_all_thresholds_type(unsigned int mod_idP, ral_link_param_type_t *param_type_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
hashtable_rc_t rc;
|
||||
rrc_ral_threshold_key_t *key;
|
||||
rrc_ral_threshold_key_t *keys = NULL;
|
||||
unsigned int num_keys = 0;
|
||||
int return_code = 0;
|
||||
rc = obj_hashtable_get_keys(eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&keys, &num_keys);
|
||||
|
||||
if (rc == HASH_TABLE_OK) {
|
||||
key = keys;
|
||||
|
||||
while (num_keys > 0) {
|
||||
if (memcmp(&key->link_param_type, param_type_pP, sizeof(ral_link_param_type_t)) == 0) {
|
||||
rc = obj_hashtable_remove (eNB_rrc_inst[mod_idP].ral_meas_thresholds, key, sizeof(rrc_ral_threshold_key_t));
|
||||
|
||||
if (rc != HASH_TABLE_OK) {
|
||||
return_code = -1;
|
||||
}
|
||||
}
|
||||
|
||||
key = &key[1];
|
||||
num_keys--;
|
||||
}
|
||||
} else {
|
||||
return_code = -1;
|
||||
}
|
||||
|
||||
if (keys != NULL) {
|
||||
free(keys);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_enb_ral_delete_threshold(unsigned int mod_idP, ral_link_param_type_t *param_type_pP, ral_threshold_t *threshold_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
hashtable_rc_t rc;
|
||||
rrc_ral_threshold_key_t ref_key;
|
||||
memcpy(&ref_key.link_param_type, param_type_pP, sizeof(ral_link_param_type_t));
|
||||
memcpy(&ref_key.threshold, threshold_pP, sizeof(ral_threshold_t));
|
||||
rc = obj_hashtable_remove (eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&ref_key, sizeof(rrc_ral_threshold_key_t));
|
||||
|
||||
if (rc == HASH_TABLE_OK) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int rrc_enb_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageDef *msg_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ral_transaction_id_t transaction_id = 0;
|
||||
rrc_ral_configure_threshold_req_t *configure_threshold_req_p = NULL;
|
||||
ral_link_cfg_param_t *link_cfg_param_p = NULL;
|
||||
ral_threshold_t *threshold_p = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
unsigned int ix_param = 0;
|
||||
unsigned int ix_thresholds = 0;
|
||||
DevAssert(msg_pP != NULL);
|
||||
LOG_I(RRC, "[eNB %d] Received %s\n", mod_idP, ITTI_MSG_NAME (msg_pP));
|
||||
configure_threshold_req_p = &RRC_RAL_CONFIGURE_THRESHOLD_REQ(msg_pP);
|
||||
transaction_id = configure_threshold_req_p->transaction_id;
|
||||
|
||||
for (ix_param = 0; ix_param < configure_threshold_req_p->num_link_cfg_params; ix_param++) {
|
||||
link_cfg_param_p = &configure_threshold_req_p->link_cfg_params[ix_param];
|
||||
|
||||
switch (link_cfg_param_p->th_action) {
|
||||
case RAL_TH_ACTION_SET_NORMAL_THRESHOLD:
|
||||
case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD:
|
||||
switch (link_cfg_param_p->link_param_type.choice) {
|
||||
case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
|
||||
switch (link_cfg_param_p->link_param_type._union.link_param_gen) {
|
||||
case RAL_LINK_PARAM_GEN_DATA_RATE:
|
||||
case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH:
|
||||
case RAL_LINK_PARAM_GEN_SINR:
|
||||
case RAL_LINK_PARAM_GEN_THROUGHPUT:
|
||||
case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_TYPE_CHOICE_QOS:
|
||||
switch (link_cfg_param_p->link_param_type._union.link_param_qos) {
|
||||
case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED:
|
||||
case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS:
|
||||
case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS:
|
||||
case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS:
|
||||
case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY:
|
||||
case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
|
||||
switch (link_cfg_param_p->link_param_type._union.link_param_lte) {
|
||||
// group by dest task id
|
||||
case RAL_LINK_PARAM_LTE_UE_RSRP:
|
||||
case RAL_LINK_PARAM_LTE_UE_RSRQ:
|
||||
case RAL_LINK_PARAM_LTE_UE_CQI:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_LTE_AVAILABLE_BW:
|
||||
case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE:
|
||||
case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS:
|
||||
case RAL_LINK_PARAM_LTE_PACKET_DELAY:
|
||||
message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ);
|
||||
PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id;
|
||||
memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t));
|
||||
itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p);
|
||||
break;
|
||||
|
||||
case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES:
|
||||
case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY:
|
||||
case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY:
|
||||
case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS:
|
||||
case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW:
|
||||
#warning "TO DO MIH LTE LINK PARAMS IN RRC ENB"
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) {
|
||||
threshold_p = &link_cfg_param_p->thresholds[ix_thresholds];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RAL_TH_ACTION_CANCEL_THRESHOLD:
|
||||
|
||||
// IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228):
|
||||
// When “Cancel threshold” is selected and no thresholds are specified, then all
|
||||
// currently configured thresholds for the given LINK_PARAM_TYPE are cancelled.
|
||||
if (link_cfg_param_p->num_thresholds == 0) {
|
||||
rrc_enb_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type);
|
||||
} else {
|
||||
//
|
||||
// When “Cancel threshold” is selected and thresholds are specified only those
|
||||
// configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was
|
||||
// specified are cancelled.
|
||||
for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) {
|
||||
threshold_p = &link_cfg_param_p->thresholds[ix_thresholds];
|
||||
rrc_enb_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -322,31 +322,27 @@ int8_t nr_mac_rrc_data_ind(const module_id_t module_idP,
|
||||
// call do_RRCSetup like full procedure and extract masterCellGroup
|
||||
NR_CellGroupConfig_t cellGroupConfig;
|
||||
NR_ServingCellConfigCommon_t *scc=RC.nrrrc[module_idP]->carrier.servingcellconfigcommon;
|
||||
uint8_t sdu2[100];
|
||||
memset(&cellGroupConfig,0,sizeof(cellGroupConfig));
|
||||
fill_initial_cellGroupConfig(rntiP,&cellGroupConfig,scc);
|
||||
MessageDef* tmp=itti_alloc_new_message_sized(TASK_RRC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE, sizeof(f1ap_initial_ul_rrc_message_t) + sdu_lenP);
|
||||
f1ap_initial_ul_rrc_message_t *msg = &F1AP_INITIAL_UL_RRC_MESSAGE(tmp);
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
||||
NULL,
|
||||
(void *)&cellGroupConfig,
|
||||
sdu2,
|
||||
100);
|
||||
msg->du2cu_rrc_container,
|
||||
sizeof(msg->du2cu_rrc_container));
|
||||
|
||||
int sdu2_len = (enc_rval.encoded+7)/8;
|
||||
if (enc_rval.encoded == -1) {
|
||||
LOG_I(F1AP,"Could not encoded cellGroupConfig, failed element %s\n",enc_rval.failed_type->name);
|
||||
exit(-1);
|
||||
}
|
||||
/* do ITTI message */
|
||||
DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(
|
||||
module_idP,
|
||||
CC_id,
|
||||
UE_id,
|
||||
rntiP,
|
||||
sduP,
|
||||
sdu_lenP,
|
||||
sdu2,
|
||||
sdu2_len
|
||||
);
|
||||
msg->du2cu_rrc_container_length = (enc_rval.encoded+7)/8;
|
||||
msg->crnti=rntiP;
|
||||
msg->rrc_container=(uint8_t*) (msg+1); // Made extra room after the struct with itti_alloc_msg_sized()
|
||||
memcpy(msg->rrc_container, sduP, sdu_lenP);
|
||||
msg->rrc_container_length=sdu_lenP;
|
||||
itti_send_msg(TASK_DU_F1, 0, tmp);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,485 +0,0 @@
|
||||
/*
|
||||
* 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 gtpv1u_task.c
|
||||
* \brief
|
||||
* \author Sebastien ROUX, Lionel Gauthier
|
||||
* \company Eurecom
|
||||
* \email: lionel.gauthier@eurecom.fr
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "mme_config.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "gtpv1u.h"
|
||||
#include "NwGtpv1u.h"
|
||||
#include "NwGtpv1uMsg.h"
|
||||
#include "NwLog.h"
|
||||
#include "gtpv1u_sgw_defs.h"
|
||||
#include "NwGtpv1uPrivate.h"
|
||||
#include "msc.h"
|
||||
|
||||
//static NwGtpv1uStackHandleT gtpv1u_stack = 0;
|
||||
static gtpv1u_data_t gtpv1u_sgw_data;
|
||||
|
||||
|
||||
static int gtpv1u_create_s1u_tunnel(Gtpv1uCreateTunnelReq *create_tunnel_reqP);
|
||||
static int gtpv1u_delete_s1u_tunnel(Teid_t context_teidP, Teid_t S1U_teidP);
|
||||
static int gtpv1u_update_s1u_tunnel(Gtpv1uUpdateTunnelReq *reqP);
|
||||
static void *gtpv1u_thread(void *args);
|
||||
|
||||
NwGtpv1uRcT gtpv1u_send_udp_msg(
|
||||
NwGtpv1uUdpHandleT udpHandle,
|
||||
uint8_t *buffer,
|
||||
uint32_t buffer_len,
|
||||
uint32_t buffer_offset,
|
||||
uint32_t peerIpAddr,
|
||||
uint32_t peerPort);
|
||||
|
||||
NwGtpv1uRcT gtpv1u_log_request(
|
||||
NwGtpv1uLogMgrHandleT hLogMgr,
|
||||
uint32_t logLevel,
|
||||
NwCharT *file,
|
||||
uint32_t line,
|
||||
NwCharT *logStr);
|
||||
|
||||
NwGtpv1uRcT gtpv1u_process_stack_req(
|
||||
NwGtpv1uUlpHandleT hUlp,
|
||||
NwGtpv1uUlpApiT *pUlpApi);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void gtpu_print_hex_octets(unsigned char* dataP, unsigned long sizeP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
unsigned long octet_index = 0;
|
||||
unsigned long buffer_marker = 0;
|
||||
unsigned char aindex;
|
||||
#define GTPU_2_PRINT_BUFFER_LEN 8000
|
||||
char gtpu_2_print_buffer[GTPU_2_PRINT_BUFFER_LEN];
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
char timeofday[64];
|
||||
unsigned int h,m,s;
|
||||
|
||||
if (dataP == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
h = tv.tv_sec/3600/24;
|
||||
m = (tv.tv_sec / 60) % 60;
|
||||
s = tv.tv_sec % 60;
|
||||
snprintf(timeofday, 64, "%02u:%02u:%02u.%06d", h,m,s,tv.tv_usec);
|
||||
|
||||
GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday);
|
||||
GTPU_DEBUG("%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
|
||||
GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday);
|
||||
|
||||
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
||||
if (GTPU_2_PRINT_BUFFER_LEN < (buffer_marker + 32)) {
|
||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker,
|
||||
"... (print buffer overflow)");
|
||||
GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((octet_index % 16) == 0) {
|
||||
if (octet_index != 0) {
|
||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||
GTPU_DEBUG("%s%s",timeofday, gtpu_2_print_buffer);
|
||||
buffer_marker = 0;
|
||||
}
|
||||
|
||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %04lu |", octet_index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print every single octet in hexadecimal form
|
||||
*/
|
||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %02x", dataP[octet_index]);
|
||||
/*
|
||||
* Align newline and pipes according to the octets in groups of 2
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Append enough spaces and put final pipe
|
||||
*/
|
||||
for (aindex = octet_index; aindex < 16; ++aindex)
|
||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " ");
|
||||
|
||||
//GTPU_DEBUG(" ");
|
||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||
GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer);
|
||||
}
|
||||
|
||||
|
||||
NwGtpv1uRcT gtpv1u_log_request(NwGtpv1uLogMgrHandleT hLogMgr,
|
||||
uint32_t logLevel,
|
||||
NwCharT *file,
|
||||
uint32_t line,
|
||||
NwCharT *logStr)
|
||||
{
|
||||
GTPU_DEBUG("%s\n", logStr);
|
||||
return NW_GTPV1U_OK;
|
||||
}
|
||||
|
||||
NwGtpv1uRcT gtpv1u_send_udp_msg(
|
||||
NwGtpv1uUdpHandleT udpHandle,
|
||||
uint8_t *buffer,
|
||||
uint32_t buffer_len,
|
||||
uint32_t buffer_offset,
|
||||
uint32_t peerIpAddr,
|
||||
uint32_t peerPort)
|
||||
{
|
||||
// Create and alloc new message
|
||||
MessageDef *message_p;
|
||||
udp_data_req_t *udp_data_req_p;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_DATA_REQ);
|
||||
|
||||
udp_data_req_p = &message_p->ittiMsg.udp_data_req;
|
||||
|
||||
udp_data_req_p->peer_address = peerIpAddr;
|
||||
udp_data_req_p->peer_port = peerPort;
|
||||
udp_data_req_p->buffer = buffer;
|
||||
udp_data_req_p->buffer_length = buffer_len;
|
||||
udp_data_req_p->buffer_offset = buffer_offset;
|
||||
|
||||
return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
|
||||
/* Callback called when a gtpv1u message arrived on UDP interface */
|
||||
NwGtpv1uRcT gtpv1u_process_stack_req(
|
||||
NwGtpv1uUlpHandleT hUlp,
|
||||
NwGtpv1uUlpApiT *pUlpApi)
|
||||
{
|
||||
switch(pUlpApi->apiType) {
|
||||
/* Here there are two type of messages handled:
|
||||
* - T-PDU
|
||||
* - END-MARKER
|
||||
*/
|
||||
case NW_GTPV1U_ULP_API_RECV_TPDU: {
|
||||
//uint8_t buffer[4096];
|
||||
//uint32_t buffer_len;
|
||||
MessageDef *message_p = NULL;
|
||||
Gtpv1uTunnelDataInd *data_ind_p = NULL;
|
||||
|
||||
/* Nw-gptv1u stack has processed a PDU. we can forward it to IPV4
|
||||
* task for transmission.
|
||||
*/
|
||||
/*if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
|
||||
buffer, (uint32_t *)&buffer_len)) {
|
||||
GTPU_ERROR("Error while retrieving T-PDU\n");
|
||||
}*/
|
||||
GTPU_DEBUG("Received TPDU from gtpv1u stack %u with size %d\n",
|
||||
pUlpApi->apiInfo.recvMsgInfo.teid,
|
||||
((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen);
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_TUNNEL_DATA_IND);
|
||||
|
||||
if (message_p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_ind_p = &message_p->ittiMsg.gtpv1uTunnelDataInd;
|
||||
data_ind_p->buffer = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf;
|
||||
data_ind_p->length = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen;
|
||||
data_ind_p->offset = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufOffset;
|
||||
data_ind_p->local_S1u_teid = pUlpApi->apiInfo.recvMsgInfo.teid;
|
||||
|
||||
if (data_ind_p->buffer == NULL) {
|
||||
GTPU_ERROR("Failed to allocate new buffer\n");
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
message_p = NULL;
|
||||
} else {
|
||||
//memcpy(data_ind_p->buffer, buffer, buffer_len);
|
||||
//data_ind_p->length = buffer_len;
|
||||
if (itti_send_msg_to_task(TASK_FW_IP, INSTANCE_DEFAULT, message_p) < 0) {
|
||||
GTPU_ERROR("Failed to send message to task\n");
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
message_p = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT: {
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
GTPU_ERROR("Received undefined UlpApi (%02x) from gtpv1u stack!\n",
|
||||
pUlpApi->apiType);
|
||||
}
|
||||
}
|
||||
|
||||
return NW_GTPV1U_OK;
|
||||
}
|
||||
|
||||
static int gtpv1u_create_s1u_tunnel(Gtpv1uCreateTunnelReq *create_tunnel_reqP)
|
||||
{
|
||||
/* Create a new nw-gtpv1-u stack req using API */
|
||||
NwGtpv1uUlpApiT stack_req;
|
||||
NwGtpv1uRcT rc;
|
||||
/* Local tunnel end-point identifier */
|
||||
uint32_t s1u_teid = 0;
|
||||
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info = NULL;
|
||||
MessageDef *message_p = NULL;
|
||||
hashtable_rc_t hash_rc;
|
||||
|
||||
GTPU_DEBUG("Rx GTPV1U_CREATE_TUNNEL_REQ Context %d\n", create_tunnel_reqP->context_teid);
|
||||
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
|
||||
|
||||
stack_req.apiType = NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT;
|
||||
|
||||
do {
|
||||
s1u_teid = gtpv1u_new_teid();
|
||||
GTPU_DEBUG("gtpv1u_create_s1u_tunnel() %u\n", s1u_teid);
|
||||
stack_req.apiInfo.createTunnelEndPointInfo.teid = s1u_teid;
|
||||
stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0;
|
||||
stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0;
|
||||
|
||||
rc = nwGtpv1uProcessUlpReq(gtpv1u_sgw_data.gtpv1u_stack, &stack_req);
|
||||
GTPU_DEBUG(".\n");
|
||||
} while (rc != NW_GTPV1U_OK);
|
||||
|
||||
gtpv1u_teid2enb_info = malloc (sizeof(gtpv1u_teid2enb_info_t));
|
||||
memset(gtpv1u_teid2enb_info, 0, sizeof(gtpv1u_teid2enb_info_t));
|
||||
gtpv1u_teid2enb_info->state = BEARER_IN_CONFIG;
|
||||
|
||||
//#warning !!! hack because missing modify session request, so force enb address
|
||||
// gtpv1u_teid2enb_info->enb_ip_addr.pdn_type = IPv4;
|
||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[0] = 192;
|
||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[1] = 168;
|
||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[2] = 1;
|
||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[3] = 2;
|
||||
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_CREATE_TUNNEL_RESP);
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.S1u_teid = s1u_teid;
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.context_teid = create_tunnel_reqP->context_teid;
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.eps_bearer_id = create_tunnel_reqP->eps_bearer_id;
|
||||
|
||||
hash_rc = hashtable_is_key_exists(gtpv1u_sgw_data.S1U_mapping, s1u_teid);
|
||||
|
||||
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
||||
hash_rc = hashtable_insert(gtpv1u_sgw_data.S1U_mapping, s1u_teid, gtpv1u_teid2enb_info);
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.status = 0;
|
||||
} else {
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.status = 0xFF;
|
||||
}
|
||||
|
||||
GTPU_DEBUG("Tx GTPV1U_CREATE_TUNNEL_RESP Context %u teid %u eps bearer id %u status %d\n",
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.context_teid,
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.S1u_teid,
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.eps_bearer_id,
|
||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.status);
|
||||
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int gtpv1u_delete_s1u_tunnel(Teid_t context_teidP, Teid_t S1U_teidP)
|
||||
{
|
||||
/* Local tunnel end-point identifier */
|
||||
MessageDef *message_p;
|
||||
|
||||
GTPU_DEBUG("Rx GTPV1U_DELETE_TUNNEL Context %u S1U teid %u\n", context_teidP, S1U_teidP);
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_DELETE_TUNNEL_RESP);
|
||||
|
||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.S1u_teid = S1U_teidP;
|
||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.context_teid = context_teidP;
|
||||
|
||||
if (hashtable_remove(gtpv1u_sgw_data.S1U_mapping, S1U_teidP) == HASH_TABLE_OK ) {
|
||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.status = 0;
|
||||
} else {
|
||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.status = -1;
|
||||
}
|
||||
|
||||
GTPU_DEBUG("Tx SGW_S1U_ENDPOINT_CREATED Context %u teid %u status %d\n", context_teidP, S1U_teidP, message_p->ittiMsg.gtpv1uDeleteTunnelResp.status);
|
||||
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
|
||||
|
||||
static int gtpv1u_update_s1u_tunnel(Gtpv1uUpdateTunnelReq *reqP)
|
||||
{
|
||||
hashtable_rc_t hash_rc;
|
||||
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info;
|
||||
MessageDef *message_p;
|
||||
|
||||
GTPU_DEBUG("Rx GTPV1U_UPDATE_TUNNEL_REQ Context %u, S-GW S1U teid %u, eNB S1U teid %u\n",
|
||||
reqP->context_teid,
|
||||
reqP->sgw_S1u_teid,
|
||||
reqP->enb_S1u_teid);
|
||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_UPDATE_TUNNEL_RESP);
|
||||
|
||||
hash_rc = hashtable_get(gtpv1u_sgw_data.S1U_mapping, reqP->sgw_S1u_teid, (void**)>pv1u_teid2enb_info);
|
||||
|
||||
if (hash_rc == HASH_TABLE_OK) {
|
||||
gtpv1u_teid2enb_info->teid_enb = reqP->enb_S1u_teid;
|
||||
gtpv1u_teid2enb_info->enb_ip_addr = reqP->enb_ip_address_for_S1u;
|
||||
gtpv1u_teid2enb_info->state = BEARER_UP;
|
||||
gtpv1u_teid2enb_info->port = GTPV1U_UDP_PORT;
|
||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.status = 0; ///< Status (Failed = 0xFF or Success = 0x0)
|
||||
} else {
|
||||
GTPU_ERROR("Mapping not found\n");
|
||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.status = 0xFF; ///< Status (Failed = 0xFF or Success = 0x0)
|
||||
}
|
||||
|
||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.context_teid = reqP->context_teid;
|
||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.sgw_S1u_teid = reqP->sgw_S1u_teid;
|
||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.enb_S1u_teid = reqP->enb_S1u_teid;
|
||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.eps_bearer_id = reqP->eps_bearer_id;
|
||||
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
|
||||
|
||||
static NwGtpv1uRcT gtpv1u_start_timer_wrapper(
|
||||
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||
uint32_t timeoutSec,
|
||||
uint32_t timeoutUsec,
|
||||
uint32_t tmrType,
|
||||
void *timeoutArg,
|
||||
NwGtpv1uTimerHandleT *hTmr)
|
||||
{
|
||||
|
||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||
long timer_id;
|
||||
|
||||
if (tmrType == NW_GTPV1U_TMR_TYPE_ONE_SHOT) {
|
||||
timer_setup(timeoutSec,
|
||||
timeoutUsec,
|
||||
TASK_GTPV1_U,
|
||||
INSTANCE_DEFAULT,
|
||||
TIMER_ONE_SHOT,
|
||||
timeoutArg,
|
||||
&timer_id);
|
||||
} else {
|
||||
timer_setup(timeoutSec,
|
||||
timeoutUsec,
|
||||
TASK_GTPV1_U,
|
||||
INSTANCE_DEFAULT,
|
||||
TIMER_PERIODIC,
|
||||
timeoutArg,
|
||||
&timer_id);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static NwGtpv1uRcT gtpv1u_stop_timer_wrapper(
|
||||
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||
NwGtpv1uTimerHandleT hTmr)
|
||||
{
|
||||
|
||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void *gtpv1u_thread(void *args)
|
||||
{
|
||||
itti_mark_task_ready(TASK_GTPV1_U);
|
||||
MSC_START_USE();
|
||||
|
||||
while(1) {
|
||||
/* Trying to fetch a message from the message queue.
|
||||
* If the queue is empty, this function will block till a
|
||||
* message is sent to the task.
|
||||
*/
|
||||
MessageDef *received_message_p = NULL;
|
||||
itti_receive_msg(TASK_GTPV1_U, &received_message_p);
|
||||
DevAssert(received_message_p != NULL);
|
||||
|
||||
|
||||
switch (ITTI_MSG_ID(received_message_p)) {
|
||||
|
||||
case TERMINATE_MESSAGE: {
|
||||
GTPU_WARN(" *** Exiting GTPU thread\n");
|
||||
itti_exit_task();
|
||||
}
|
||||
break;
|
||||
|
||||
// DATA COMING FROM UDP
|
||||
case UDP_DATA_IND: {
|
||||
udp_data_ind_t *udp_data_ind_p;
|
||||
udp_data_ind_p = &received_message_p->ittiMsg.udp_data_ind;
|
||||
nwGtpv1uProcessUdpReq(gtpv1u_sgw_data.gtpv1u_stack,
|
||||
udp_data_ind_p->buffer,
|
||||
udp_data_ind_p->buffer_length,
|
||||
udp_data_ind_p->peer_port,
|
||||
udp_data_ind_p->peer_address);
|
||||
//itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case TIMER_HAS_EXPIRED:
|
||||
nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg);
|
||||
break;
|
||||
|
||||
default: {
|
||||
GTPU_ERROR("Unkwnon message ID %d:%s\n",
|
||||
ITTI_MSG_ID(received_message_p),
|
||||
ITTI_MSG_NAME(received_message_p));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p);
|
||||
received_message_p = NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int gtpv1u_init(const mme_config_t *mme_config_p)
|
||||
{
|
||||
int ret = 0;
|
||||
NwGtpv1uRcT rc = 0;
|
||||
NwGtpv1uUlpEntityT ulp;
|
||||
NwGtpv1uUdpEntityT udp;
|
||||
NwGtpv1uLogMgrEntityT log;
|
||||
NwGtpv1uTimerMgrEntityT tmr;
|
||||
|
||||
GTPU_DEBUG("Initializing GTPV1U interface\n");
|
||||
|
||||
memset(>pv1u_sgw_data, 0, sizeof(gtpv1u_sgw_data));
|
||||
|
||||
gtpv1u_sgw_data.sgw_ip_address_for_S1u_S12_S4_up = mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up;
|
||||
|
||||
if (itti_create_task(TASK_GTPV1_U, >pv1u_thread, NULL) < 0) {
|
||||
GTPU_ERROR("gtpv1u phtread_create: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
GTPU_DEBUG("Initializing GTPV1U interface: DONE\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user