RIC-961:implement Xn and X2 component IDs correctly in E2M
[ric-plt/e2mgr.git] / E2Manager / models / e2_setup_response_message.go
1 //
2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
4 // Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 //
10 //      http://www.apache.org/licenses/LICENSE-2.0
11 //
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17
18 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 //  platform project (RICP).
20
21 package models
22
23 import (
24         "encoding/xml"
25 )
26
27 const (
28         CauseID                       = "1"
29         GlobalE2nodeID                = "3"
30         GlobalRicID                   = "4"
31         RanFunctionIDItemID           = "6"
32         RanFunctionsAcceptedID        = "9"
33         RanFunctionsAddedID           = "10"
34         TimeToWaitID                  = "31"
35         TransactionID                 = "49"
36         E2nodeConfigAdditionID        = "50"
37         E2nodeConfigAdditionItemID    = "51"
38         E2nodeConfigAdditionAckID     = "52"
39         E2nodeConfigAdditionAckItemID = "53"
40 )
41
42 type TimeToWait = int
43
44 var TimeToWaitEnum = struct {
45         V60s TimeToWait
46         V20s TimeToWait
47         V10s TimeToWait
48         V5s  TimeToWait
49         V2s  TimeToWait
50         V1s  TimeToWait
51 }{60, 20, 10, 5, 2, 1}
52
53 var timeToWaitMap = map[TimeToWait]interface{}{
54         TimeToWaitEnum.V60s: struct {
55                 XMLName xml.Name `xml:"TimeToWait"`
56                 Text    string   `xml:",chardata"`
57                 V60s    string   `xml:"v60s"`
58         }{},
59         TimeToWaitEnum.V20s: struct {
60                 XMLName xml.Name `xml:"TimeToWait"`
61                 Text    string   `xml:",chardata"`
62                 V20s    string   `xml:"v20s"`
63         }{},
64         TimeToWaitEnum.V10s: struct {
65                 XMLName xml.Name `xml:"TimeToWait"`
66                 Text    string   `xml:",chardata"`
67                 V10s    string   `xml:"v10s"`
68         }{},
69         TimeToWaitEnum.V5s: struct {
70                 XMLName xml.Name `xml:"TimeToWait"`
71                 Text    string   `xml:",chardata"`
72                 V5s     string   `xml:"v5s"`
73         }{},
74         TimeToWaitEnum.V2s: struct {
75                 XMLName xml.Name `xml:"TimeToWait"`
76                 Text    string   `xml:",chardata"`
77                 V2s     string   `xml:"v2s"`
78         }{},
79         TimeToWaitEnum.V1s: struct {
80                 XMLName xml.Name `xml:"TimeToWait"`
81                 Text    string   `xml:",chardata"`
82                 V1s     string   `xml:"v1s"`
83         }{},
84 }
85
86 type ConfigStatus = int
87
88 var ConfigStatusEnum = struct {
89         Success ConfigStatus
90         Failure ConfigStatus
91 }{0, 1}
92
93 var configStatusMap = map[ConfigStatus]interface{}{
94         ConfigStatusEnum.Success: struct {
95                 XMLName xml.Name `xml:"updateOutcome"`
96                 Text    string   `xml:",chardata"`
97                 Success string   `xml:"success"`
98         }{},
99         ConfigStatusEnum.Failure: struct {
100                 XMLName xml.Name `xml:"updateOutcome"`
101                 Text    string   `xml:",chardata"`
102                 Failure string   `xml:"failure"`
103         }{},
104 }
105
106 func NewE2SetupSuccessResponseMessage(plmnId string, ricId string, request *E2SetupRequestMessage) E2SetupResponseMessage {
107         outcome := SuccessfulOutcome{}
108         outcome.ProcedureCode = "1"
109
110         e2SetupRequestIes := request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs
111         numOfIes := len(e2SetupRequestIes)
112
113         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, numOfIes)
114
115         for ieCount := 0; ieCount < numOfIes; ieCount++ {
116                 switch e2SetupRequestIes[ieCount].ID {
117                 case TransactionID:
118                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = TransactionID
119                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = TransID{
120                                 TransactionID: request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[ieCount].Value.TransactionID,
121                         }
122
123                 case GlobalE2nodeID:
124                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = GlobalRicID
125                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = GlobalRICID{GlobalRICID: struct {
126                                 Text         string `xml:",chardata"`
127                                 PLMNIdentity string `xml:"pLMN-Identity"`
128                                 RicID        string `xml:"ric-ID"`
129                         }{PLMNIdentity: plmnId, RicID: ricId}}
130
131                 case RanFunctionsAddedID:
132                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = RanFunctionsAcceptedID
133                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = RANfunctionsIDList{RANfunctionsIDList: struct {
134                                 Text                      string                      `xml:",chardata"`
135                                 ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
136                         }{ProtocolIESingleContainer: extractRanFunctionsIDList(request, ieCount)}}
137
138                 case E2nodeConfigAdditionID:
139                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].ID = E2nodeConfigAdditionAckID
140                         outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs[ieCount].Value = E2NodeConfigUpdateAckList{E2NodeConfigUpdateAckList: struct {
141                                 Text                        string                        `xml:",chardata"`
142                                 E2NodeConfigSingleContainer []E2NodeConfigSingleContainer `xml:"ProtocolIE-SingleContainer"`
143                         }{E2NodeConfigSingleContainer: extractE2NodeConfigUpdateList(request, ieCount, 0)}}
144                 }
145         }
146
147         return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}}
148 }
149
150 func NewE2SetupFailureResponseMessage(timeToWait TimeToWait, cause Cause, request *E2SetupRequestMessage) E2SetupResponseMessage {
151         outcome := UnsuccessfulOutcome{}
152
153         outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs = make([]E2setupFailureIEs, 3)
154         outcome.ProcedureCode = "1"
155
156         outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].ID = TransactionID
157         outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[0].Value.Value = TransFailID{
158                 ID: request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.TransactionID,
159         }
160
161         outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].ID = CauseID
162         outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].Value.Value = cause
163
164         outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].ID = TimeToWaitID
165         outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].Value.Value = timeToWaitMap[timeToWait]
166
167         return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}}
168 }
169
170 type E2SetupResponseMessage struct {
171         XMLName xml.Name `xml:"E2SetupSuccessResponseMessage"`
172         Text    string   `xml:",chardata"`
173         E2APPDU E2APPDU
174 }
175
176 type E2APPDU struct {
177         XMLName xml.Name `xml:"E2AP-PDU"`
178         Text    string   `xml:",chardata"`
179         Outcome interface{}
180 }
181
182 type SuccessfulOutcome struct {
183         XMLName       xml.Name `xml:"successfulOutcome"`
184         Text          string   `xml:",chardata"`
185         ProcedureCode string   `xml:"procedureCode"`
186         Criticality   struct {
187                 Text   string `xml:",chardata"`
188                 Reject string `xml:"reject"`
189         } `xml:"criticality"`
190         Value struct {
191                 Text            string `xml:",chardata"`
192                 E2setupResponse struct {
193                         Text        string `xml:",chardata"`
194                         ProtocolIEs struct {
195                                 Text               string               `xml:",chardata"`
196                                 E2setupResponseIEs []E2setupResponseIEs `xml:"E2setupResponseIEs"`
197                         } `xml:"protocolIEs"`
198                 } `xml:"E2setupResponse"`
199         } `xml:"value"`
200 }
201
202 type E2setupResponseIEs struct {
203         Text        string `xml:",chardata"`
204         ID          string `xml:"id"`
205         Criticality struct {
206                 Text   string `xml:",chardata"`
207                 Reject string `xml:"reject"`
208         } `xml:"criticality"`
209         Value interface{} `xml:"value"`
210 }
211
212 type GlobalRICID struct {
213         Text        string `xml:",chardata"`
214         GlobalRICID struct {
215                 Text         string `xml:",chardata"`
216                 PLMNIdentity string `xml:"pLMN-Identity"`
217                 RicID        string `xml:"ric-ID"`
218         } `xml:"GlobalRIC-ID"`
219 }
220
221 type RANfunctionsIDList struct {
222         Text               string `xml:",chardata"`
223         RANfunctionsIDList struct {
224                 Text                      string                      `xml:",chardata"`
225                 ProtocolIESingleContainer []ProtocolIESingleContainer `xml:"ProtocolIE-SingleContainer"`
226         } `xml:"RANfunctionsID-List"`
227 }
228
229 type ProtocolIESingleContainer struct {
230         Text        string `xml:",chardata"`
231         ID          string `xml:"id"`
232         Criticality struct {
233                 Text   string `xml:",chardata"`
234                 Ignore string `xml:"ignore"`
235         } `xml:"criticality"`
236         Value struct {
237                 Text              string `xml:",chardata"`
238                 RANfunctionIDItem struct {
239                         Text                string `xml:",chardata"`
240                         RanFunctionID       uint32 `xml:"ranFunctionID"`
241                         RanFunctionRevision uint32 `xml:"ranFunctionRevision"`
242                 } `xml:"RANfunctionID-Item"`
243         } `xml:"value"`
244 }
245
246 type TransID struct {
247         Text          string `xml:",chardata"`
248         TransactionID string `xml:"TransactionID"`
249 }
250
251 type TransFailID struct {
252         XMLName xml.Name `xml:"TransactionID"`
253         ID      string   `xml:",chardata"`
254 }
255
256 type E2NodeConfigUpdateAckList struct {
257         Text                      string `xml:",chardata"`
258         E2NodeConfigUpdateAckList struct {
259                 Text                        string                        `xml:",chardata"`
260                 E2NodeConfigSingleContainer []E2NodeConfigSingleContainer `xml:"ProtocolIE-SingleContainer"`
261         } `xml:"E2nodeComponentConfigAdditionAck-List"`
262 }
263
264 type E2NodeConfigSingleContainer struct {
265         Text        string `xml:",chardata"`
266         ID          string `xml:"id"`
267         Criticality struct {
268                 Text   string `xml:",chardata"`
269                 Reject string `xml:"reject"`
270         } `xml:"criticality"`
271         Value struct {
272                 Text                      string `xml:",chardata"`
273                 E2NodeConfigUpdateAckItem struct {
274                         Text                  string              `xml:",chardata"`
275                         E2nodeComponentType   E2NodeComponentType `xml:"e2nodeComponentInterfaceType"`
276                         E2nodeComponentID     E2NodeComponentIDResp
277                         E2nodeConfigUpdateAck E2nodeConfigUpdateAckResp
278                 } `xml:"E2nodeComponentConfigAdditionAck-Item"`
279         } `xml:"value"`
280 }
281
282 type E2NodeComponentIDResp struct {
283         XMLName xml.Name `xml:"e2nodeComponentID"`
284         Value   interface{}
285 }
286
287 type E2nodeConfigUpdateAckResp struct {
288         XMLName xml.Name `xml:"e2nodeComponentConfigurationAck"`
289         Value   interface{}
290 }
291
292 type UnsuccessfulOutcome struct {
293         XMLName       xml.Name `xml:"unsuccessfulOutcome"`
294         Text          string   `xml:",chardata"`
295         ProcedureCode string   `xml:"procedureCode"`
296         Criticality   struct {
297                 Text   string `xml:",chardata"`
298                 Reject string `xml:"reject"`
299         } `xml:"criticality"`
300         Value struct {
301                 Text           string `xml:",chardata"`
302                 E2setupFailure struct {
303                         Text        string `xml:",chardata"`
304                         ProtocolIEs struct {
305                                 Text              string              `xml:",chardata"`
306                                 E2setupFailureIEs []E2setupFailureIEs `xml:"E2setupFailureIEs"`
307                         } `xml:"protocolIEs"`
308                 } `xml:"E2setupFailure"`
309         } `xml:"value"`
310 }
311
312 type E2setupFailureIEs struct {
313         Text        string `xml:",chardata"`
314         ID          string `xml:"id"`
315         Criticality struct {
316                 Text   string `xml:",chardata"`
317                 Ignore string `xml:"ignore"`
318         } `xml:"criticality"`
319         Value struct {
320                 Text  string `xml:",chardata"`
321                 Value interface{}
322         } `xml:"value"`
323 }
324
325 func extractRanFunctionsIDList(request *E2SetupRequestMessage, index int) []ProtocolIESingleContainer {
326         list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[index].Value.RANfunctionsList
327         ids := make([]ProtocolIESingleContainer, len(list.ProtocolIESingleContainer))
328         for i := 0; i < len(ids); i++ {
329                 ids[i] = convertToRANfunctionID(list, i)
330         }
331         return ids
332 }
333
334 func convertToRANfunctionID(list *RANfunctionsList, i int) ProtocolIESingleContainer {
335         id := ProtocolIESingleContainer{}
336
337         id.ID = RanFunctionIDItemID
338         id.Value.RANfunctionIDItem.RanFunctionID = list.ProtocolIESingleContainer[i].Value.RANfunctionItem.RanFunctionID
339         id.Value.RANfunctionIDItem.RanFunctionRevision = list.ProtocolIESingleContainer[i].Value.RANfunctionItem.RanFunctionRevision
340
341         return id
342 }
343
344 func extractE2NodeConfigUpdateList(request *E2SetupRequestMessage, index int, outcome int) []E2NodeConfigSingleContainer {
345         list := &request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[index].Value.E2NodeConfigList
346         ids := make([]E2NodeConfigSingleContainer, len(list.ProtocolIESingleContainer))
347         for i := 0; i < len(ids); i++ {
348                 ids[i] = convertToE2NodeConfig(list, i, outcome)
349         }
350         return ids
351 }
352
353 func convertToE2NodeConfig(list *E2NodeConfigList, i int, outcome int) E2NodeConfigSingleContainer {
354         id := E2NodeConfigSingleContainer{}
355         id.ID = E2nodeConfigAdditionAckItemID
356
357         id.Value.E2NodeConfigUpdateAckItem.E2nodeConfigUpdateAck.Value = configStatusMap[outcome]
358
359         id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentType = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType
360
361         if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.NG != nil {
362                 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeNG{
363                         AMFName: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeNG.AMFName,
364                 }
365         } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.XN != nil {
366                 ifXn := E2NodeIFTypeXN{}
367                 if gnbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalgNBID; gnbid != nil {
368                         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}}
369                 } else if ngenb := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID; ngenb != nil {
370                         if ngenbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdMacro; ngenbid != "" && len(ngenbid) == 20 {
371                                 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}}
372                         } else if ngenbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdShortMacro; ngenbid != "" && len(ngenbid) == 18 {
373                                 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}}
374                         } else if ngenbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNGRANNodeID.GlobalngeNBID.EnbID.EnbIdLongMacro; ngenbid != "" && len(ngenbid) == 21 {
375                                 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}}
376                         }
377                 } else {
378                         //not valid
379                 }
380                 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifXn
381         } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.E1 != nil {
382                 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeE1{
383                         GNBCUCPID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeE1.GNBCUCPID,
384                 }
385         } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.F1 != nil {
386                 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeF1{
387                         GNBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeF1.GNBDUID,
388                 }
389         } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.W1 != nil {
390                 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeW1{
391                         NGENBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeW1.NGENBDUID,
392                 }
393         } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.S1 != nil {
394                 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeS1{
395                         MMENAME: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeS1.MMENAME,
396                 }
397         } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.X2 != nil {
398                 ifX2 := E2NodeIFTypeX2{}
399                 if gnbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalenGNBID; gnbid != nil {
400                         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}}
401                 } else if enb := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID; enb != nil {
402                         if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.MacroEnbId; enbid != "" && len(enbid) == 20 {
403                                 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}}
404                         } else if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.HomeEnbId; enbid != "" && len(enbid) == 28 {
405                                 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}}
406                         } else if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.ShortMacroEnbId; enbid != "" && len(enbid) == 18 {
407                                 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}}
408                         } else if enbid := list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.LongMacroEnbId; enbid != "" && len(enbid) == 21 {
409                                 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}}
410                         }
411                 } else {
412                         //not valid
413                 }
414                 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifX2
415         }
416
417         return id
418 }