RIC-961:implement Xn and X2 component IDs correctly in E2M
[ric-plt/e2mgr.git] / E2Manager / models / e2_setup_response_message.go
index 62c733d..2fcecc4 100644 (file)
@@ -1,6 +1,7 @@
 //
 // 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.
 //  platform project (RICP).
 
 package models
+
 import (
        "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{
+var TimeToWaitEnum = struct {
        V60s TimeToWait
        V20s TimeToWait
        V10s TimeToWait
-       V5s TimeToWait
-       V2s TimeToWait
-       V1s TimeToWait
+       V5s  TimeToWait
+       V2s  TimeToWait
+       V1s  TimeToWait
 }{60, 20, 10, 5, 2, 1}
 
 var timeToWaitMap = map[TimeToWait]interface{}{
-       TimeToWaitEnum.V60s  : struct {
+       TimeToWaitEnum.V60s: struct {
                XMLName xml.Name `xml:"TimeToWait"`
-               Text string `xml:",chardata"`
-               V60s string `xml:"v60s"`
+               Text    string   `xml:",chardata"`
+               V60s    string   `xml:"v60s"`
        }{},
-       TimeToWaitEnum.V20s  : struct {
+       TimeToWaitEnum.V20s: struct {
                XMLName xml.Name `xml:"TimeToWait"`
-               Text string `xml:",chardata"`
-               V20s string `xml:"v20s"`
+               Text    string   `xml:",chardata"`
+               V20s    string   `xml:"v20s"`
        }{},
-       TimeToWaitEnum.V10s  : struct {
+       TimeToWaitEnum.V10s: struct {
                XMLName xml.Name `xml:"TimeToWait"`
-               Text string `xml:",chardata"`
-               V10s string `xml:"v10s"`
+               Text    string   `xml:",chardata"`
+               V10s    string   `xml:"v10s"`
        }{},
-       TimeToWaitEnum.V5s   : struct {
+       TimeToWaitEnum.V5s: struct {
                XMLName xml.Name `xml:"TimeToWait"`
-               Text string `xml:",chardata"`
-               V5s string `xml:"v5s"`
+               Text    string   `xml:",chardata"`
+               V5s     string   `xml:"v5s"`
        }{},
-       TimeToWaitEnum.V2s   : struct {
+       TimeToWaitEnum.V2s: struct {
                XMLName xml.Name `xml:"TimeToWait"`
-               Text string `xml:",chardata"`
-               V2s string `xml:"v2s"`
+               Text    string   `xml:",chardata"`
+               V2s     string   `xml:"v2s"`
        }{},
-       TimeToWaitEnum.V1s   : struct {
+       TimeToWaitEnum.V1s: struct {
                XMLName xml.Name `xml:"TimeToWait"`
-               Text string `xml:",chardata"`
-               V1s string `xml:"v1s"`
+               Text    string   `xml:",chardata"`
+               V1s     string   `xml:"v1s"`
        }{},
 }
 
-func NewE2SetupSuccessResponseMessage(plmnId string, ricId string, request *E2SetupRequestMessage) E2SetupResponseMessage{
+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.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, 2)
        outcome.ProcedureCode = "1"
-       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[1].ID = "9"
-       outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[1].Value = RANfunctionsIDList{RANfunctionsIDList: struct {
-               Text                      string `xml:",chardata"`
-               ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
-       }{ProtocolIESingleContainer:extractRanFunctionsIDList(request)}}
-       return E2SetupResponseMessage{E2APPDU:E2APPDU{Outcome:outcome}}
+
+       e2SetupRequestIes := request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs
+       numOfIes := len(e2SetupRequestIes)
+
+       outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, numOfIes)
+
+       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,
+                       }
+
+               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}}
+
+               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]
-       return E2SetupResponseMessage{E2APPDU:E2APPDU{Outcome:outcome}}
+
+       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}}
 }
 
 type E2SetupResponseMessage struct {
@@ -104,14 +175,14 @@ type E2SetupResponseMessage struct {
 
 type E2APPDU struct {
        XMLName xml.Name `xml:"E2AP-PDU"`
-       Text    string `xml:",chardata"`
+       Text    string   `xml:",chardata"`
        Outcome interface{}
 }
 
 type SuccessfulOutcome struct {
-       XMLName xml.Name        `xml:"successfulOutcome"`
-       Text          string `xml:",chardata"`
-       ProcedureCode string `xml:"procedureCode"`
+       XMLName       xml.Name `xml:"successfulOutcome"`
+       Text          string   `xml:",chardata"`
+       ProcedureCode string   `xml:"procedureCode"`
        Criticality   struct {
                Text   string `xml:",chardata"`
                Reject string `xml:"reject"`
@@ -121,8 +192,8 @@ type SuccessfulOutcome struct {
                E2setupResponse struct {
                        Text        string `xml:",chardata"`
                        ProtocolIEs struct {
-                               Text               string `xml:",chardata"`
-                               E2setupResponseIEs []E2setupResponseIEs`xml:"E2setupResponseIEs"`
+                               Text               string               `xml:",chardata"`
+                               E2setupResponseIEs []E2setupResponseIEs `xml:"E2setupResponseIEs"`
                        } `xml:"protocolIEs"`
                } `xml:"E2setupResponse"`
        } `xml:"value"`
@@ -135,7 +206,7 @@ type E2setupResponseIEs struct {
                Text   string `xml:",chardata"`
                Reject string `xml:"reject"`
        } `xml:"criticality"`
-       Value interface{}`xml:"value"`
+       Value interface{} `xml:"value"`
 }
 
 type GlobalRICID struct {
@@ -148,9 +219,9 @@ type GlobalRICID struct {
 }
 
 type RANfunctionsIDList struct {
-       Text        string `xml:",chardata"`
+       Text               string `xml:",chardata"`
        RANfunctionsIDList struct {
-               Text                      string `xml:",chardata"`
+               Text                      string                      `xml:",chardata"`
                ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
        } `xml:"RANfunctionsID-List"`
 }
@@ -166,28 +237,73 @@ type ProtocolIESingleContainer struct {
                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"`
-       ProcedureCode string `xml:"procedureCode"`
+       XMLName       xml.Name `xml:"unsuccessfulOutcome"`
+       Text          string   `xml:",chardata"`
+       ProcedureCode string   `xml:"procedureCode"`
        Criticality   struct {
                Text   string `xml:",chardata"`
                Reject string `xml:"reject"`
        } `xml:"criticality"`
        Value struct {
-               Text            string `xml:",chardata"`
+               Text           string `xml:",chardata"`
                E2setupFailure struct {
                        Text        string `xml:",chardata"`
                        ProtocolIEs struct {
-                               Text               string `xml:",chardata"`
-                               E2setupFailureIEs []E2setupFailureIEs`xml:"E2setupFailureIEs"`
+                               Text              string              `xml:",chardata"`
+                               E2setupFailureIEs []E2setupFailureIEs `xml:"E2setupFailureIEs"`
                        } `xml:"protocolIEs"`
                } `xml:"E2setupFailure"`
        } `xml:"value"`
@@ -206,28 +322,97 @@ type E2setupFailureIEs struct {
        } `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
-       ids := make([]ProtocolIESingleContainer,len(list.ProtocolIESingleContainer))
-       for i := 0; i< len(ids); i++{
+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)
        }
        return ids
 }
 
-func convertToRANfunctionID(list *RANfunctionsList, i int) ProtocolIESingleContainer{
+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
-}
\ No newline at end of file
+}
+
+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
+}