Commit 6e2f63bf authored by Xue Song's avatar Xue Song

Add rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND and...

Add rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND and rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE
parent 7034159e
......@@ -30,4 +30,7 @@ MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_dat
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq)
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req)
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_req_t, NRGtpv1uDeleteTunnelReq)
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_resp_t, NRGtpv1uDeleteTunnelResp)
MESSAGE_DEF(GTPV1U_GNB_NG_REQ, MESSAGE_PRIORITY_MED, Gtpv1uNGReq, gtpv1uNGReq)
......@@ -40,7 +40,10 @@
#define GTPV1U_ENB_END_MARKER_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd
#define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req
#define GTPV1U_GNB_NG_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uNGReq
#define GTPV1U_GNB_DELETE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelReq
#define GTPV1U_GNB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelResp
#define GTPV1U_GNB_NG_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uNGReq
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
......@@ -194,4 +197,16 @@ typedef struct gtpv1u_gnb_create_tunnel_resp_s {
transport_layer_addr_t gnb_addr;
} gtpv1u_gnb_create_tunnel_resp_t;
typedef struct gtpv1u_gnb_delete_tunnel_req_s {
rnti_t rnti;
uint8_t num_pdusession;
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
} gtpv1u_gnb_delete_tunnel_req_t;
typedef struct gtpv1u_gnb_delete_tunnel_resp_s {
rnti_t rnti;
uint8_t status; ///< Status of NGU endpoint deleteion (Failed = 0xFF or Success = 0x0)
teid_t gnb_NGu_teid; ///< local NGU Tunnel Endpoint Identifier to be deleted
} gtpv1u_gnb_delete_tunnel_resp_t;
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
......@@ -261,7 +261,10 @@ typedef enum pdu_session_satus_e {
PDU_SESSION_STATUS_NEW,
PDU_SESSION_STATUS_DONE,
PDU_SESSION_STATUS_ESTABLISHED,
PDU_SESSION_STATUS_REESTABLISHED, // after HO
PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA
PDU_SESSION_STATUS_FAILED,
PDU_SESSION_STATUS_TORELEASE // to release DRB between eNB and UE
} pdu_session_status_t;
typedef struct pdu_session_param_s {
......@@ -355,6 +358,8 @@ typedef struct gNB_RRC_UE_s {
//release e_rabs
uint8_t nb_release_of_e_rabs;
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
uint8_t nb_release_of_pdusessions;
pdusession_failed_t pdusessions_release_failed[NGAP_MAX_PDUSESSION];
// LG: For GTPV1 TUNNELS
uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB];
......@@ -373,6 +378,7 @@ typedef struct gNB_RRC_UE_s {
uint32_t ue_reestablishment_timer;
uint32_t ue_reestablishment_timer_thres;
uint8_t e_rab_release_command_flag;
uint8_t pdu_session_release_command_flag;
//------------------------------------------------------------------------------//
NR_CellGroupId_t cellGroupId;
struct NR_SpCellConfig *spCellConfig;
......
......@@ -136,3 +136,10 @@ int
nr_rrc_mac_remove_ue(module_id_t mod_idP,
rnti_t rntiP);
void
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid,
uint32_t nas_length,
uint8_t *nas_buffer);
......@@ -118,6 +118,7 @@ extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * con
static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn);
mui_t rrc_gNB_mui = 0;
uint8_t first_rrcreconfiguration = 0;
///---------------------------------------------------------------------------------------------------------------///
///---------------------------------------------------------------------------------------------------------------///
......@@ -545,6 +546,100 @@ rrc_gNB_generate_defaultRRCReconfiguration(
// rrc_rlc_config_asn1_req
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid,
uint32_t nas_length,
uint8_t *nas_buffer)
//-----------------------------------------------------------------------------
{
uint8_t buffer[RRC_BUF_SIZE];
int i;
uint16_t size = 0;
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = NULL;
NR_DRB_Identity_t *DRB_release;
DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
if (DRB_Release_configList2) {
free(DRB_Release_configList2);
}
DRB_Release_configList2 = CALLOC(1, sizeof(*DRB_Release_configList2));
for(i = 0; i < NB_RB_MAX; i++) {
if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) {
DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t));
*DRB_release = i+1;
ASN_SEQUENCE_ADD(&DRB_Release_configList2->list, DRB_release);
}
}
/* If list is empty free the list and reset the address */
if (nas_length > 0) {
memcpy(ue_context_pP->ue_context.nas_pdu.buffer, nas_buffer, nas_length);
ue_context_pP->ue_context.nas_pdu.length = nas_length;
LOG_I(NR_RRC,"add NAS info with size %d\n", nas_length);
} else {
LOG_W(NR_RRC,"dedlicated NAS list is empty\n");
}
memset(buffer, 0, RRC_BUF_SIZE);
size = do_RRCReconfiguration(ctxt_pP,
ue_context_pP,
buffer,
xid,
NULL);
ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
"[MSG] RRC Reconfiguration\n");
/* Free all NAS PDUs */
if (nas_length > 0) {
/* Free the NAS PDU buffer and invalidate it */
free(nas_buffer);
}
LOG_I(NR_RRC,
"[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n",
ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
MSC_LOG_TX_MESSAGE(
MSC_RRC_GNB,
MSC_RRC_UE,
buffer,
size,
MSC_AS_TIME_FMT" dedicated NR_RRCReconfiguration UE %x MUI %d size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_pP->ue_context.rnti,
rrc_gNB_mui,
size);
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
memcpy (message_buffer, buffer, size);
message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_DCCH_DATA_IND);
GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
GNB_RRC_DCCH_DATA_IND (message_p).size = size;
itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
#else
nr_rrc_data_req(
ctxt_pP,
DCCH,
rrc_gNB_mui++,
SDU_CONFIRM_NO,
size,
buffer,
PDCP_TRANSMISSION_MODE_CONTROL);
#endif
}
//-----------------------------------------------------------------------------
/*
* Process the RRC Reconfiguration Complete from the UE
......@@ -921,7 +1016,8 @@ rrc_gNB_decode_dcch(
asn_dec_rval_t dec_rval;
NR_UL_DCCH_Message_t *ul_dcch_msg = NULL;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
// NR_RRCSetupComplete_t *rrcSetupComplete = NULL;
MessageDef *msg_delete_tunnels_p = NULL;
uint8_t xid;
int i;
......@@ -974,7 +1070,7 @@ rrc_gNB_decode_dcch(
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete:
LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %x\n", ctxt_pP->rnti);
LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %x\n", ctxt_pP->rnti);
if(!ue_context_p) {
LOG_I(NR_RRC, "Processing NR_RRCReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
break;
......@@ -1007,7 +1103,39 @@ rrc_gNB_decode_dcch(
ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
}
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
if (AMF_MODE_ENABLED) {
if(ue_context_p->ue_context.pdu_session_release_command_flag == 1) {
xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier;
ue_context_p->ue_context.pdu_session_release_command_flag = 0;
//gtp tunnel delete
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, GTPV1U_GNB_DELETE_TUNNEL_REQ);
memset(&GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
for(i = 0; i < NB_RB_MAX; i++) {
if(xid == ue_context_p->ue_context.pdusession[i].xid) {
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] =
ue_context_p->ue_context.gnb_gtp_psi[i];
ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i]));
ue_context_p->ue_context.gnb_gtp_psi[i] = 0;
}
}
itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p);
//NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
} else {
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP,
ue_context_p,
ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
}
}
if (first_rrcreconfiguration == 0){
first_rrcreconfiguration = 1;
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
}
break;
......@@ -1284,6 +1412,7 @@ rrc_gNB_decode_dcch(
ue_context_p,
ul_dcch_msg);
}
sleep(1);
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
break;
......@@ -1377,6 +1506,13 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(msg_p, msg_name_p, instance);
break;
case NGAP_PDUSESSION_RELEASE_COMMAND:
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(msg_p, msg_name_p, instance);
break;
case GTPV1U_GNB_DELETE_TUNNEL_RESP:
break;
/*
#if defined(ENABLE_USE_MME)
......
......@@ -1228,3 +1228,166 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n");
}
//------------------------------------------------------------------------------
void
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
)
//------------------------------------------------------------------------------
{
int pdu_sessions_released = 0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_RRC_GNB, NGAP_PDUSESSION_RELEASE_RESPONSE);
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
for (int i = 0; i < NB_RB_MAX; i++) {
if (xid == ue_context_pP->ue_context.pdusession[i].xid) {
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id =
ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
pdu_sessions_released++;
//clear
memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t));
}
}
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_released = pdu_sessions_released;
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_failed = ue_context_pP->ue_context.nb_release_of_pdusessions;
memcpy(&(NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusessions_failed[0]), &ue_context_pP->ue_context.pdusessions_release_failed[0],
sizeof(pdusession_failed_t)*ue_context_pP->ue_context.nb_release_of_pdusessions);
ue_context_pP->ue_context.setup_pdu_sessions -= pdu_sessions_released;
LOG_I(NR_RRC,"NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %d release_pdu_sessions %d setup_pdu_sessions %d \n",
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id,
pdu_sessions_released, ue_context_pP->ue_context.setup_pdu_sessions);
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
//clear xid
for(int i = 0; i < NB_RB_MAX; i++) {
ue_context_pP->ue_context.pdusession[i].xid = -1;
}
//clear release pdusessions
ue_context_pP->ue_context.nb_release_of_pdusessions = 0;
memset(&ue_context_pP->ue_context.pdusessions_release_failed[0], 0, sizeof(pdusession_failed_t)*NGAP_MAX_PDUSESSION);
return 0;
}
//------------------------------------------------------------------------------
int
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
MessageDef *msg_p,
const char *msg_name,
instance_t instance
)
//------------------------------------------------------------------------------
{
uint32_t gNB_ue_ngap_id;
rrc_gNB_ue_context_t *ue_context_p = NULL;
protocol_ctxt_t ctxt;
pdusession_release_t pdusession_release_params[NGAP_MAX_PDUSESSION];
uint8_t nb_pdusessions_torelease;
MessageDef *msg_delete_tunnels_p = NULL;
uint8_t xid;
int i, pdusession;
uint8_t b_existed,is_existed;
uint8_t pdusession_release_drb;
memcpy(&pdusession_release_params[0], &(NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).pdusession_release_params[0]),
sizeof(pdusession_release_t)*NGAP_MAX_PDUSESSION);
gNB_ue_ngap_id = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
nb_pdusessions_torelease = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).nb_pdusessions_torelease;
if (nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) {
return -1;
}
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id);
LOG_I(NR_RRC, "[gNB %d] Received %s: gNB_ue_ngap_id %d \n", instance, msg_name, gNB_ue_ngap_id);
if (ue_context_p != NULL) {
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id);
LOG_I(NR_RRC,"PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %d release_pdusessions %d \n",
NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id, gNB_ue_ngap_id, nb_pdusessions_torelease);
for (pdusession = 0; pdusession < nb_pdusessions_torelease; pdusession++) {
b_existed = 0;
is_existed = 0;
for (i = pdusession-1; i >= 0; i--) {
if (pdusession_release_params[pdusession].pdusession_id == pdusession_release_params[i].pdusession_id) {
is_existed = 1;
break;
}
}
if(is_existed == 1) {
// pdusession_id is existed
continue;
}
for (i = 0; i < NR_NB_RB_MAX; i++) {
if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) {
b_existed = 1;
break;
}
}
if(b_existed == 0) {
// no pdusession_id
LOG_I(NR_RRC, "no pdusession_id \n");
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30;
ue_context_p->ue_context.nb_release_of_pdusessions++;
} else {
if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) {
ue_context_p->ue_context.pdusession[i].xid = xid;
continue;
} else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id);
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE;
ue_context_p->ue_context.pdusession[i].xid = xid;
pdusession_release_drb++;
} else {
// pdusession_id status NG
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 0;
ue_context_p->ue_context.nb_release_of_pdusessions++;
}
}
}
if(pdusession_release_drb > 0) {
//TODO RRCReconfiguration To UE
LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n");
rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.length, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.buffer);
} else {
//gtp tunnel delete
LOG_I(NR_RRC, "gtp tunnel delete \n");
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, GTPV1U_GNB_DELETE_TUNNEL_REQ);
memset(&GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
for(i = 0; i < NB_RB_MAX; i++) {
if(xid == ue_context_p->ue_context.pdusession[i].xid) {
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i];
ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i]));
ue_context_p->ue_context.gnb_gtp_psi[i] = 0;
}
}
itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p);
//NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
LOG_I(NR_RRC, "Send PDU Session Release Response \n");
}
} else {
LOG_E(NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %d Error ue_context_p NULL \n",
NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id, NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id);
return -1;
}
return 0;
}
......@@ -142,4 +142,11 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
NR_UL_DCCH_Message_t *const ul_dcch_msg
);
int
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
MessageDef *msg_p,
const char *msg_name,
instance_t instance
);
#endif
......@@ -118,6 +118,7 @@ uint8_t do_NR_RRCReconfigurationComplete(
);
mui_t nr_rrc_mui=0;
uint8_t first_rrcreconfigurationcomplete = 0;
static Rrc_State_NR_t nr_rrc_get_state (module_id_t ue_mod_idP) {
return NR_UE_rrc_inst[ue_mod_idP].nrRrcState;
......@@ -2328,36 +2329,39 @@ nr_rrc_ue_decode_dcch(
nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
gNB_indexP,
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
if (first_rrcreconfigurationcomplete == 0) {
first_rrcreconfigurationcomplete = 1;
#ifdef ITTI_SIM
//wait send RRCReconfigurationComplete and InitialContextSetupResponse
sleep(1);
as_nas_info_t initialNasMsg;
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
generateRegistrationComplete(&initialNasMsg, NULL);
if(initialNasMsg.length > 0){
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
//wait send RegistrationComplete
usleep(100*150);
as_nas_info_t pduEstablishMsg;
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
generatePduSessionEstablishRequest(&pduEstablishMsg);
if(initialNasMsg.length > 0){
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
//wait send RRCReconfigurationComplete and InitialContextSetupResponse
sleep(1);
as_nas_info_t initialNasMsg;
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
generateRegistrationComplete(&initialNasMsg, NULL);
if(initialNasMsg.length > 0){
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
//wait send RegistrationComplete
usleep(100*150);
as_nas_info_t pduEstablishMsg;
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
generatePduSessionEstablishRequest(&pduEstablishMsg);
if(initialNasMsg.length > 0){
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
#endif
}
}
break;
......
......@@ -551,6 +551,83 @@ gtpv1u_create_ngu_tunnel(
return ret;
}
//-----------------------------------------------------------------------------
int gtpv1u_delete_ngu_tunnel(
const instance_t instanceP,
const gtpv1u_gnb_delete_tunnel_req_t *const req_pP) {
NwGtpv1uUlpApiT stack_req;
NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
MessageDef *message_p = NULL;
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
teid_t teid_gNB = 0;
int pdusession_index = 0;
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_GNB_DELETE_TUNNEL_RESP);
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti = req_pP->rnti;
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status = 0;
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)&gtpv1u_ue_data_p);
if (hash_rc == HASH_TABLE_OK) {
for (pdusession_index = 0; pdusession_index < req_pP->num_pdusession; pdusession_index++) {
teid_gNB = gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB;
LOG_D(GTPU, "Rx GTPV1U_ENB_DELETE_TUNNEL user rnti %x eNB S1U teid %u eps bearer id %u\n",
req_pP->rnti, teid_gNB, req_pP->pdusession_id[pdusession_index]);
{
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
stack_req.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT;
LOG_D(GTPU, "gtpv1u_delete_ngu_tunnel pdusession %u %u\n",
req_pP->pdusession_id[pdusession_index],
teid_gNB);
stack_req.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle =
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB_stack_session;
rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req);
LOG_D(GTPU, ".\n");
}
if (rc != NW_GTPV1U_OK) {
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status |= 0xFF;
LOG_E(GTPU, "NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT failed");
}
//-----------------------
// PDCP->GTPV1U mapping
//-----------------------
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].state = BEARER_DOWN;
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB = 0;
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_upf = 0;
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].upf_ip_addr = 0;
gtpv1u_ue_data_p->num_bearers -= 1;
if (gtpv1u_ue_data_p->num_bearers == 0) {
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti);
LOG_D(GTPU, "Removed user rnti %x,no more bearers configured\n", req_pP->rnti);
}
//-----------------------
// GTPV1U->PDCP mapping
//-----------------------
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, teid_gNB);
if (hash_rc != HASH_TABLE_OK) {
LOG_D(GTPU, "Removed user rnti %x , gNB NGU teid %u not found\n", req_pP->rnti, teid_gNB);
}
}
}// else silently do nothing
LOG_D(GTPU, "Tx GTPV1U_GNB_DELETE_TUNNEL_RESP user rnti %x gNB NGU teid %u status %u\n",
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).gnb_NGu_teid,
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status);
MSC_LOG_TX_MESSAGE(
MSC_GTPU_GNB,
MSC_RRC_GNB,
NULL,0,
"0 GTPV1U_GNB_DELETE_TUNNEL_RESP rnti %x teid %x",
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
teid_gNB);
return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p);
}
//-----------------------------------------------------------------------------
static int gtpv1u_gNB_send_init_udp(const Gtpv1uNGReq *req) {
// Create and alloc new message
......@@ -603,6 +680,10 @@ void *gtpv1u_gNB_process_itti_msg(void *notUsed) {
gtpv1u_ng_req(instance, &received_message_p->ittiMsg.gtpv1uNGReq);
break;
case GTPV1U_GNB_DELETE_TUNNEL_REQ:
gtpv1u_delete_ngu_tunnel(instance, &received_message_p->ittiMsg.NRGtpv1uDeleteTunnelReq);
break;
case TERMINATE_MESSAGE: {
if (RC.nr_gtpv1u_data_g->ue_mapping != NULL) {
hashtable_destroy (&(RC.nr_gtpv1u_data_g->ue_mapping));
......
......@@ -1754,7 +1754,7 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id,
return 0;
}
// handle e-rab release command and send it to rrc_end
// handle pdu session release command and send it to rrc_end
static
int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
uint32_t stream,
......@@ -1772,7 +1772,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceReleaseCommand;
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received E-RAB release command for non existing AMF context\n", assoc_id);
NGAP_ERROR("[SCTP %d] Received pdu session release command for non existing AMF context\n", assoc_id);
return -1;
}
......@@ -1805,11 +1805,11 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
}
/* Initial context request = UE-related procedure -> stream != 0 */
if (stream == 0) {
NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
assoc_id, stream);
return -1;
}
// if (stream == 0) {
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
// assoc_id, stream);
// return -1;
// }
ue_desc_p->rx_stream = stream;
......@@ -1818,7 +1818,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
(uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id);
}
NGAP_DEBUG("[SCTP %d] Received E-RAB release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
NGAP_DEBUG("[SCTP %d] Received pdu session release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id);
message_p = itti_alloc_new_message(TASK_NGAP, NGAP_PDUSESSION_RELEASE_COMMAND);
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
......@@ -1850,7 +1850,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i];
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].pdusession_id = item_p->pDUSessionID;
NGAP_DEBUG("[SCTP] Received E-RAB release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
NGAP_DEBUG("[SCTP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
}
} else {
return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment