[AMF] Added RANConfigurationUpdate (#943)

This commit is contained in:
Sukchan Lee 2021-04-16 16:26:13 +09:00
parent bf5f64b5e5
commit ea89d8dc8e
10 changed files with 433 additions and 3 deletions

View File

@ -172,7 +172,7 @@ ogs_pkbuf_t *ngap_build_ng_setup_failure(
NGAP_NGSetupFailureIEs_t *ie = NULL;
NGAP_Cause_t *Cause = NULL;
NGAP_TimeToWait_t *TimeToWait = NULL;
ogs_debug(" Group[%d] Cause[%d] TimeToWait[%ld]",
group, (int)cause, time_to_wait);
@ -217,6 +217,85 @@ ogs_pkbuf_t *ngap_build_ng_setup_failure(
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *ngap_build_ran_configuration_update_ack(void)
{
NGAP_NGAP_PDU_t pdu;
NGAP_SuccessfulOutcome_t *successfulOutcome = NULL;
ogs_debug("RANConfigurationUpdateAcknowledge");
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
pdu.choice.successfulOutcome = CALLOC(1, sizeof(NGAP_SuccessfulOutcome_t));
successfulOutcome = pdu.choice.successfulOutcome;
successfulOutcome->procedureCode =
NGAP_ProcedureCode_id_RANConfigurationUpdate;
successfulOutcome->criticality = NGAP_Criticality_reject;
successfulOutcome->value.present =
NGAP_SuccessfulOutcome__value_PR_RANConfigurationUpdateAcknowledge;
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *ngap_build_ran_configuration_update_failure(
NGAP_Cause_PR group, long cause, long time_to_wait)
{
NGAP_NGAP_PDU_t pdu;
NGAP_UnsuccessfulOutcome_t *unsuccessfulOutcome = NULL;
NGAP_RANConfigurationUpdateFailure_t *RANConfigurationUpdateFailure = NULL;
NGAP_RANConfigurationUpdateFailureIEs_t *ie = NULL;
NGAP_Cause_t *Cause = NULL;
NGAP_TimeToWait_t *TimeToWait = NULL;
ogs_debug(" Group[%d] Cause[%d] TimeToWait[%ld]",
group, (int)cause, time_to_wait);
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_unsuccessfulOutcome;
pdu.choice.unsuccessfulOutcome =
CALLOC(1, sizeof(NGAP_UnsuccessfulOutcome_t));
unsuccessfulOutcome = pdu.choice.unsuccessfulOutcome;
unsuccessfulOutcome->procedureCode =
NGAP_ProcedureCode_id_RANConfigurationUpdate;
unsuccessfulOutcome->criticality = NGAP_Criticality_reject;
unsuccessfulOutcome->value.present =
NGAP_UnsuccessfulOutcome__value_PR_RANConfigurationUpdateFailure;
RANConfigurationUpdateFailure =
&unsuccessfulOutcome->value.choice.RANConfigurationUpdateFailure;
if (time_to_wait > -1) {
ie = CALLOC(1, sizeof(NGAP_RANConfigurationUpdateFailureIEs_t));
ASN_SEQUENCE_ADD(&RANConfigurationUpdateFailure->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_TimeToWait;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present =
NGAP_RANConfigurationUpdateFailureIEs__value_PR_TimeToWait;
TimeToWait = &ie->value.choice.TimeToWait;
}
ie = CALLOC(1, sizeof(NGAP_RANConfigurationUpdateFailureIEs_t));
ASN_SEQUENCE_ADD(&RANConfigurationUpdateFailure->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_Cause;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_RANConfigurationUpdateFailureIEs__value_PR_Cause;
Cause = &ie->value.choice.Cause;
Cause->present = group;
Cause->choice.radioNetwork = cause;
if (TimeToWait)
*TimeToWait = time_to_wait;
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *ngap_build_downlink_nas_transport(
ran_ue_t *ran_ue, ogs_pkbuf_t *gmmbuf, bool ue_ambr, bool allowed_nssai)
{

View File

@ -30,6 +30,10 @@ ogs_pkbuf_t *ngap_build_ng_setup_response(void);
ogs_pkbuf_t *ngap_build_ng_setup_failure(
NGAP_Cause_PR group, long cause, long time_to_wait);
ogs_pkbuf_t *ngap_build_ran_configuration_update_ack(void);
ogs_pkbuf_t *ngap_build_ran_configuration_update_failure(
NGAP_Cause_PR group, long cause, long time_to_wait);
ogs_pkbuf_t *ngap_build_downlink_nas_transport(
ran_ue_t *ran_ue, ogs_pkbuf_t *gmmbuf, bool ue_ambr, bool allowed_nssai);

View File

@ -3196,6 +3196,214 @@ void ngap_handle_handover_notification(
}
}
void ngap_handle_ran_configuration_update(
amf_gnb_t *gnb, ogs_ngap_message_t *message)
{
char buf[OGS_ADDRSTRLEN];
int i, j, k;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_RANConfigurationUpdate_t *RANConfigurationUpdate = NULL;
NGAP_RANConfigurationUpdateIEs_t *ie = NULL;
NGAP_GlobalRANNodeID_t *GlobalRANNodeID = NULL;
NGAP_GlobalGNB_ID_t *globalGNB_ID = NULL;
NGAP_SupportedTAList_t *SupportedTAList = NULL;
NGAP_PagingDRX_t *PagingDRX = NULL;
NGAP_Cause_PR group = NGAP_Cause_PR_NOTHING;
long cause = 0;
uint32_t gnb_id;
ogs_assert(gnb);
ogs_assert(gnb->sctp.sock);
ogs_assert(message);
initiatingMessage = message->choice.initiatingMessage;
ogs_assert(initiatingMessage);
RANConfigurationUpdate = &initiatingMessage->value.choice.RANConfigurationUpdate;
ogs_assert(RANConfigurationUpdate);
ogs_debug("RANConfigurationUpdate");
for (i = 0; i < RANConfigurationUpdate->protocolIEs.list.count; i++) {
ie = RANConfigurationUpdate->protocolIEs.list.array[i];
switch (ie->id) {
case NGAP_ProtocolIE_ID_id_GlobalRANNodeID:
GlobalRANNodeID = &ie->value.choice.GlobalRANNodeID;
break;
case NGAP_ProtocolIE_ID_id_SupportedTAList:
SupportedTAList = &ie->value.choice.SupportedTAList;
break;
case NGAP_ProtocolIE_ID_id_DefaultPagingDRX:
PagingDRX = &ie->value.choice.PagingDRX;
break;
default:
break;
}
}
if (GlobalRANNodeID) {
globalGNB_ID = GlobalRANNodeID->choice.globalGNB_ID;
if (!globalGNB_ID) {
ogs_error("No globalGNB_ID");
group = NGAP_Cause_PR_protocol;
cause = NGAP_CauseProtocol_semantic_error;
ngap_send_ran_configuration_update_failure(gnb, group, cause);
return;
}
ogs_ngap_GNB_ID_to_uint32(&globalGNB_ID->gNB_ID, &gnb_id);
ogs_debug(" IP[%s] GNB_ID[0x%x]",
OGS_ADDR(gnb->sctp.addr, buf), gnb_id);
amf_gnb_set_gnb_id(gnb, gnb_id);
}
if (SupportedTAList) {
/* Parse Supported TA */
for (i = 0, gnb->num_of_supported_ta_list = 0;
i < SupportedTAList->list.count &&
gnb->num_of_supported_ta_list < OGS_MAX_NUM_OF_TAI;
i++) {
NGAP_SupportedTAItem_t *SupportedTAItem = NULL;
SupportedTAItem = (NGAP_SupportedTAItem_t *)
SupportedTAList->list.array[i];
if (!SupportedTAItem) {
ogs_error("No SupportedTAItem");
group = NGAP_Cause_PR_protocol;
cause = NGAP_CauseProtocol_semantic_error;
ngap_send_ran_configuration_update_failure(gnb, group, cause);
return;
}
ogs_asn_OCTET_STRING_to_uint24(&SupportedTAItem->tAC,
&gnb->supported_ta_list[i].tac);
ogs_debug(" TAC[%d]", gnb->supported_ta_list[i].tac.v);
for (j = 0, gnb->supported_ta_list[i].num_of_bplmn_list = 0;
j < SupportedTAItem->broadcastPLMNList.list.count &&
gnb->supported_ta_list[i].num_of_bplmn_list <
OGS_MAX_NUM_OF_BPLMN;
j++) {
NGAP_BroadcastPLMNItem_t *BroadcastPLMNItem = NULL;
NGAP_PLMNIdentity_t *pLMNIdentity = NULL;
BroadcastPLMNItem = (NGAP_BroadcastPLMNItem_t *)
SupportedTAItem->broadcastPLMNList.list.array[j];
if (!BroadcastPLMNItem) {
ogs_error("No BroadcastPLMNItem");
group = NGAP_Cause_PR_protocol;
cause = NGAP_CauseProtocol_semantic_error;
ngap_send_ran_configuration_update_failure(
gnb, group, cause);
return;
}
pLMNIdentity = (NGAP_PLMNIdentity_t *)
&BroadcastPLMNItem->pLMNIdentity;
ogs_assert(pLMNIdentity);
memcpy(&gnb->supported_ta_list[i].bplmn_list[j].plmn_id,
pLMNIdentity->buf, sizeof(ogs_plmn_id_t));
ogs_debug(" PLMN_ID[MCC:%d MNC:%d]",
ogs_plmn_id_mcc(&gnb->supported_ta_list[i].
bplmn_list[j].plmn_id),
ogs_plmn_id_mnc(&gnb->supported_ta_list[i].
bplmn_list[j].plmn_id));
for (k = 0, gnb->supported_ta_list[i].
bplmn_list[j].num_of_s_nssai = 0;
k < BroadcastPLMNItem->tAISliceSupportList.list.count &&
gnb->supported_ta_list[i].bplmn_list[j].num_of_s_nssai <
OGS_MAX_NUM_OF_SLICE;
k++) {
NGAP_SliceSupportItem_t *SliceSupportItem = NULL;
NGAP_S_NSSAI_t *s_NSSAI = NULL;
SliceSupportItem = (NGAP_SliceSupportItem_t *)
BroadcastPLMNItem->tAISliceSupportList.list.array[k];
if (!SliceSupportItem) {
ogs_error("No SliceSupportItem");
group = NGAP_Cause_PR_protocol;
cause = NGAP_CauseProtocol_semantic_error;
ngap_send_ran_configuration_update_failure(
gnb, group, cause);
return;
}
s_NSSAI = &SliceSupportItem->s_NSSAI;
ogs_assert(s_NSSAI);
ogs_asn_OCTET_STRING_to_uint8(&s_NSSAI->sST,
&gnb->supported_ta_list[i].
bplmn_list[j].s_nssai[k].sst);
if (!s_NSSAI->sD) {
gnb->supported_ta_list[i].bplmn_list[j].
s_nssai[k].sd.v = OGS_S_NSSAI_NO_SD_VALUE;
} else {
ogs_asn_OCTET_STRING_to_uint24(s_NSSAI->sD,
&gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sd);
}
ogs_debug(" S_NSSAI[SST:%d SD:0x%x]",
gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sst,
gnb->supported_ta_list[i].bplmn_list[j].
s_nssai[k].sd.v);
gnb->supported_ta_list[i].bplmn_list[j].num_of_s_nssai++;
}
gnb->supported_ta_list[i].num_of_bplmn_list++;
}
gnb->num_of_supported_ta_list++;
}
if (gnb->num_of_supported_ta_list == 0) {
ogs_warn("RANConfigurationUpdate failure:");
ogs_warn(" No supported TA exist in request");
group = NGAP_Cause_PR_protocol;
cause =
NGAP_CauseProtocol_message_not_compatible_with_receiver_state;
ngap_send_ran_configuration_update_failure(gnb, group, cause);
return;
}
if (!served_tai_is_found(gnb)) {
ogs_warn("RANConfigurationUpdate failure:");
ogs_warn(" Cannot find Served TAI. "
"Check 'amf.tai' configuration");
group = NGAP_Cause_PR_misc;
cause = NGAP_CauseMisc_unknown_PLMN;
ngap_send_ran_configuration_update_failure(gnb, group, cause);
return;
}
if (!s_nssai_is_found(gnb)) {
ogs_warn("RANConfigurationUpdate failure:");
ogs_warn(" Cannot find S_NSSAI. "
"Check 'amf.plmn_support.s_nssai' configuration");
group = NGAP_Cause_PR_misc;
cause = NGAP_CauseMisc_unknown_PLMN;
ngap_send_ran_configuration_update_failure(gnb, group, cause);
return;
}
}
if (PagingDRX)
ogs_debug(" PagingDRX[%ld]", *PagingDRX);
ngap_send_ran_configuration_update_ack(gnb);
}
void ngap_handle_ng_reset(
amf_gnb_t *gnb, ogs_ngap_message_t *message)
{

View File

@ -76,6 +76,9 @@ void ngap_handle_uplink_ran_status_transfer(
void ngap_handle_handover_notification(
amf_gnb_t *gnb, ogs_ngap_message_t *message);
void ngap_handle_ran_configuration_update(
amf_gnb_t *gnb, ogs_ngap_message_t *message);
void ngap_handle_ng_reset(
amf_gnb_t *gnb, ogs_ngap_message_t *message);

View File

@ -262,6 +262,32 @@ void ngap_send_ng_setup_failure(
ngap_send_to_gnb(gnb, ngap_buffer, NGAP_NON_UE_SIGNALLING));
}
void ngap_send_ran_configuration_update_ack(amf_gnb_t *gnb)
{
ogs_pkbuf_t *ngap_buffer;
ogs_debug("RANConfigurationUpdateAcknowledge");
ngap_buffer = ngap_build_ran_configuration_update_ack();
ogs_expect_or_return(ngap_buffer);
ogs_expect(OGS_OK ==
ngap_send_to_gnb(gnb, ngap_buffer, NGAP_NON_UE_SIGNALLING));
}
void ngap_send_ran_configuration_update_failure(
amf_gnb_t *gnb, NGAP_Cause_PR group, long cause)
{
ogs_pkbuf_t *ngap_buffer;
ogs_debug("RANConfigurationUpdateFailure");
ngap_buffer = ngap_build_ran_configuration_update_failure(
group, cause, NGAP_TimeToWait_v10s);
ogs_expect_or_return(ngap_buffer);
ogs_expect(OGS_OK ==
ngap_send_to_gnb(gnb, ngap_buffer, NGAP_NON_UE_SIGNALLING));
}
#if 0
void ngap_send_ue_context_modification_request(amf_ue_t *amf_ue)
{

View File

@ -50,6 +50,9 @@ int ngap_send_to_5gsm(amf_ue_t *amf_ue, ogs_pkbuf_t *esmbuf);
void ngap_send_ng_setup_response(amf_gnb_t *gnb);
void ngap_send_ng_setup_failure(
amf_gnb_t *gnb, NGAP_Cause_PR group, long cause);
void ngap_send_ran_configuration_update_ack(amf_gnb_t *gnb);
void ngap_send_ran_configuration_update_failure(
amf_gnb_t *gnb, NGAP_Cause_PR group, long cause);
void ngap_send_ue_context_modification_request(amf_ue_t *amf_ue);

View File

@ -113,6 +113,9 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
case NGAP_ProcedureCode_id_HandoverCancel:
ngap_handle_handover_cancel(gnb, pdu);
break;
case NGAP_ProcedureCode_id_RANConfigurationUpdate:
ngap_handle_ran_configuration_update(gnb, pdu);
break;
case NGAP_ProcedureCode_id_NGReset:
ngap_handle_ng_reset(gnb, pdu);
break;

View File

@ -54,8 +54,7 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize)
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NGSetup;
@ -162,6 +161,98 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize)
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_ran_configuration_update(bool supported_ta_list)
{
ogs_pkbuf_t *pkbuf = NULL;
int i, j;
ogs_plmn_id_t *plmn_id = NULL;
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_RANConfigurationUpdate_t *RANConfigurationUpdate = NULL;
NGAP_RANConfigurationUpdateIEs_t *ie = NULL;
NGAP_GlobalRANNodeID_t *GlobalRANNodeID = NULL;
NGAP_RANNodeName_t *RANNodeName = NULL;
NGAP_GlobalGNB_ID_t *globalGNB_ID = NULL;
NGAP_SupportedTAList_t *SupportedTAList = NULL;
NGAP_SupportedTAItem_t *SupportedTAItem = NULL;
NGAP_BroadcastPLMNItem_t *BroadcastPLMNItem = NULL;
NGAP_SliceSupportItem_t *SliceSupportItem = NULL;
NGAP_PLMNIdentity_t *pLMNIdentity = NULL;
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
NGAP_ProcedureCode_id_RANConfigurationUpdate;
initiatingMessage->criticality = NGAP_Criticality_reject;
initiatingMessage->value.present =
NGAP_InitiatingMessage__value_PR_RANConfigurationUpdate;
RANConfigurationUpdate =
&initiatingMessage->value.choice.RANConfigurationUpdate;
if (supported_ta_list == true) {
ie = CALLOC(1, sizeof(NGAP_RANConfigurationUpdateIEs_t));
ASN_SEQUENCE_ADD(&RANConfigurationUpdate->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_SupportedTAList;
ie->criticality = NGAP_Criticality_reject;
ie->value.present =
NGAP_RANConfigurationUpdateIEs__value_PR_SupportedTAList;
SupportedTAList = &ie->value.choice.SupportedTAList;
SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
if (test_self()->nr_served_tai[0].list2.num)
ogs_asn_uint24_to_OCTET_STRING(
test_self()->nr_served_tai[0].list2.tai[0].tac,
&SupportedTAItem->tAC);
else if (test_self()->nr_served_tai[0].list0.tai[0].num)
ogs_asn_uint24_to_OCTET_STRING(
test_self()->nr_served_tai[0].list0.tai[0].tac[0],
&SupportedTAItem->tAC);
else
ogs_assert_if_reached();
for (i = 0; i < test_self()->num_of_plmn_support; i++) {
plmn_id = &test_self()->plmn_support[i].plmn_id;
BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));
ogs_asn_buffer_to_OCTET_STRING(
plmn_id, OGS_PLMN_ID_LEN, &BroadcastPLMNItem->pLMNIdentity);
for (j = 0; j < test_self()->plmn_support[i].num_of_s_nssai; j++) {
ogs_s_nssai_t *s_nssai =
&test_self()->plmn_support[i].s_nssai[j];
SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t));
ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
&SliceSupportItem->s_NSSAI.sST);
if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(NGAP_SD_t));
ogs_asn_uint24_to_OCTET_STRING(
s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
}
ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list,
SliceSupportItem);
}
ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
BroadcastPLMNItem);
}
ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
}
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_initial_ue_message(
test_ue_t *test_ue, ogs_pkbuf_t *gmmbuf,
bool s_tmsi, bool ue_context_requested)

View File

@ -25,6 +25,8 @@ extern "C" {
#endif
ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize);
ogs_pkbuf_t *testngap_build_ran_configuration_update(bool supported_ta_list);
ogs_pkbuf_t *testngap_build_initial_ue_message(
test_ue_t *test_ue, ogs_pkbuf_t *gmmbuf,
bool s_tmsi, bool ue_context_requested);

View File

@ -272,6 +272,17 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send RANConfigurationUpdate */
sendbuf = testngap_build_ran_configuration_update(true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive RANConfigurationUpdateAcknowledge */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send NGReset */
sendbuf = ogs_ngap_build_ng_reset(
NGAP_Cause_PR_radioNetwork,