//
// Copyright 2019 AT&T Intellectual Property
// Copyright 2019 Nokia
+// Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
"encoding/xml"
)
+const (
+ CauseID = "1"
+ GlobalE2nodeID = "3"
+ GlobalRicID = "4"
+ RanFunctionIDItemID = "6"
+ RanFunctionsAcceptedID = "9"
+ RanFunctionsAddedID = "10"
+ TimeToWaitID = "31"
+ TransactionID = "49"
+ E2nodeConfigAdditionID = "50"
+ E2nodeConfigAdditionItemID = "51"
+ E2nodeConfigAdditionAckID = "52"
+ E2nodeConfigAdditionAckItemID = "53"
+)
+
type TimeToWait = int
var TimeToWaitEnum = struct {
}{},
}
+type ConfigStatus = int
+
+var ConfigStatusEnum = struct {
+ Success ConfigStatus
+ Failure ConfigStatus
+}{0, 1}
+
+var configStatusMap = map[ConfigStatus]interface{}{
+ ConfigStatusEnum.Success: struct {
+ XMLName xml.Name `xml:"updateOutcome"`
+ Text string `xml:",chardata"`
+ Success string `xml:"success"`
+ }{},
+ ConfigStatusEnum.Failure: struct {
+ XMLName xml.Name `xml:"updateOutcome"`
+ Text string `xml:",chardata"`
+ Failure string `xml:"failure"`
+ }{},
+}
+
func NewE2SetupSuccessResponseMessage(plmnId string, ricId string, request *E2SetupRequestMessage) E2SetupResponseMessage {
outcome := SuccessfulOutcome{}
outcome.ProcedureCode = "1"
- setupRequestIes := request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs
+ e2SetupRequestIes := request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs
+ numOfIes := len(e2SetupRequestIes)
- outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, len(setupRequestIes))
- outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[0].ID = "4"
- outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[0].Value = GlobalRICID{GlobalRICID: struct {
- Text string `xml:",chardata"`
- PLMNIdentity string `xml:"pLMN-Identity"`
- RicID string `xml:"ric-ID"`
- }{PLMNIdentity: plmnId, RicID: ricId}}
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, numOfIes)
- if len(setupRequestIes) < 2 {
- return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}}
- }
+ for ieCount := 0; ieCount < numOfIes; ieCount++ {
+ switch e2SetupRequestIes[ieCount].ID {
+ case TransactionID:
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = TransactionID
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = TransID{
+ TransactionID: request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[ieCount].Value.TransactionID,
+ }
- functionsIdList := extractRanFunctionsIDList(request)
+ case GlobalE2nodeID:
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = GlobalRicID
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = GlobalRICID{GlobalRICID: struct {
+ Text string `xml:",chardata"`
+ PLMNIdentity string `xml:"pLMN-Identity"`
+ RicID string `xml:"ric-ID"`
+ }{PLMNIdentity: plmnId, RicID: ricId}}
- outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[1].ID = "9"
- outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[1].Value = RANfunctionsIDList{RANfunctionsIDList: struct {
- Text string `xml:",chardata"`
- ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
- }{ProtocolIESingleContainer: functionsIdList}}
+ case RanFunctionsAddedID:
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = RanFunctionsAcceptedID
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = RANfunctionsIDList{RANfunctionsIDList: struct {
+ Text string `xml:",chardata"`
+ ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
+ }{ProtocolIESingleContainer: extractRanFunctionsIDList(request, ieCount)}}
+
+ case E2nodeConfigAdditionID:
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = E2nodeConfigAdditionAckID
+ outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = E2NodeConfigUpdateAckList{E2NodeConfigUpdateAckList: struct {
+ Text string `xml:",chardata"`
+ E2NodeConfigSingleContainer []E2NodeConfigSingleContainer `xml:"ProtocolIE-SingleContainer"`
+ }{E2NodeConfigSingleContainer: extractE2NodeConfigUpdateList(request, ieCount, 0)}}
+ }
+ }
return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}}
}
-func NewE2SetupFailureResponseMessage(timeToWait TimeToWait) E2SetupResponseMessage {
+func NewE2SetupFailureResponseMessage(timeToWait TimeToWait, cause Cause, request *E2SetupRequestMessage) E2SetupResponseMessage {
outcome := UnsuccessfulOutcome{}
- outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs = make([]E2setupFailureIEs, 2)
+
+ outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs = make([]E2setupFailureIEs, 3)
outcome.ProcedureCode = "1"
- outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].ID = "1"
- outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].Value.Value = Cause{}
- outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].ID = "31"
- outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].Value.Value = timeToWaitMap[timeToWait]
+
+ outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].ID = TransactionID
+ outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].Value.Value = TransFailID{
+ ID: request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.TransactionID,
+ }
+
+ outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].ID = CauseID
+ outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].Value.Value = cause
+
+ outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].ID = TimeToWaitID
+ outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].Value.Value = timeToWaitMap[timeToWait]
+
return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}}
}
Text string `xml:",chardata"`
RANfunctionIDItem struct {
Text string `xml:",chardata"`
- RanFunctionID string `xml:"ranFunctionID"`
- RanFunctionRevision string `xml:"ranFunctionRevision"`
+ RanFunctionID uint32 `xml:"ranFunctionID"`
+ RanFunctionRevision uint32 `xml:"ranFunctionRevision"`
} `xml:"RANfunctionID-Item"`
} `xml:"value"`
}
+type TransID struct {
+ Text string `xml:",chardata"`
+ TransactionID string `xml:"TransactionID"`
+}
+
+type TransFailID struct {
+ XMLName xml.Name `xml:"TransactionID"`
+ ID string `xml:",chardata"`
+}
+
+type E2NodeConfigUpdateAckList struct {
+ Text string `xml:",chardata"`
+ E2NodeConfigUpdateAckList struct {
+ Text string `xml:",chardata"`
+ E2NodeConfigSingleContainer []E2NodeConfigSingleContainer `xml:"ProtocolIE-SingleContainer"`
+ } `xml:"E2nodeComponentConfigAdditionAck-List"`
+}
+
+type E2NodeConfigSingleContainer struct {
+ Text string `xml:",chardata"`
+ ID string `xml:"id"`
+ Criticality struct {
+ Text string `xml:",chardata"`
+ Reject string `xml:"reject"`
+ } `xml:"criticality"`
+ Value struct {
+ Text string `xml:",chardata"`
+ E2NodeConfigUpdateAckItem struct {
+ Text string `xml:",chardata"`
+ E2nodeComponentType E2NodeComponentType `xml:"e2nodeComponentInterfaceType"`
+ E2nodeComponentID E2NodeComponentIDResp
+ E2nodeConfigUpdateAck E2nodeConfigUpdateAckResp
+ } `xml:"E2nodeComponentConfigAdditionAck-Item"`
+ } `xml:"value"`
+}
+
+type E2NodeComponentIDResp struct {
+ XMLName xml.Name `xml:"e2nodeComponentID"`
+ Value interface{}
+}
+
+type E2nodeConfigUpdateAckResp struct {
+ XMLName xml.Name `xml:"e2nodeComponentConfigurationAck"`
+ Value interface{}
+}
+
type UnsuccessfulOutcome struct {
XMLName xml.Name `xml:"unsuccessfulOutcome"`
Text string `xml:",chardata"`
} `xml:"value"`
}
-type Cause struct {
- XMLName xml.Name `xml:"Cause"`
- Text string `xml:",chardata"`
- Transport struct {
- Text string `xml:",chardata"`
- TransportResourceUnavailable string `xml:"transport-resource-unavailable"`
- } `xml:"transport"`
-}
-
-func extractRanFunctionsIDList(request *E2SetupRequestMessage) []ProtocolIESingleContainer {
-
- list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[1].Value.RANfunctionsList
+func extractRanFunctionsIDList(request *E2SetupRequestMessage, index int) []ProtocolIESingleContainer {
+ list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[index].Value.RANfunctionsList
ids := make([]ProtocolIESingleContainer, len(list.ProtocolIESingleContainer))
for i := 0; i < len(ids); i++ {
ids[i] = convertToRANfunctionID(list, i)
func convertToRANfunctionID(list *RANfunctionsList, i int) ProtocolIESingleContainer {
id := ProtocolIESingleContainer{}
- id.ID = "6"
+
+ id.ID = RanFunctionIDItemID
id.Value.RANfunctionIDItem.RanFunctionID = list.ProtocolIESingleContainer[i].Value.RANfunctionItem.RanFunctionID
id.Value.RANfunctionIDItem.RanFunctionRevision = list.ProtocolIESingleContainer[i].Value.RANfunctionItem.RanFunctionRevision
+
+ return id
+}
+
+func extractE2NodeConfigUpdateList(request *E2SetupRequestMessage, index int, outcome int) []E2NodeConfigSingleContainer {
+ list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[index].Value.E2NodeConfigList
+ ids := make([]E2NodeConfigSingleContainer, len(list.ProtocolIESingleContainer))
+ for i := 0; i < len(ids); i++ {
+ ids[i] = convertToE2NodeConfig(list, i, outcome)
+ }
+ return ids
+}
+
+func convertToE2NodeConfig(list *E2NodeConfigList, i int, outcome int) E2NodeConfigSingleContainer {
+ id := E2NodeConfigSingleContainer{}
+ id.ID = E2nodeConfigAdditionAckItemID
+
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeConfigUpdateAck.Value = configStatusMap[outcome]
+
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentType = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType
+
+ if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.NG != nil {
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeNG{
+ AMFName: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeNG.AMFName,
+ }
+ } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.XN != nil {
+ ifXn := E2NodeIFTypeXN{}
+ if gnbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalgNBID; gnbid != nil {
+ ifXn.GlobalNGRANNodeID.GlobalgNBID = &GNB{PLMNID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalgNBID.PLMNID, GnbID: GnbID{GnbID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalgNBID.GnbID.GnbID}}
+ } else if ngenb := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID; ngenb != nil {
+ if ngenbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdMacro; ngenbid != "" && len(ngenbid) == 20 {
+ ifXn.GlobalNGRANNodeID.GlobalngeNBID = &NgeNBID{PLMNID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.PLMNID, EnbID: &EnbID_Xn{EnbIdMacro: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdMacro}}
+ } else if ngenbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdShortMacro; ngenbid != "" && len(ngenbid) == 18 {
+ ifXn.GlobalNGRANNodeID.GlobalngeNBID = &NgeNBID{PLMNID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.PLMNID, EnbID: &EnbID_Xn{EnbIdShortMacro: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdShortMacro}}
+ } else if ngenbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdLongMacro; ngenbid != "" && len(ngenbid) == 21 {
+ ifXn.GlobalNGRANNodeID.GlobalngeNBID = &NgeNBID{PLMNID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.PLMNID, EnbID: &EnbID_Xn{EnbIdLongMacro: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdLongMacro}}
+ }
+ } else {
+ //not valid
+ }
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifXn
+ } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.E1 != nil {
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeE1{
+ GNBCUCPID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeE1.GNBCUCPID,
+ }
+ } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.F1 != nil {
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeF1{
+ GNBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeF1.GNBDUID,
+ }
+ } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.W1 != nil {
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeW1{
+ NGENBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeW1.NGENBDUID,
+ }
+ } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.S1 != nil {
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeS1{
+ MMENAME: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeS1.MMENAME,
+ }
+ } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.X2 != nil {
+ ifX2 := E2NodeIFTypeX2{}
+ if gnbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalenGNBID; gnbid != nil {
+ ifX2.GlobalenGNBID = &GlobalenGNBID{PLMNIdentity: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalenGNBID.PLMNIdentity, GNBID: GNBID{GNBID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalenGNBID.GNBID.GNBID}}
+ } else if enb := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID; enb != nil {
+ if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.MacroEnbId; enbid != "" && len(enbid) == 20 {
+ ifX2.GlobalENBID = &GlobalENBID{PLMNIdentity: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.PLMNIdentity, ENBID: &ENBID_X2{MacroEnbId: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.MacroEnbId}}
+ } else if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.HomeEnbId; enbid != "" && len(enbid) == 28 {
+ ifX2.GlobalENBID = &GlobalENBID{PLMNIdentity: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.PLMNIdentity, ENBID: &ENBID_X2{HomeEnbId: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.HomeEnbId}}
+ } else if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.ShortMacroEnbId; enbid != "" && len(enbid) == 18 {
+ ifX2.GlobalENBID = &GlobalENBID{PLMNIdentity: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.PLMNIdentity, ENBID: &ENBID_X2{ShortMacroEnbId: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.ShortMacroEnbId}}
+ } else if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.LongMacroEnbId; enbid != "" && len(enbid) == 21 {
+ ifX2.GlobalENBID = &GlobalENBID{PLMNIdentity: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.PLMNIdentity, ENBID: &ENBID_X2{LongMacroEnbId: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.LongMacroEnbId}}
+ }
+ } else {
+ //not valid
+ }
+ id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifX2
+ }
+
return id
}