2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
4 // Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
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
10 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 // This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 // platform project (RICP).
31 RanFunctionIDItemID = "6"
32 RanFunctionsAcceptedID = "9"
33 RanFunctionsAddedID = "10"
36 E2nodeConfigAdditionID = "50"
37 E2nodeConfigAdditionItemID = "51"
38 E2nodeConfigAdditionAckID = "52"
39 E2nodeConfigAdditionAckItemID = "53"
44 var TimeToWaitEnum = struct {
51 }{60, 20, 10, 5, 2, 1}
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"`
59 TimeToWaitEnum.V20s: struct {
60 XMLName xml.Name `xml:"TimeToWait"`
61 Text string `xml:",chardata"`
62 V20s string `xml:"v20s"`
64 TimeToWaitEnum.V10s: struct {
65 XMLName xml.Name `xml:"TimeToWait"`
66 Text string `xml:",chardata"`
67 V10s string `xml:"v10s"`
69 TimeToWaitEnum.V5s: struct {
70 XMLName xml.Name `xml:"TimeToWait"`
71 Text string `xml:",chardata"`
72 V5s string `xml:"v5s"`
74 TimeToWaitEnum.V2s: struct {
75 XMLName xml.Name `xml:"TimeToWait"`
76 Text string `xml:",chardata"`
77 V2s string `xml:"v2s"`
79 TimeToWaitEnum.V1s: struct {
80 XMLName xml.Name `xml:"TimeToWait"`
81 Text string `xml:",chardata"`
82 V1s string `xml:"v1s"`
86 type ConfigStatus = int
88 var ConfigStatusEnum = struct {
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"`
99 ConfigStatusEnum.Failure: struct {
100 XMLName xml.Name `xml:"updateOutcome"`
101 Text string `xml:",chardata"`
102 Failure string `xml:"failure"`
106 func NewE2SetupSuccessResponseMessage(plmnId string, ricId string, request *E2SetupRequestMessage) E2SetupResponseMessage {
107 outcome := SuccessfulOutcome{}
108 outcome.ProcedureCode = "1"
110 e2SetupRequestIes := request.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs
111 numOfIes := len(e2SetupRequestIes)
113 outcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs = make([]E2setupResponseIEs, numOfIes)
115 for ieCount := 0; ieCount < numOfIes; ieCount++ {
116 switch e2SetupRequestIes[ieCount].ID {
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,
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}}
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)}}
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)}}
147 return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}}
150 func NewE2SetupFailureResponseMessage(timeToWait TimeToWait, cause Cause, request *E2SetupRequestMessage) E2SetupResponseMessage {
151 outcome := UnsuccessfulOutcome{}
153 outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs = make([]E2setupFailureIEs, 3)
154 outcome.ProcedureCode = "1"
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,
161 outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].ID = CauseID
162 outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[1].Value.Value = cause
164 outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].ID = TimeToWaitID
165 outcome.Value.E2setupFailure.ProtocolIEs.E2setupFailureIEs[2].Value.Value = timeToWaitMap[timeToWait]
167 return E2SetupResponseMessage{E2APPDU: E2APPDU{Outcome: outcome}}
170 type E2SetupResponseMessage struct {
171 XMLName xml.Name `xml:"E2SetupSuccessResponseMessage"`
172 Text string `xml:",chardata"`
176 type E2APPDU struct {
177 XMLName xml.Name `xml:"E2AP-PDU"`
178 Text string `xml:",chardata"`
182 type SuccessfulOutcome struct {
183 XMLName xml.Name `xml:"successfulOutcome"`
184 Text string `xml:",chardata"`
185 ProcedureCode string `xml:"procedureCode"`
187 Text string `xml:",chardata"`
188 Reject string `xml:"reject"`
189 } `xml:"criticality"`
191 Text string `xml:",chardata"`
192 E2setupResponse struct {
193 Text string `xml:",chardata"`
195 Text string `xml:",chardata"`
196 E2setupResponseIEs []E2setupResponseIEs `xml:"E2setupResponseIEs"`
197 } `xml:"protocolIEs"`
198 } `xml:"E2setupResponse"`
202 type E2setupResponseIEs struct {
203 Text string `xml:",chardata"`
206 Text string `xml:",chardata"`
207 Reject string `xml:"reject"`
208 } `xml:"criticality"`
209 Value interface{} `xml:"value"`
212 type GlobalRICID struct {
213 Text string `xml:",chardata"`
215 Text string `xml:",chardata"`
216 PLMNIdentity string `xml:"pLMN-Identity"`
217 RicID string `xml:"ric-ID"`
218 } `xml:"GlobalRIC-ID"`
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"`
229 type ProtocolIESingleContainer struct {
230 Text string `xml:",chardata"`
233 Text string `xml:",chardata"`
234 Ignore string `xml:"ignore"`
235 } `xml:"criticality"`
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"`
246 type TransID struct {
247 Text string `xml:",chardata"`
248 TransactionID string `xml:"TransactionID"`
251 type TransFailID struct {
252 XMLName xml.Name `xml:"TransactionID"`
253 ID string `xml:",chardata"`
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"`
264 type E2NodeConfigSingleContainer struct {
265 Text string `xml:",chardata"`
268 Text string `xml:",chardata"`
269 Reject string `xml:"reject"`
270 } `xml:"criticality"`
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"`
282 type E2NodeComponentIDResp struct {
283 XMLName xml.Name `xml:"e2nodeComponentID"`
287 type E2nodeConfigUpdateAckResp struct {
288 XMLName xml.Name `xml:"e2nodeComponentConfigurationAck"`
292 type UnsuccessfulOutcome struct {
293 XMLName xml.Name `xml:"unsuccessfulOutcome"`
294 Text string `xml:",chardata"`
295 ProcedureCode string `xml:"procedureCode"`
297 Text string `xml:",chardata"`
298 Reject string `xml:"reject"`
299 } `xml:"criticality"`
301 Text string `xml:",chardata"`
302 E2setupFailure struct {
303 Text string `xml:",chardata"`
305 Text string `xml:",chardata"`
306 E2setupFailureIEs []E2setupFailureIEs `xml:"E2setupFailureIEs"`
307 } `xml:"protocolIEs"`
308 } `xml:"E2setupFailure"`
312 type E2setupFailureIEs struct {
313 Text string `xml:",chardata"`
316 Text string `xml:",chardata"`
317 Ignore string `xml:"ignore"`
318 } `xml:"criticality"`
320 Text string `xml:",chardata"`
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)
334 func convertToRANfunctionID(list *RANfunctionsList, i int) ProtocolIESingleContainer {
335 id := ProtocolIESingleContainer{}
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
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)
353 func convertToE2NodeConfig(list *E2NodeConfigList, i int, outcome int) E2NodeConfigSingleContainer {
354 id := E2NodeConfigSingleContainer{}
355 id.ID = E2nodeConfigAdditionAckItemID
357 id.Value.E2NodeConfigUpdateAckItem.E2nodeConfigUpdateAck.Value = configStatusMap[outcome]
359 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentType = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType
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,
365 } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.XN != nil {
366 ifXn := E2NodeIFTypeXN{}
367 ifXn.GlobalNgENBID.GNB.PLMNID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.GNB.PLMNID
368 ifXn.GlobalNgENBID.GNB.GnbID.GnbID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.GNB.GnbID.GnbID
369 ifXn.GlobalNgENBID.NGENB.PLMNID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.PLMNID
370 ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDMacro = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDMacro
371 ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDShortMacro = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDShortMacro
372 ifXn.GlobalNgENBID.NGENB.GnbID.ENBIDLongMacro = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeXN.GlobalNgENBID.NGENB.GnbID.ENBIDLongMacro
374 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifXn
375 } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.E1 != nil {
376 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeE1{
377 GNBCUCPID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeE1.GNBCUCPID,
379 } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.F1 != nil {
380 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeF1{
381 GNBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeF1.GNBDUID,
383 } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.W1 != nil {
384 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeW1{
385 NGENBDUID: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeW1.NGENBDUID,
387 } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.S1 != nil {
388 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = E2NodeIFTypeS1{
389 MMENAME: list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeS1.MMENAME,
391 } else if list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentType.X2 != nil {
392 ifX2 := E2NodeIFTypeX2{}
393 ifX2.GlobalENBID.PLMNIdentity = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.PLMNIdentity
394 ifX2.GlobalENBID.ENBID.MacroENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.MacroENBID
395 ifX2.GlobalENBID.ENBID.HomeENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.HomeENBID
396 ifX2.GlobalENBID.ENBID.ShortMacroENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.ShortMacroENBID
397 ifX2.GlobalENBID.ENBID.LongMacroENBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalENBID.ENBID.LongMacroENBID
399 ifX2.GlobalEnGNBID.PLMNIdentity = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalEnGNBID.PLMNIdentity
400 ifX2.GlobalEnGNBID.GNBID.GNBID = list.ProtocolIESingleContainer[i].Value.E2nodeConfigAdditionItem.E2nodeComponentID.E2NodeIFTypeX2.GlobalEnGNBID.GNBID.GNBID
402 id.Value.E2NodeConfigUpdateAckItem.E2nodeComponentID.Value = ifX2