diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index a91e7918a9..abf10ee0fe 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -182,6 +182,7 @@ extern void reset_opp_meas(void); extern void print_opp_meas(void); extern void init_eNB_afterRU(void); +extern void *udp_eNB_task(void *args_p); int transmission_mode=1; int emulate_rf = 0; @@ -389,10 +390,10 @@ int create_gNB_tasks(uint32_t gnb_nb) { if (gnb_nb > 0) { /* Last task to create, others task must be ready before its start */ - if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + /*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { LOG_E(GNB_APP, "Create task for gNB APP failed\n"); return -1; - } + }*/ if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){ LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; @@ -407,10 +408,10 @@ int create_gNB_tasks(uint32_t gnb_nb) { } } - /* + if (EPC_MODE_ENABLED) { if (gnb_nb > 0) { - if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { + /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; } @@ -418,7 +419,7 @@ int create_gNB_tasks(uint32_t gnb_nb) { if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { LOG_E(S1AP, "Create task for S1AP failed\n"); return -1; - } + }*/ if(!emulate_rf){ if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { LOG_E(UDP_, "Create task for UDP failed\n"); @@ -430,12 +431,17 @@ int create_gNB_tasks(uint32_t gnb_nb) { LOG_E(GTPU, "Create task for GTPV1U failed\n"); return -1; } + } } - */ + if (gnb_nb > 0) { + if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { @@ -830,6 +836,7 @@ int main( int argc, char **argv ) } openair0_cfg[0].threequarter_fs = threequarter_fs; + EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; #if T_TRACER T_Config_Init(); diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h index 57201721ce..5e5794fc55 100644 --- a/openair2/COMMON/s1ap_messages_def.h +++ b/openair2/COMMON/s1ap_messages_def.h @@ -66,6 +66,7 @@ MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_m MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp) MESSAGE_DEF(S1AP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_t , s1ap_path_switch_req) MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_ack_t , s1ap_path_switch_req_ack) +MESSAGE_DEF(S1AP_E_RAB_MODIFICATION_IND , MESSAGE_PRIORITY_MED, s1ap_e_rab_modification_ind_t , s1ap_e_rab_modification_ind) /* S1AP -> RRC messages */ MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas ) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index aa718dbcf8..7225ae31b3 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -45,6 +45,7 @@ #define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp #define S1AP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req #define S1AP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req_ack +#define S1AP_E_RAB_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modification_ind #define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas #define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req @@ -281,12 +282,26 @@ typedef struct e_rab_tobe_added_s { uint8_t drb_ID; /* The transport layer address for the IP packets */ - transport_layer_addr_t eNB_addr; + transport_layer_addr_t sgw_addr; /* S-GW Tunnel endpoint identifier */ uint32_t gtp_teid; } e_rab_tobe_added_t; +typedef struct e_rab_admitted_tobe_added_s { + /* Unique e_rab_id for the UE. */ + uint8_t e_rab_id; + + /* Unique drb_ID for the UE. */ + uint8_t drb_ID; + + /* The transport layer address for the IP packets */ + transport_layer_addr_t gnb_addr; + + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} e_rab_admitted_tobe_added_t; + typedef struct e_rab_tobeswitched_s { @@ -646,6 +661,27 @@ typedef struct s1ap_path_switch_req_ack_s { } s1ap_path_switch_req_ack_t; +typedef struct s1ap_e_rab_modification_ind_s { + + unsigned eNB_ue_s1ap_id:24; + + /* MME UE id */ + uint32_t mme_ue_s1ap_id; + + /* Number of e_rab setup-ed in the list */ + uint8_t nb_of_e_rabs_tobemodified; + + uint8_t nb_of_e_rabs_nottobemodified; + + /* list of e_rab setup-ed by RRC layers */ + e_rab_setup_t e_rabs_tobemodified[S1AP_MAX_E_RAB]; + + e_rab_setup_t e_rabs_nottobemodified[S1AP_MAX_E_RAB]; + + uint16_t ue_initial_id; + +} s1ap_e_rab_modification_ind_t; + // S1AP --> RRC messages typedef struct s1ap_ue_release_command_s { diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index ed3470a7d6..38b3b7d653 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -363,7 +363,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { uint8_t nb_e_rabs_admitted_tobeadded; /* list of e_rab to be added by RRC layers */ - e_rab_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB]; + e_rab_admitted_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ e_rab_t e_rab_param[S1AP_MAX_E_RAB]; diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index f11e302771..821174deda 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -71,7 +71,7 @@ static void configure_nr_rrc(uint32_t gnb_id) /*------------------------------------------------------------------------------*/ -/* + static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties) { uint32_t gnb_id; @@ -83,18 +83,18 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse // note: there is an implicit relationship between the data structure and the message name - msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse + /*msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse - RCconfig_NR_S1(msg_p, gnb_id); + RCconfig_NR_S1(msg_p, gnb_id);*/ if (gnb_id == 0) RCconfig_nr_gtpu(); - s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse - LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx); + /*s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse + LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);*/ LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id)); - itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); + //itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); register_gnb_pending++; } @@ -102,7 +102,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, return register_gnb_pending; } -*/ + /*------------------------------------------------------------------------------*/ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) { @@ -132,6 +132,7 @@ void *gNB_app_task(void *args_p) uint32_t gnb_id_start = 0; uint32_t gnb_id_end = gnb_id_start + gnb_nb; uint32_t x2_register_gnb_pending = 0; + uint32_t register_gnb_pending=0; uint32_t gnb_id; MessageDef *msg_p = NULL; const char *msg_name = NULL; @@ -176,7 +177,7 @@ void *gNB_app_task(void *args_p) if (EPC_MODE_ENABLED) { /* Try to register each gNB */ //registered_gnb = 0; - //register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p); + register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p); } else { /* Start L2L1 task */ msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE); diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index f050733a13..52b06b9f11 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -382,6 +382,7 @@ typedef enum e_rab_satus_e { E_RAB_STATUS_DONE, // from the eNB perspective E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE E_RAB_STATUS_REESTABLISHED, // after HO + E_RAB_STATUS_TOMODIFY, // ENDC NSA E_RAB_STATUS_FAILED, E_RAB_STATUS_TORELEASE // to release DRB between eNB and UE } e_rab_status_t; @@ -613,6 +614,7 @@ typedef struct eNB_RRC_UE_s { /* Number of e_rab to be modified in the list */ uint8_t nb_of_modify_e_rabs; uint8_t nb_of_failed_e_rabs; + uint8_t nb_of_modify_endc_e_rabs; e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; @@ -627,6 +629,10 @@ typedef struct eNB_RRC_UE_s { uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + // LG: For GTPV1 TUNNELS ENDC + uint32_t gnb_gtp_endc_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t gnb_gtp_endc_addrs[S1AP_MAX_E_RAB]; + rb_id_t gnb_gtp_endc_ebi[S1AP_MAX_E_RAB]; /* Total number of e_rab already setup in the list */ uint8_t nb_x2u_e_rabs; // LG: For GTPV1 TUNNELS(X2U) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index aafd1cbf6f..b8bbb55a82 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4372,6 +4372,16 @@ rrc_eNB_process_MeasurementReport( msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ); X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; + //For the moment we have a single E-RAB which will be the one to be added to the gNB + //Not sure how to select bearers to be added if there are multiple. + X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; + for (int e_rab=0; i< X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded; e_rab++){ + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].gtp_teid = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid; + memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].sgw_addr, + &ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr, + sizeof(transport_layer_addr_t)); + } LOG_I(RRC, "[eNB %d] frame %d subframe %d: UE rnti %x switching to NSA mode\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rnti); @@ -7493,6 +7503,16 @@ rrc_eNB_decode_dcch( } ue_context_p->ue_context.reestablishment_xid = -1; + + //Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete + //including NR specific elements. Not sure if this is the correct one and the correct placement + if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + scg_ConfigResponseNR_r15->buf!=NULL){ + /*Trigger E-RAB Modification Indication */ + rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p); + } + } else { dedicated_DRB = 1; ue_context_p->ue_context.Status = RRC_RECONFIGURED; @@ -8527,6 +8547,27 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, ue_context = (rrc_eNB_ue_context_t *) get_first_ue_context(RC.rrc[enb_mod_idP]); + ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded; + + int j=0; + while(j < m->nb_e_rabs_admitted_tobeadded){ + for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++){ + //Update ue_context information with gNB's address and new GTP tunnel ID + if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id){ + memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.length); + ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length; + ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid; + ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY; + break; + } + } + j++; + } + + + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, ENB_FLAG_YES, diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 11c6d27f5f..d2e3d4999f 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -2283,3 +2283,77 @@ int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id) }*/ return 0; } + + +int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP) { + MessageDef *msg_p = NULL; + int e_rab = 0; + int e_rab_modify_index = 0; + int e_rab_notmodify_index = 0; + rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL; + hashtable_rc_t h_rc; + + uint8_t inde_list[ue_context_pP->ue_context.nb_of_e_rabs]; + memset(inde_list, 0, ue_context_pP->ue_context.nb_of_e_rabs*sizeof(uint8_t)); + + msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFICATION_IND); + + + S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; + S1AP_E_RAB_MODIFICATION_IND (msg_p).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id; + + LOG_I (RRC,"E-RAB modification indication: nb nb_of_e_rabs %u status %u\n", + ue_context_pP->ue_context.nb_of_e_rabs, + ue_context_pP->ue_context.e_rab[e_rab].status); + + if (ue_context_pP->ue_context.nb_of_modify_endc_e_rabs > 0){ + S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified = ue_context_pP->ue_context.nb_of_modify_endc_e_rabs; + for (e_rab = 0; e_rab < ue_context_pP->ue_context.setup_e_rabs ; e_rab++) { + //Add E-RAB in the list of E-RABs to be modified + if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_TOMODIFY) { + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length); + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length; + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab]; + e_rab_modify_index++; + } + //Add E-RAB in the list of E-RABs NOT to be modified + else{ + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length); + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length; + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab]; + e_rab_notmodify_index++; + } + } + S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_nottobemodified = e_rab_notmodify_index; + } + + if (e_rab_modify_index > 0) { + LOG_I(RRC,"S1AP_E_RAB_MODIFICATION_IND: sending the message: nb_of_erabstobemodified %d, total e_rabs %d, index %d\n", + S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified, ue_context_pP->ue_context.setup_e_rabs, e_rab); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_S1AP_ENB, + (const char *)&S1AP_E_RAB_MODIFICATION_IND (msg_p), + sizeof(s1ap_e_rab_modification_ind_t), + MSC_AS_TIME_FMT" E RAB MODIFICATION IND UE %X eNB_ue_s1ap_id %u e_rabs:%u succ", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_id_rnti, + S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id, + e_rab_modify_index); + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); + } else { + itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + } + + return 0; +} + + + diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h index e5ff9c27d6..a55d17bfd1 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.h +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h @@ -285,4 +285,6 @@ int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, r int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id); +int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP); + #endif /* RRC_ENB_S1AP_H_ */ diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 1e4b1be054..eb04b0240f 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -65,9 +65,9 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP); -void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList); +void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m); -void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p); +void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m); void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CellGroupConfig_t *secondaryCellGroup, @@ -89,7 +89,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc, NR_RRCReconfiguration_t *reconfig, NR_RadioBearerConfig_t *rbconfig); -int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo); +int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3abb7e191e..4f1f9287bc 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -245,13 +245,13 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo, (const char *)buffer, (enc_rval.encoded+7)>>3); - parse_CG_ConfigInfo(rrc,CG_ConfigInfo); + parse_CG_ConfigInfo(rrc,CG_ConfigInfo,NULL); } else { struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc); LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); - rrc_add_nsa_user(rrc,ue_context_p); + rrc_add_nsa_user(rrc,ue_context_p,NULL); } } } @@ -311,12 +311,6 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x (uint8_t *)m->rrc_buffer, (int) m->rrc_buffer_size);//m->rrc_buffer_size); -/* asn_dec_rval_t dec_rval = uper_decode( NULL, - &asn_DEF_LTE_UL_DCCH_Message, - (void **)<E_UL_DCCH_Message, - (uint8_t *)m->rrc_buffer, - (int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size); -*/ gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { @@ -342,7 +336,7 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo, (const char *)m->rrc_buffer, (enc_rval.encoded+7)>>3); - parse_CG_ConfigInfo(rrc,CG_ConfigInfo); + parse_CG_ConfigInfo(rrc,CG_ConfigInfo,m); } diff --git a/openair2/RRC/NR/rrc_gNB_internode.c b/openair2/RRC/NR/rrc_gNB_internode.c index 581015db56..916f4d63da 100644 --- a/openair2/RRC/NR/rrc_gNB_internode.c +++ b/openair2/RRC/NR/rrc_gNB_internode.c @@ -38,7 +38,7 @@ #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" -int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) { +int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m) { if (CG_ConfigInfo->criticalExtensions.present == NR_CG_ConfigInfo__criticalExtensions_PR_c1) { if (CG_ConfigInfo->criticalExtensions.choice.c1) { @@ -56,7 +56,7 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) { AssertFatal(1==0,"[InterNode] Failed to decode NR_UE_CapabilityRAT_ContainerList (%zu bits), size of OCTET_STRING %lu\n", dec_rval.consumed, cg_ConfigInfo->ue_CapabilityInfo->size); } - rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList); + rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList, m); } if (cg_ConfigInfo->candidateCellInfoListMN) AssertFatal(1==0,"Can't handle candidateCellInfoListMN yet\n"); } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 18fc3d7e7c..d70bbed189 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -37,8 +37,9 @@ #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" -void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList) { +void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m) { struct rrc_gNB_ue_context_s *ue_context_p = NULL; OCTET_STRING_t *ueCapabilityRAT_Container_nr; @@ -94,10 +95,10 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerL xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); } - rrc_add_nsa_user(rrc,ue_context_p); + rrc_add_nsa_user(rrc,ue_context_p, m); } -void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p) { +void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) { // generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331) @@ -105,6 +106,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ MessageDef *msg; msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); + gtpv1u_enb_create_tunnel_req_t create_tunnel_req; + gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; + uint8_t inde_list[m->nb_e_rabs_tobeadded]; + memset(inde_list, 0, m->nb_e_rabs_tobeadded*sizeof(uint8_t)); + protocol_ctxt_t *ctxt = NULL; // NR RRCReconfiguration @@ -133,6 +139,45 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ //int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + if(m!=NULL){ + if (m->nb_e_rabs_tobeadded>0){ + for (int i=0; inb_e_rabs_tobeadded; i++){ + // Add the new E-RABs at the corresponding rrc ue context of the gNB + ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id; + ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid; + memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t)); + ue_context_p->ue_context.nb_of_e_rabs++; + //Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW + create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id; + create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid; + memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t)); + inde_list[i] = i; + } + //PM: Is this where we should extract the rnti from? + create_tunnel_req.rnti = ue_context_p->ue_id_rnti; + create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded; + PROTOCOL_CTXT_SET_BY_MODULE_ID(ctxt, rrc->module_id, GNB_FLAG_YES, NOT_A_RNTI, 0, 0,rrc->module_id); + gtpv1u_create_s1u_tunnel( + ctxt->instance, + &create_tunnel_req, + &create_tunnel_resp); + rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( + ctxt, + &create_tunnel_resp, + &inde_list[0]); + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded; + + for(int i=0; iue_context.nb_of_e_rabs; i++){ + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id; + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i]; + memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t)); + } + } + else + LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n"); + } + + //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size // Send to X2 entity to transport to MeNB asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index b297c96e56..debe5e0712 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -359,7 +359,7 @@ void x2ap_eNB_handle_sctp_init_msg_multi_cnf( * Failure means multi_sd < 0. */ if (instance->multi_sd < 0) { - X2AP_ERROR("Error: be sure to properly configure X2 in your configuration file.\n"); + X2AP_ERROR("Error: be sure to properly configure X22 in your configuration file.\n"); DevAssert(instance->multi_sd >= 0); } @@ -474,7 +474,7 @@ void x2ap_eNB_handle_sgNB_add_req(instance_t instance, x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1); x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE); - x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data, ue_id); + x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data, ue_id); } static diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 47a3475063..c5cc84c21c 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1496,7 +1496,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response( } int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( - x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id) + x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id) { X2AP_X2AP_PDU_t pdu; X2AP_SgNBAdditionRequest_t *out; @@ -1527,9 +1527,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY; e_rab_tobe_added_t e_MCG_rabs_tobeadded; e_MCG_rabs_tobeadded.gtp_teid = 0; - e_MCG_rabs_tobeadded.eNB_addr.length = 24; + e_MCG_rabs_tobeadded.sgw_addr.length = 24; uint8_t buf[20] = { 0 }; - memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t)); + memcpy(e_MCG_rabs_tobeadded.sgw_addr.buffer, buf, 20*sizeof(uint8_t)); FILE *fd; fd = fopen("../../../executables/uecap.raw","r"); @@ -1614,8 +1614,8 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item; e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item; { - e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID; - e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID; + e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].drb_ID; + e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].e_rab_id; e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB; e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources; e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources; @@ -1628,14 +1628,14 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = priority_level; //Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case - INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID); - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = e_MCG_rabs_tobeadded.eNB_addr.length/8; - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_MCG_rabs_tobeadded.eNB_addr.length%8; + INT32_TO_OCTET_STRING(x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID); + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length/8; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length%8; e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf = calloc(1, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); memcpy (e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf, - e_MCG_rabs_tobeadded.eNB_addr.buffer, + x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.buffer, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); } @@ -1748,21 +1748,21 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item = &e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; { - e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].e_rab_id; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources; if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent; - INT32_TO_OCTET_STRING(e_SCG_rabs_tobeadded.gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID); + INT32_TO_OCTET_STRING(x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID); e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = e_SCG_rabs_tobeadded.eNB_addr.length/8; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_SCG_rabs_tobeadded.eNB_addr.length%8; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf = calloc(1, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); memcpy (e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf, - e_SCG_rabs_tobeadded.eNB_addr.buffer, + x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.buffer, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); } diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 114ed84a68..3dfccc0e52 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -70,7 +70,7 @@ int x2ap_gNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2a int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); -int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id); +int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id); int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index b7a9b70596..3dfc297ed6 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1749,11 +1749,11 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; - memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.buffer, + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); - X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.length = + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.length = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; OCTET_STRING_TO_INT32(&e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID, @@ -1891,10 +1891,10 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->e_RAB_ID ; if(e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ - memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.buffer, + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer, e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf, e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.length = + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; OCTET_STRING_TO_INT32(&e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID, @@ -1964,7 +1964,7 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead + //Allocate an ITTI X2AP_sGNB_reconfiguration_complete message msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE); /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 3592cf80a1..c228034245 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -69,7 +69,6 @@ s1ap_eNB_config_t s1ap_config; static int s1ap_eNB_generate_s1_setup_request( s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p); - void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB); void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); @@ -361,6 +360,12 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { } break; + case S1AP_E_RAB_MODIFICATION_IND: { + s1ap_eNB_generate_E_RAB_Modification_Indication(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &S1AP_E_RAB_MODIFICATION_IND(received_msg)); + } + break; + case S1AP_UE_CONTEXT_RELEASE_COMPLETE: { s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), &S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); @@ -508,3 +513,7 @@ static int s1ap_eNB_generate_s1_setup_request( s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0); return ret; } + + + + diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 87abc1ede9..28ee11187e 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -104,6 +104,11 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_ uint32_t stream, S1AP_S1AP_PDU_t *pdu); +static +int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here */ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* HandoverPreparation */ @@ -154,6 +159,9 @@ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* UplinkUEAssociatedLPPaTransport */ { 0, 0, 0 }, /* DownlinkNonUEAssociatedLPPaTransport */ { 0, 0, 0 }, /* UplinkNonUEAssociatedLPPaTransport */ + { 0, 0, 0 }, /* UERadioCapabilityMatch */ + { 0, 0, 0 }, /* PWSRestartIndication */ + { 0, s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm, 0 }, /* E_RABModificationIndication */ }; char *s1ap_direction2String(int s1ap_dir) { static char *s1ap_direction_String[] = { @@ -1722,3 +1730,13 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_ // TODO continue return 0; } + +static +int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu){ + + LOG_W(S1AP, "Implementation of S1AP E-RAB Modification confirm handler is pending...\n"); + return 0; +} + diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index d271ddf6ba..4877609754 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -1620,3 +1620,146 @@ int s1ap_eNB_path_switch_req(instance_t instance, return ret; } + + +//----------------------------------------------------------------------------- +/* +* eNB generate a S1 E_RAB Modification Indication towards MME +*/ +int s1ap_eNB_generate_E_RAB_Modification_Indication( + instance_t instance, + s1ap_e_rab_modification_ind_t *e_rab_modification_ind) +//----------------------------------------------------------------------------- +{ + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_E_RABModificationIndication_t *out = NULL; + S1AP_E_RABModificationIndicationIEs_t *ie = NULL; + S1AP_E_RABToBeModifiedItemBearerModInd_t *E_RAB_ToBeModifiedItem_BearerModInd = NULL; + S1AP_E_RABToBeModifiedItemBearerModIndIEs_t *E_RAB_ToBeModifiedItem_BearerModInd_IEs = NULL; + + S1AP_E_RABNotToBeModifiedItemBearerModInd_t *E_RAB_NotToBeModifiedItem_BearerModInd = NULL; + S1AP_E_RABNotToBeModifiedItemBearerModIndIEs_t *E_RAB_NotToBeModifiedItem_BearerModInd_IEs = NULL; + + + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + uint8_t *buffer = NULL; + uint32_t len = 0; + int ret = 0; + DevAssert(s1ap_eNB_instance_p != NULL); + DevAssert(e_rab_modification_ind != NULL); + + int num_e_rabs_tobemodified = e_rab_modification_ind->nb_of_e_rabs_tobemodified; + int num_e_rabs_nottobemodified = e_rab_modification_ind->nb_of_e_rabs_nottobemodified; + + uint32_t CSG_id = 0; + + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_E_RABModificationIndication; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_E_RABModificationIndication; + out = &pdu.choice.initiatingMessage.value.choice.E_RABModificationIndication; + /* mandatory */ + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = e_rab_modification_ind->mme_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = e_rab_modification_ind->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //E-RABs to be modified list + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModInd; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABToBeModifiedListBearerModInd; + + //The following two for-loops here will probably need to change. We should do a different type of search + for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedItemBearerModInd; + E_RAB_ToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject; + E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABToBeModifiedItemBearerModIndIEs__value_PR_E_RABToBeModifiedItemBearerModInd; + E_RAB_ToBeModifiedItem_BearerModInd = &E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABToBeModifiedItemBearerModInd; + + { + E_RAB_ToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_tobemodified[i].e_rab_id; + + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length/8; + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length%8; + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf = calloc(1, E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size); + memcpy (E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.buffer, + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size); + + INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_tobemodified[i].gtp_teid, &E_RAB_ToBeModifiedItem_BearerModInd->dL_GTP_TEID); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABToBeModifiedListBearerModInd.list, E_RAB_ToBeModifiedItem_BearerModInd_IEs); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //E-RABs NOT to be modified list + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedListBearerModInd; + ie->criticality = S1AP_Criticality_reject; + if(num_e_rabs_nottobemodified > 0) { + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd; + + for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedItemBearerModInd; + E_RAB_NotToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject; + E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABNotToBeModifiedItemBearerModIndIEs__value_PR_E_RABNotToBeModifiedItemBearerModInd; + E_RAB_NotToBeModifiedItem_BearerModInd = &E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABNotToBeModifiedItemBearerModInd; + + { + E_RAB_NotToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_nottobemodified[i].e_rab_id; + + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.length/8; + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.length%8; + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf = + calloc(1, E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size); + memcpy (E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.buffer, + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size); + + INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_nottobemodified[i].gtp_teid, &E_RAB_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list, E_RAB_NotToBeModifiedItem_BearerModInd_IEs); + } + } + else + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_NOTHING; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CSGMembershipInfo; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_CSGMembershipInfo; + ie->value.choice.CSGMembershipInfo.cSGMembershipStatus = S1AP_CSGMembershipStatus_member; + INT32_TO_BIT_STRING(CSG_id, &ie->value.choice.CSGMembershipInfo.cSG_Id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + S1AP_ERROR("Failed to encode S1 setup request\n"); + return -1; + } + + /* Non UE-Associated signalling -> stream = 0 */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, len, 0); + return ret; +} + + diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.h b/openair3/S1AP/s1ap_eNB_nas_procedures.h index c425719872..47f71cc795 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.h +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.h @@ -52,4 +52,8 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, int s1ap_eNB_path_switch_req(instance_t instance, s1ap_path_switch_req_t *path_switch_req_p); + +int s1ap_eNB_generate_E_RAB_Modification_Indication( + instance_t instance, s1ap_e_rab_modification_ind_t *e_rab_modification_ind); + #endif /* S1AP_ENB_NAS_PROCEDURES_H_ */ diff --git a/targets/COMMON/create_nr_tasks.c b/targets/COMMON/create_nr_tasks.c index 24c4115980..13f72b3876 100644 --- a/targets/COMMON/create_nr_tasks.c +++ b/targets/COMMON/create_nr_tasks.c @@ -51,17 +51,17 @@ int create_gNB_tasks(uint32_t gnb_nb) } if (gnb_nb > 0) { - /* Last task to create, others task must be ready before its start */ + // Last task to create, others task must be ready before its start if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { LOG_E(GNB_APP, "Create task for gNB APP failed\n"); return -1; } } -/* + if (EPC_MODE_ENABLED) { if (gnb_nb > 0) { - if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { + /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; } @@ -69,7 +69,7 @@ int create_gNB_tasks(uint32_t gnb_nb) if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { LOG_E(S1AP, "Create task for S1AP failed\n"); return -1; - } + }*/ if(!emulate_rf){ if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { LOG_E(UDP_, "Create task for UDP failed\n"); @@ -84,7 +84,15 @@ int create_gNB_tasks(uint32_t gnb_nb) } } -*/ + + /*if (gnb_nb > 0) { + // Last task to create, others task must be ready before its start + if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } + }*/ + if (gnb_nb > 0) { LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); @@ -100,4 +108,4 @@ int create_gNB_tasks(uint32_t gnb_nb) return 0; } -#endif +//#endif