diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 67a803facec3d54be177631ab02f0ca5ed42daa1..149bf1ece04e3a29fccb492129d4f3d71b9cff8e 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -19,6 +19,9 @@ * contact@openairinterface.org */ +/* F1AP -> SCTP */ +MESSAGE_DEF(F1AP_CU_SCTP_REQ , MESSAGE_PRIORITY_MED, f1ap_cu_setup_req_t , f1ap_cu_setup_req) + /* eNB application layer -> F1AP messages */ MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index e2f01d895419da25f50bac3526cf2abf83793497..48870ee4788e26686673678ebddbdcd5d8569028 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -51,6 +51,10 @@ // Note this should be 512 from maxval in 38.473 #define F1AP_MAX_NB_CELLS 2 +typedef struct f1ap_cu_setup_req_s { + // +} f1ap_cu_setup_req_t; + typedef struct f1ap_setup_req_s { // Midhaul networking parameters @@ -67,6 +71,9 @@ typedef struct f1ap_setup_req_s { uint32_t gNB_DU_id; char *gNB_DU_name; + /* The type of the cell */ + enum cell_type_e cell_type; + /// number of DU cells available uint16_t num_cells_available; //0< num_cells_to_available <= 512; diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index cab95a532856b9b45624cb3865bc943abc12c85c..9e61e971c1a55e51cedaf4f44690685427dd5a69 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -128,8 +128,7 @@ static uint32_t eNB_app_register(ngran_node_t node_type,uint32_t enb_id_start, u msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ); RCconfig_DU_F1(msg_p, enb_id); - LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); - AssertFatal(1==0,"No ITTI ask for F1AP yet\n"); + LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); // configure GTPu here for F1U } @@ -213,12 +212,11 @@ void *eNB_app_task(void *args_p) LOG_I(ENB_APP, "%s() Creating RRC instance RC.rrc[%d]:%p (%d of %d)\n", __FUNCTION__, enb_id, RC.rrc[enb_id], enb_id+1, enb_id_end); memset((void *)RC.rrc[enb_id],0,sizeof(eNB_RRC_INST)); configure_rrc(enb_id); - + if (RC.nb_macrlc_inst >0 && mac_has_f1[enb_id]==1) RC.rrc[enb_id]->node_type = ngran_eNB_DU; else pdcp_layer_init(); } - # if defined(ENABLE_USE_MME) /* Try to register each eNB */ registered_enb = 0; diff --git a/openair2/F1AP/CU_F1AP.c b/openair2/F1AP/CU_F1AP.c index 641581c6af890a81180a9d055cae6866300a67e7..7551164caa891614b9a22ee227dc8b0865a4ac76 100644 --- a/openair2/F1AP/CU_F1AP.c +++ b/openair2/F1AP/CU_F1AP.c @@ -32,6 +32,7 @@ #include "conversions.h" #include "f1ap_common.h" +#include "cu_f1ap_defs.h" #include "f1ap_encoder.h" #include "f1ap_decoder.h" #include "sctp_cu.h" @@ -39,8 +40,13 @@ #include "common/utils/LOG/log.h" #include "intertask_interface.h" +#include "T.h" + #define MAX_F1AP_BUFFER_SIZE 4096 +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + /* This structure describes association of a DU to a CU */ typedef struct f1ap_info { @@ -87,8 +93,7 @@ uint8_t F1AP_get_next_transaction_identifier(module_id_t enb_mod_idP, module_id_ // ============================================================================== static -void CU_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) -{ +void CU_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { int result; DevAssert(sctp_data_ind != NULL); @@ -100,6 +105,30 @@ void CU_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } +void CU_send_sctp_init_req(instance_t enb_id) { + // 1. get the itti msg, and retrive the enb_id from the message + // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port + // 3. creat an itti message to init + + MessageDef *message_p = NULL; + + message_p = itti_alloc_new_message (TASK_CU_F1, SCTP_INIT_MSG); + message_p->ittiMsg.sctp_init.port = RC.rrc[enb_id]->eth_params_s.my_portc; + message_p->ittiMsg.sctp_init.ppid = F1AP_SCTP_PPID; + message_p->ittiMsg.sctp_init.ipv4 = 1; + message_p->ittiMsg.sctp_init.ipv6 = 0; + message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; + message_p->ittiMsg.sctp_init.ipv4_address[0] = RC.rrc[enb_id]->eth_params_s.my_addr; + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; + message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + + itti_send_msg_to_task(TASK_SCTP, enb_id, message_p); +} + void *F1AP_CU_task(void *arg) { printf("Start F1AP CU task!\n"); @@ -117,12 +146,9 @@ void *F1AP_CU_task(void *arg) { while (1) { switch (ITTI_MSG_ID(received_msg)) { - //case F1AP_CU_SCTP_REQ: // this is not a true F1 message, but rather an ITTI message sent by enb_app - // 1. save the itti msg so that you can use it to sen f1ap_setup_req - // 2. send a sctp_init req - // CU_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), - // &F1AP_SETUP_REQ(received_msg)); - // break; + case F1AP_CU_SCTP_REQ: + CU_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + break; case SCTP_DATA_IND: CU_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); diff --git a/openair2/F1AP/DU_F1AP.c b/openair2/F1AP/DU_F1AP.c index 5653d1560815671d105f999db67c62009f32cb67..8dc1f1019801714727c20c782910b6ee31e8cd41 100644 --- a/openair2/F1AP/DU_F1AP.c +++ b/openair2/F1AP/DU_F1AP.c @@ -32,17 +32,24 @@ #include "conversions.h" #include "f1ap_common.h" +#include "du_f1ap_defs.h" #include "platform_types.h" #include "common/utils/LOG/log.h" #include "sctp_du.h" #include "intertask_interface.h" +#include "T.h" + +// helper functions +#define F1AP_TRANSACTION_IDENTIFIER_NUMBER 3 +#define F1AP_UE_IDENTIFIER_NUMBER 3 +#define NUMBER_OF_eNB_MAX 3 /* This structure describes association of a DU to a CU */ typedef struct f1ap_info { module_id_t enb_mod_idP; - module_id_t du_mod_idP; + module_id_t cu_mod_idP; /* Unique eNB_id to identify the eNB within EPC. * In our case the eNB is a macro eNB so the id will be 20 bits long. @@ -71,11 +78,6 @@ typedef struct f1ap_info { } f1ap_info_t; -// helper functions -#define F1AP_TRANSACTION_IDENTIFIER_NUMBER 3 -#define F1AP_UE_IDENTIFIER_NUMBER 3 -#define NUMBER_OF_eNB_MAX 3 - void DU_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); @@ -122,6 +124,7 @@ void *F1AP_DU_task(void *arg) { itti_mark_task_ready(TASK_DU_F1); + // SCTP while (1) { switch (ITTI_MSG_ID(received_msg)) { @@ -130,12 +133,13 @@ void *F1AP_DU_task(void *arg) { // itti_exit_task(); // break; - //case F1AP_SETUP_REQ: // this is not a true F1 message, but rather an ITTI message sent by enb_app - // 1. save the itti msg so that you can use it to sen f1ap_setup_req + case F1AP_SETUP_REQ: // this is not a true F1 message, but rather an ITTI message sent by enb_app + // 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message, + // 2. store the message in f1ap context, that is also stored in RC // 2. send a sctp_association req - // DU_send_sctp_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), - // &F1AP_SETUP_REQ(received_msg)); - // break; + DU_send_sctp_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &F1AP_SETUP_REQ(received_msg)); + break; case SCTP_NEW_ASSOCIATION_RESP: // 1. store the respon @@ -145,6 +149,7 @@ void *F1AP_DU_task(void *arg) { break; case SCTP_DATA_IND: + // ex: any F1 incoming message for DU ends here DU_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); break; @@ -164,16 +169,73 @@ void *F1AP_DU_task(void *arg) { // ============================================================================== -void DU_send_sctp_association_req(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) +static void du_f1ap_register(du_f1ap_instance_t *instance_p, + char *cu_ip_address, + int cu_port, + uint16_t in_streams, + uint16_t out_streams) { - // - AssertFatal(0,"Not implemented yet\n"); + + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); + + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + + sctp_new_association_req_p->port = cu_port; + sctp_new_association_req_p->ppid = F1AP_SCTP_PPID; + + sctp_new_association_req_p->in_streams = in_streams; + sctp_new_association_req_p->out_streams = out_streams; + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); } -void DU_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) -{ - // - AssertFatal(0,"Not implemented yet\n"); +void DU_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1ap_setup_req) { + du_f1ap_instance_t *new_instance; + //uint8_t index; + + DevAssert(f1ap_setup_req != NULL); + + /* Look if the provided instance already exists */ + //new_instance = s1ap_eNB_get_instance(instance); + + // @Todo + // if (new_instance != NULL) { + // /* Checks if it is a retry on the same eNB */ + // DevCheck(new_instance->gNB_DU_id == f1ap_setup_req->gNB_DU_id, new_instance->gNB_DU_id, f1ap_setup_req->gNB_DU_id, 0); + // DevCheck(new_instance->cell_type == f1ap_setup_req->cell_type, new_instance->cell_type, f1ap_setup_req->cell_type, 0); + // DevCheck(new_instance->tac == f1ap_setup_req->tac, new_instance->tac, f1ap_setup_req->tac, 0); + // DevCheck(new_instance->mcc == f1ap_setup_req->mcc, new_instance->mcc, f1ap_setup_req->mcc, 0); + // DevCheck(new_instance->mnc == f1ap_setup_req->mnc, new_instance->mnc, f1ap_setup_req->mnc, 0); + // DevCheck(new_instance->mnc_digit_length == f1ap_setup_req->mnc_digit_length, new_instance->mnc_digit_length, f1ap_setup_req->mnc_digit_length, 0); + // DevCheck(new_instance->default_drx == f1ap_setup_req->default_drx, new_instance->default_drx, f1ap_setup_req->default_drx, 0); + // } else { + new_instance = calloc(1, sizeof(du_f1ap_instance_t)); + DevAssert(new_instance != NULL); + + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->gNB_DU_id = f1ap_setup_req->gNB_DU_id; + new_instance->gNB_DU_name = f1ap_setup_req->gNB_DU_name; + new_instance->tac = f1ap_setup_req->tac[0]; + new_instance->mcc = f1ap_setup_req->mcc[0]; + new_instance->mnc = f1ap_setup_req->mnc[0]; + new_instance->mnc_digit_length = f1ap_setup_req->mnc_digit_length; + + //} + + du_f1ap_register(new_instance, + &f1ap_setup_req->CU_ipv4_address, + &f1ap_setup_req->CU_port, + f1ap_setup_req->sctp_in_streams, + f1ap_setup_req->sctp_out_streams); + +} + +void DU_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + DU_send_F1_SETUP_REQUEST(instance, sctp_new_association_resp); } @@ -181,7 +243,7 @@ void DU_handle_sctp_association_resp(instance_t instance, sctp_new_association_r // SETUP REQUEST -void DU_send_F1_SETUP_REQUEST(module_id_t enb_mod_idP, module_id_t du_mod_idP) { +void DU_send_F1_SETUP_REQUEST(module_id_t enb_mod_idP, module_id_t du_mod_idP, f1ap_setup_req_t *msg_p) { //void DU_send_F1_SETUP_REQUEST(F1SetupRequest_t *F1SetupRequest) { F1AP_F1AP_PDU_t pdu; F1AP_F1SetupRequest_t *out; @@ -590,8 +652,9 @@ int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length) { // SETUP SUCCESSFUL -void DU_handle_F1_SETUP_RESPONSE(struct F1AP_F1AP_PDU_t *pdu_p) { - +void DU_handle_F1_SETUP_RESPONSE() { + + AssertFatal(0,"Not implemented yet\n"); /* decode */ //DU_F1AP_decode(args_p); diff --git a/openair2/F1AP/cu_f1ap_defs.h b/openair2/F1AP/cu_f1ap_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..0f8a1e8353527337edda0b9b90f43f37438803c1 --- /dev/null +++ b/openair2/F1AP/cu_f1ap_defs.h @@ -0,0 +1,63 @@ +/* + * 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 + */ + +#include <stdint.h> + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#ifndef CU_F1AP_DEFS_H_ +#define CU_F1AP_DEFS_H_ + +struct cu_f1ap_instance_s; +typedef struct du_f1ap_instance_s { + /* Next f1ap du association. + * Only used for virtual mode. + */ + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + // F1_Setup_Req payload + uint32_t gNB_CU_id; + char *gNB_CU_name; + + /* Unique eNB_id to identify the eNB within EPC. + * In our case the eNB is a macro eNB so the id will be 20 bits long. + * For Home eNB id, this field should be 28 bits long. + */ + uint32_t eNB_id; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + +} cu_f1ap_instance_t; + +#endif /* CU_F1AP_DEFS_H_ */ diff --git a/openair2/F1AP/du_f1ap_defs.h b/openair2/F1AP/du_f1ap_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..a93591106f5e7981802e55709ab1c201828ab003 --- /dev/null +++ b/openair2/F1AP/du_f1ap_defs.h @@ -0,0 +1,63 @@ +/* + * 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 + */ + +#include <stdint.h> + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#ifndef DU_F1AP_DEFS_H_ +#define DU_F1AP_DEFS_H_ + +struct du_f1ap_instance_s; +typedef struct du_f1ap_instance_s { + /* Next f1ap du association. + * Only used for virtual mode. + */ + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + // F1_Setup_Req payload + uint32_t gNB_DU_id; + char *gNB_DU_name; + + /* Unique eNB_id to identify the eNB within EPC. + * In our case the eNB is a macro eNB so the id will be 20 bits long. + * For Home eNB id, this field should be 28 bits long. + */ + uint32_t eNB_id; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + +} du_f1ap_instance_t; + +#endif /* DU_F1AP_DEFS_H_ */