blob: 742a0ab27af2ec13eca32becdb959e32bca0c0ca [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
26 "time"
27
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000028 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000029 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/opencord/omci-lib-go"
31 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/log"
33 //ic "github.com/opencord/voltha-protos/v4/go/inter_container"
34 //"github.com/opencord/voltha-protos/v4/go/openflow_13"
35 //"github.com/opencord/voltha-protos/v4/go/voltha"
mpagenko3dbcdd22020-07-22 07:38:45 +000036)
37
mpagenko1cc3cb42020-07-27 15:24:38 +000038const (
39 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000040 aniEvStart = "aniEvStart"
41 aniEvStartConfig = "aniEvStartConfig"
42 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
43 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
44 aniEvRxTcontsResp = "aniEvRxTcontsResp"
45 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
46 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
47 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
48 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
49 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080050 aniEvWaitFlowRem = "aniEvWaitFlowRem"
51 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000052 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
53 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
54 aniEvRemTcontPath = "aniEvRemTcontPath"
55 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
56 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
57 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
58 aniEvTimeoutSimple = "aniEvTimeoutSimple"
59 aniEvTimeoutMids = "aniEvTimeoutMids"
60 aniEvReset = "aniEvReset"
61 aniEvRestart = "aniEvRestart"
mpagenko1cc3cb42020-07-27 15:24:38 +000062)
63const (
64 // states of config PON ANI port FSM
65 aniStDisabled = "aniStDisabled"
66 aniStStarting = "aniStStarting"
67 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
68 aniStCreatingMBPCD = "aniStCreatingMBPCD"
69 aniStSettingTconts = "aniStSettingTconts"
70 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
71 aniStCreatingGemIWs = "aniStCreatingGemIWs"
72 aniStSettingPQs = "aniStSettingPQs"
73 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
74 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000075 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080076 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000077 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
78 aniStResetTcont = "aniStResetTcont"
79 aniStRemDot1PMapper = "aniStRemDot1PMapper"
80 aniStRemAniBPCD = "aniStRemAniBPCD"
81 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000082 aniStResetting = "aniStResetting"
83)
Holger Hildebrandt10d98192021-01-27 15:29:31 +000084const cAniFsmIdleState = aniStConfigDone
mpagenko1cc3cb42020-07-27 15:24:38 +000085
Girish Gowdra041dcb32020-11-16 16:54:30 -080086const (
87 tpIDOffset = 64
88)
89
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000090type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030091 gemPortID uint16
92 upQueueID uint16
93 downQueueID uint16
94 direction uint8
95 qosPolicy string
96 weight uint8
97 pbitString string
98 isMulticast bool
99 multicastGemID uint16
100 staticACL string
101 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000102}
103
Himani Chawla6d2ae152020-09-02 13:11:20 +0530104//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
105type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000106 pDeviceHandler *deviceHandler
107 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530108 pOmciCC *omciCC
109 pOnuUniPort *onuUniPort
110 pUniTechProf *onuUniTechProf
111 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800112 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000113 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000114 requestEvent OnuDeviceEvent
Himani Chawla4d908332020-08-31 12:30:20 +0530115 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000116 pAdaptFsm *AdapterFsm
117 chSuccess chan<- uint8
118 procStep uint8
119 chanSet bool
120 mapperSP0ID uint16
121 macBPCD0ID uint16
122 tcont0ID uint16
123 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000124 gemPortAttribsSlice []ponAniGemPortAttribs
mpagenko01e726e2020-10-23 09:45:29 +0000125 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000126 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenko3dbcdd22020-07-22 07:38:45 +0000127}
128
Himani Chawla6d2ae152020-09-02 13:11:20 +0530129//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000130func newUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800131 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000132 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530133 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000134 pDeviceHandler: apDeviceHandler,
135 deviceID: apDeviceHandler.deviceID,
136 pOmciCC: apDevOmciCC,
137 pOnuUniPort: apUniPort,
138 pUniTechProf: apUniTechProf,
139 pOnuDB: apOnuDB,
140 techProfileID: aTechProfileID,
141 requestEvent: aRequestEvent,
142 chanSet: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000143 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000144 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
145
mpagenko01e726e2020-10-23 09:45:29 +0000146 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000147 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000148 logger.Errorw(ctx, "uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000149 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000150 return nil
151 }
152
153 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000154 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000155 fsm.Events{
156
mpagenko1cc3cb42020-07-27 15:24:38 +0000157 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000158
159 //Note: .1p-Mapper and MBPCD might also have multi instances (per T-Cont) - by now only one 1 T-Cont considered!
mpagenko1cc3cb42020-07-27 15:24:38 +0000160 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000161 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000162 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
163 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000164 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000165 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000166 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000167 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000168 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000169 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000170 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000171
mpagenko8b07c1b2020-11-26 10:36:31 +0000172 //for removing Gem related resources
173 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800174 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
175 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000176 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
177 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStConfigDone},
178
179 //for removing TCONT related resources
180 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
181 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStRemDot1PMapper},
182 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
183 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
184
185 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
186 aniStRemovingGemIW, aniStRemovingGemNCTP,
187 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000188 {Name: aniEvTimeoutMids, Src: []string{
189 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000190
mpagenko1cc3cb42020-07-27 15:24:38 +0000191 // exceptional treatment for all states except aniStResetting
192 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
193 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
mpagenko8b07c1b2020-11-26 10:36:31 +0000194 aniStConfigDone, aniStRemovingGemIW, aniStRemovingGemNCTP,
195 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000196 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000197 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
mpagenko3dbcdd22020-07-22 07:38:45 +0000198 },
199
200 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000201 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
202 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
203 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
204 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
205 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
206 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
207 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
208 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
209 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
210 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
211 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
212 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
213 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
214 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
215 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
216 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
217 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
218 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000219 },
220 )
221 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000222 logger.Errorw(ctx, "uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000223 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000224 return nil
225 }
226
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 logger.Debugw(ctx, "uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000228 return instFsm
229}
230
Himani Chawla6d2ae152020-09-02 13:11:20 +0530231//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
232func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000233 oFsm.chSuccess = aChSuccess
234 oFsm.procStep = aProcStep
235 oFsm.chanSet = true
236}
237
dbainbri4d3a0dc2020-12-02 00:33:42 +0000238func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530239 if aPAFsm != nil && aPAFsm.pFsm != nil {
240 //stick to pythonAdapter numbering scheme
241 //index 0 in naming refers to possible usage of multiple instances (later)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800242 oFsm.mapperSP0ID = ieeeMapperServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) + uint16(oFsm.techProfileID)
243 oFsm.macBPCD0ID = macBridgePortAniEID + uint16(oFsm.pOnuUniPort.entityID) + uint16(oFsm.techProfileID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530244
Girish Gowdra041dcb32020-11-16 16:54:30 -0800245 /*
246 // Find a free TCONT Instance ID and use it
247 foundFreeTcontInstID := false
248 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000249 if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.TContClassID); len(tcontInstKeys) > 0 {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800250
251 // FIXME: Ideally the ME configurations on the ONU should constantly be MIB Synced back to the ONU DB
252 // So, as soon as we use up a TCONT Entity on the ONU, the DB at ONU adapter should know that the TCONT
253 // entity is used up via MIB Sync procedure and it will not use it for subsequent TCONT on that ONU.
254 // But, it seems, due to the absence of the constant mib-sync procedure, the TCONT Entities show up as
255 // free even though they are already reserved on the ONU. It seems the mib is synced only once, initially
256 // when the ONU is discovered.
257 /*
258 for _, tcontInstID := range tcontInstKeys {
259 tconInst := oFsm.pOnuDB.GetMe(me.TContClassID, tcontInstID)
260 returnVal := tconInst["AllocId"]
261 if returnVal != nil {
262 if allocID, err := oFsm.pOnuDB.getUint16Attrib(returnVal); err == nil {
263 // If the TCONT Instance ID is set to 0xff or 0xffff, it means it is free to use.
264 if allocID == 0xff || allocID == 0xffff {
265 foundFreeTcontInstID = true
266 oFsm.tcont0ID = uint16(tcontInstID)
267 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
268 "device-id": oFsm.deviceID})
269 break
270 }
271 } else {
272 logger.Errorw("error-converting-alloc-id-to-uint16", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
273 }
274 } else {
275 logger.Errorw("error-extracting-alloc-id-attribute", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
276 }
277 }
278 */
279
280 // Ensure that the techProfileID is in a valid range so that we can allocate a free Tcont for it.
281 if oFsm.techProfileID >= tpIDOffset && oFsm.techProfileID < uint8(tpIDOffset+len(tcontInstKeys)) {
282 // For now, as a dirty workaround, use the tpIDOffset to index the TcontEntityID to be used.
283 // The first TP ID for the ONU will get the first TcontEntityID, the next will get second and so on.
284 // Here the assumption is TP ID will always start from 64 (this is also true to Technology Profile Specification) and the
285 // TP ID will increment in single digit
286 oFsm.tcont0ID = tcontInstKeys[oFsm.techProfileID-tpIDOffset]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 logger.Debugw(ctx, "Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800288 "device-id": oFsm.deviceID})
289 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 logger.Errorw(ctx, "tech profile id not in valid range", log.Fields{"device-id": oFsm.deviceID, "tp-id": oFsm.techProfileID, "num-tcont": len(tcontInstKeys)})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800291 if oFsm.chanSet {
292 // indicate processing error/abort to the caller
293 oFsm.chSuccess <- 0
294 oFsm.chanSet = false //reset the internal channel state
295 }
296 //reset the state machine to enable usage on subsequent requests
297 _ = aPAFsm.pFsm.Event(aniEvReset)
298 return
299 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530300 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800302 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530303 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800304 /*
305 if !foundFreeTcontInstID {
306 // This should never happen. If it does, the behavior is unpredictable.
307 logger.Warnw("No free TCONT instances found", log.Fields{"device-id": oFsm.deviceID})
308 }*/
309
310 // Access critical state with lock
311 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000312 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
313 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
Girish Gowdra041dcb32020-11-16 16:54:30 -0800314 oFsm.pUniTechProf.mutexTPState.Unlock()
315
Himani Chawla26e555c2020-08-31 12:30:20 +0530316 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800317 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300318 loGemPortAttribs := ponAniGemPortAttribs{}
319
Himani Chawla26e555c2020-08-31 12:30:20 +0530320 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
321
dbainbri4d3a0dc2020-12-02 00:33:42 +0000322 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530323
324 loGemPortAttribs.gemPortID = gemEntry.gemPortID
325 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
326 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
327 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
328 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
329
330 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
331 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
332 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
333 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
334 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
335 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
336
337 usQueueFound := false
338 dsQueueFound := false
339 for _, mgmtEntityID := range queueInstKeys {
340 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
341 returnVal := meAttributes["RelatedPort"]
342 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530343 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530344 if relatedPort == usQrelPortMask {
345 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000347 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 usQueueFound = true
349 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
350 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000351 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000352 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530353 dsQueueFound = true
354 }
355 if usQueueFound && dsQueueFound {
356 break
357 }
358 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 }
361 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000362 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 }
364 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000366 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 }
368 }
369 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530371 }
372 loGemPortAttribs.direction = gemEntry.direction
373 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
374 loGemPortAttribs.weight = gemEntry.queueWeight
375 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia4b232302020-11-11 10:58:10 +0300376 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300377 //TODO this might effectively ignore the for loop starting at line 316
378 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300379 loGemPortAttribs.isMulticast = true
380 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
381 loGemPortAttribs.staticACL = gemEntry.staticACL
382 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530383
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300385 "gemPortID": loGemPortAttribs.gemPortID,
386 "isMulticast": loGemPortAttribs.isMulticast,
387 "multicastGemID": loGemPortAttribs.multicastGemID,
388 "staticACL": loGemPortAttribs.staticACL,
389 "dynamicACL": loGemPortAttribs.dynamicACL,
390 })
391
392 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000393 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300394 "gemPortID": loGemPortAttribs.gemPortID,
395 "upQueueID": loGemPortAttribs.upQueueID,
396 "downQueueID": loGemPortAttribs.downQueueID,
397 "pbitString": loGemPortAttribs.pbitString,
398 "prioQueueIndex": gemEntry.prioQueueIndex,
399 })
400 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530401
402 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
403 }
404 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
405 }
406}
407
dbainbri4d3a0dc2020-12-02 00:33:42 +0000408func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
409 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000410 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000411 // in case the used channel is not yet defined (can be re-used after restarts)
412 if oFsm.omciMIdsResponseReceived == nil {
413 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000415 } else {
416 // as we may 're-use' this instance of FSM and the connected channel
417 // make sure there is no 'lingering' request in the already existing channel:
418 // (simple loop sufficient as we are the only receiver)
419 for len(oFsm.omciMIdsResponseReceived) > 0 {
420 <-oFsm.omciMIdsResponseReceived
421 }
422 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000423 //ensure internal slices are empty (which might be set from previous run) - release memory
424 oFsm.gemPortAttribsSlice = nil
425
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000426 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000428
429 //let the state machine run forward from here directly
430 pConfigAniStateAFsm := oFsm.pAdaptFsm
431 if pConfigAniStateAFsm != nil {
432 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000434
mpagenko3dbcdd22020-07-22 07:38:45 +0000435 }
436}
437
dbainbri4d3a0dc2020-12-02 00:33:42 +0000438func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
439 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000440 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000441 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
442 oFsm.requestEventOffset = 0 //0 offset for last config request activity
dbainbri4d3a0dc2020-12-02 00:33:42 +0000443 meInstance := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000444 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
445 //accept also nil as (error) return value for writing to LastTx
446 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000447 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000448}
449
dbainbri4d3a0dc2020-12-02 00:33:42 +0000450func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
451 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000452 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
453 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000454 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000455 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
456 meParams := me.ParamData{
457 EntityID: oFsm.macBPCD0ID,
458 Attributes: me.AttributeValueMap{
459 "BridgeIdPointer": bridgePtr,
460 "PortNum": 0xFF, //fixed unique ANI side indication
461 "TpType": 3, //for .1PMapper
462 "TpPointer": oFsm.mapperSP0ID,
463 },
464 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000465 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000466 oFsm.pAdaptFsm.commChan, meParams)
467 //accept also nil as (error) return value for writing to LastTx
468 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000469 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000470}
471
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
473 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000474 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
475 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000476 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000477 meParams := me.ParamData{
478 EntityID: oFsm.tcont0ID,
479 Attributes: me.AttributeValueMap{
480 "AllocId": oFsm.alloc0ID,
481 },
482 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000484 oFsm.pAdaptFsm.commChan, meParams)
485 //accept also nil as (error) return value for writing to LastTx
486 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000487 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000488}
489
dbainbri4d3a0dc2020-12-02 00:33:42 +0000490func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
491 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000492 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000494}
495
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
497 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000498 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000500}
501
dbainbri4d3a0dc2020-12-02 00:33:42 +0000502func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
503 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000504 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000505 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000506}
507
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300509
dbainbri4d3a0dc2020-12-02 00:33:42 +0000510 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000511 "toGemIw": 1024, /* cmp above */
512 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000513
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000515 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000516 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000517
mpagenko3dbcdd22020-07-22 07:38:45 +0000518 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000519 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530520 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000521 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000522
523 //assign the GemPorts according to the configured Prio
524 var loPrioGemPortArray [8]uint16
525 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300526 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300528 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
529 "prioString": gemPortAttribs.pbitString})
530 continue
531 }
532 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300534 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
535 "prioString": gemPortAttribs.pbitString})
536 continue
537 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000538 for i := 0; i < 8; i++ {
539 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
540 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
541 if prio == 1 { // Check this p-bit is set
542 if loPrioGemPortArray[i] == 0 {
543 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
544 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000545 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000546 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000547 "SetGemPort": loPrioGemPortArray[i]})
548 }
549 }
550 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000552 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000553 "prioString": gemPortAttribs.pbitString, "position": i})
554 }
555
556 }
557 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300558
ozgecanetsia4b232302020-11-11 10:58:10 +0300559 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530560 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300561 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530562 if value != 0 {
563 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530564 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000565 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000566 "for Prio": index,
567 "IwPtr": strconv.FormatInt(int64(value), 16),
568 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300569 } else {
570 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000571 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
572 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300573 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530574 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000575 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300576 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000577 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
578 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300579 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530580
581 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000582 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000583 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300584 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
585 // this reset needs to be performed only if the tech profile provides upstream gem ports but no priority is set
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000586 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300587 //pConfigAniStateAFsm := oFsm.pAdaptFsm
588 //if pConfigAniStateAFsm != nil {
589 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
590 // go func(aPAFsm *AdapterFsm) {
591 // if aPAFsm != nil && aPAFsm.pFsm != nil {
592 // _ = aPAFsm.pFsm.Event(aniEvReset)
593 // }
594 // }(pConfigAniStateAFsm)
595 //}
596 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000597 pConfigAniStateAFsm := oFsm.pAdaptFsm
598 if pConfigAniStateAFsm != nil {
599 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530600 go func(aPAFsm *AdapterFsm) {
601 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300602 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000603 }
604 }(pConfigAniStateAFsm)
605 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300606 } else {
607 meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
608 oFsm.pAdaptFsm.commChan, meParams)
609 //accept also nil as (error) return value for writing to LastTx
610 // - this avoids misinterpretation of new received OMCI messages
611 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000612 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000613}
614
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
616 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000617 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000618 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko01e726e2020-10-23 09:45:29 +0000620 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800621 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko01e726e2020-10-23 09:45:29 +0000622 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
mpagenko8b07c1b2020-11-26 10:36:31 +0000623 // but only in case the techProfile was configured (not deleted)
624 if oFsm.requestEventOffset == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000625 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
mpagenko8b07c1b2020-11-26 10:36:31 +0000626 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000627
mpagenko01e726e2020-10-23 09:45:29 +0000628 if oFsm.chanSet {
629 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000631 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
632 oFsm.chSuccess <- oFsm.procStep
633 oFsm.chanSet = false //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000634 }
mpagenko01e726e2020-10-23 09:45:29 +0000635
636 //the FSM is left active in this state as long as no specific reset or remove is requested from outside
mpagenko3dbcdd22020-07-22 07:38:45 +0000637}
638
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -0800640
mpagenkoa23a6292021-02-23 10:40:10 +0000641 oFsm.pUniTechProf.mutexTPState.Lock()
Girish Gowdra9085bca2021-03-08 12:57:48 -0800642 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending() {
mpagenkoa23a6292021-02-23 10:40:10 +0000643 oFsm.pUniTechProf.mutexTPState.Unlock()
Girish Gowdra26a40922021-01-29 17:14:34 -0800644 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
645 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
646 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
647 pConfigAniStateAFsm := oFsm.pAdaptFsm
648 if pConfigAniStateAFsm != nil {
649 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
650 go func(aPAFsm *AdapterFsm) {
651 if aPAFsm != nil && aPAFsm.pFsm != nil {
652 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvWaitFlowRem)
653 }
654 }(pConfigAniStateAFsm)
655 } else {
656 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
657 }
658 return
659 }
660
mpagenko8b07c1b2020-11-26 10:36:31 +0000661 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000662 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
663 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000664 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000665 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
666 "GemIwTp-entity-id": loGemPortID})
667 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
668
669 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000671 oFsm.pAdaptFsm.commChan, loGemPortID)
672 oFsm.pLastTxMeInstance = meInstance
673}
674
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000676 oFsm.pUniTechProf.mutexTPState.Lock()
677 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
678 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000680 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
681 "GemNCTP-entity-id": loGemPortID})
682 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000684 oFsm.pAdaptFsm.commChan, loGemPortID)
685 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800686 // Mark the gem port to be removed for Performance History monitoring
687 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
688 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(loGemPortID)
689 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000690}
691
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
693 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000694 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
695
696 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
697 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
698 meParams := me.ParamData{
699 EntityID: oFsm.tcont0ID,
700 Attributes: me.AttributeValueMap{
701 "AllocId": unusedTcontAllocID,
702 },
703 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000705 oFsm.pAdaptFsm.commChan, meParams)
706 oFsm.pLastTxMeInstance = meInstance
707}
708
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
710 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000711 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
712
dbainbri4d3a0dc2020-12-02 00:33:42 +0000713 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000714 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
715 oFsm.pLastTxMeInstance = meInstance
716}
717
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
719 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000720 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
721
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000723 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
724 oFsm.pLastTxMeInstance = meInstance
725}
726
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
728 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000729 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
730 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko8b07c1b2020-11-26 10:36:31 +0000732 if oFsm.chanSet {
733 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000735 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
736 oFsm.chSuccess <- oFsm.procStep
737 oFsm.chanSet = false //reset the internal channel state
738 }
739
740 //let's reset the state machine in order to release all resources now
741 pConfigAniStateAFsm := oFsm.pAdaptFsm
742 if pConfigAniStateAFsm != nil {
743 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
744 go func(aPAFsm *AdapterFsm) {
745 if aPAFsm != nil && aPAFsm.pFsm != nil {
746 _ = aPAFsm.pFsm.Event(aniEvReset)
747 }
748 }(pConfigAniStateAFsm)
749 }
750}
751
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
753 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000754 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000755
mpagenko3dbcdd22020-07-22 07:38:45 +0000756 pConfigAniStateAFsm := oFsm.pAdaptFsm
757 if pConfigAniStateAFsm != nil {
758 // abort running message processing
759 fsmAbortMsg := Message{
760 Type: TestMsg,
761 Data: TestMessage{
762 TestMessageVal: AbortMessageProcessing,
763 },
764 }
765 pConfigAniStateAFsm.commChan <- fsmAbortMsg
766
767 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530768 go func(aPAFsm *AdapterFsm) {
769 if aPAFsm != nil && aPAFsm.pFsm != nil {
770 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000771 }
772 }(pConfigAniStateAFsm)
773 }
774}
775
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
777 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000778 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000779 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000780
mpagenko01e726e2020-10-23 09:45:29 +0000781 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000783}
784
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
786 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000787loop:
788 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000789 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000790 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000791 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530792 message, ok := <-oFsm.pAdaptFsm.commChan
793 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530795 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
796 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
797 break loop
798 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530800
801 switch message.Type {
802 case TestMsg:
803 msg, _ := message.Data.(TestMessage)
804 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000806 break loop
807 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530809 case OMCI:
810 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000811 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530812 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530814 "message.Type": message.Type})
815 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000816
Himani Chawla4d908332020-08-31 12:30:20 +0530817 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530819}
820
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530822 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
823 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000825 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530826 return
827 }
828 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
829 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000831 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530832 return
833 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000835 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
836 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
837 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
838 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
839 // maybe we can use just the same eventName for different state transitions like "forward"
840 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
841 switch oFsm.pLastTxMeInstance.GetName() {
842 case "Ieee8021PMapperServiceProfile":
843 { // let the FSM proceed ...
844 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
845 }
846 case "MacBridgePortConfigurationData":
847 { // let the FSM proceed ...
848 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
849 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300850 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
mpagenkofc4f56e2020-11-04 17:17:49 +0000851 { // let aniConfig Multi-Id processing proceed by stopping the wait function
852 oFsm.omciMIdsResponseReceived <- true
853 }
854 }
855 }
856 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000857 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530858 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
859 return
860 }
Himani Chawla4d908332020-08-31 12:30:20 +0530861}
862
dbainbri4d3a0dc2020-12-02 00:33:42 +0000863func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530864 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
865 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000867 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530868 return
869 }
870 msgObj, msgOk := msgLayer.(*omci.SetResponse)
871 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000873 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530874 return
875 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530877 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000879 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530880 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
881 return
882 }
mpagenko01e726e2020-10-23 09:45:29 +0000883 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
884 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530885 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
886 // if, then something like:
887 //oFsm.pOnuDB.StoreMe(msgObj)
888
mpagenko01e726e2020-10-23 09:45:29 +0000889 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530890 case "TCont":
891 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000892 if oFsm.requestEventOffset == 0 { //from TCont config request
893 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
894 } else { // from T-Cont reset request
895 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
896 }
Himani Chawla4d908332020-08-31 12:30:20 +0530897 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300898 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
Himani Chawla4d908332020-08-31 12:30:20 +0530899 { // let the PrioQueue init proceed by stopping the wait function
900 oFsm.omciMIdsResponseReceived <- true
901 }
902 case "Ieee8021PMapperServiceProfile":
903 { // let the FSM proceed ...
904 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
905 }
906 }
907 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000908}
909
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000911 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
912 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000913 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000914 log.Fields{"device-id": oFsm.deviceID})
915 return
916 }
917 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
918 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000919 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000920 log.Fields{"device-id": oFsm.deviceID})
921 return
922 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +0000924 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +0000926 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
927 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
928 // store error for mgmt display?
929 return
930 }
931 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
932 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
933 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
934 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
935
936 switch oFsm.pLastTxMeInstance.GetName() {
937 case "GemInterworkingTerminationPoint":
938 { // let the FSM proceed ...
939 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
940 }
941 case "GemPortNetworkCtp":
942 { // let the FSM proceed ...
943 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
944 }
945 case "Ieee8021PMapperServiceProfile":
946 { // let the FSM proceed ...
947 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
948 }
949 case "MacBridgePortConfigurationData":
950 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
951 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
952 }
953 }
954 }
955}
956
dbainbri4d3a0dc2020-12-02 00:33:42 +0000957func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
958 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000959 "msgType": msg.OmciMsg.MessageType})
960
961 switch msg.OmciMsg.MessageType {
962 case omci.CreateResponseType:
963 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530965
mpagenko3dbcdd22020-07-22 07:38:45 +0000966 } //CreateResponseType
967 case omci.SetResponseType:
968 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000970
mpagenko3dbcdd22020-07-22 07:38:45 +0000971 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000972 case omci.DeleteResponseType:
973 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000974 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +0000975
976 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000977 default:
978 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000979 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000980 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000981 return
982 }
983 }
984}
985
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000987 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
988 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000990 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
991 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000992 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000993 meParams := me.ParamData{
994 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
995 Attributes: me.AttributeValueMap{
996 "PortId": gemPortAttribs.gemPortID,
997 "TContPointer": oFsm.tcont0ID,
998 "Direction": gemPortAttribs.direction,
999 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1000 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1001 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1002 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1003 },
1004 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001005 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001006 oFsm.pAdaptFsm.commChan, meParams)
1007 //accept also nil as (error) return value for writing to LastTx
1008 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001009 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +00001010
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001011 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001013 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001015 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301016 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001017 return
1018 }
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001019 // Mark the gem port to be removed for Performance History monitoring
1020 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
1021 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(gemPortAttribs.gemPortID)
1022 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001023 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001024
1025 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001026 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301027 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001028}
1029
dbainbri4d3a0dc2020-12-02 00:33:42 +00001030func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001031 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1032 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001033 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001034 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1035 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001036 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001037
ozgecanetsia4b232302020-11-11 10:58:10 +03001038 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1039 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001040
1041 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001042 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001043 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001044 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001045 "InterworkingOption": 0, // Don't Care
1046 "ServiceProfilePointer": 0, // Don't Care
1047 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001048 },
1049 }
1050 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1051 true, oFsm.pAdaptFsm.commChan, meParams)
1052 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001053 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001054 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001055 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001056 logger.Errorw(ctx, "GemTP IW multicast create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001057 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1058 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1059 return
1060 }
1061 ipv4MulticastTable := make([]uint8, 12)
1062 //Gem Port ID
1063 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1064 //Secondary Key
1065 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1066 // Multicast IP range start This is the 224.0.0.1 address
1067 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1068 // MulticastIp range stop
1069 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1070
1071 meIPV4MCTableParams := me.ParamData{
1072 EntityID: gemPortAttribs.multicastGemID,
1073 Attributes: me.AttributeValueMap{
1074 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1075 },
1076 }
1077 meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1078 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
1079 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
ozgecanetsia4b232302020-11-11 10:58:10 +03001080
1081 } else {
1082 meParams := me.ParamData{
1083 EntityID: gemPortAttribs.gemPortID,
1084 Attributes: me.AttributeValueMap{
1085 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1086 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1087 "ServiceProfilePointer": oFsm.mapperSP0ID,
1088 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1089 "GalProfilePointer": galEthernetEID,
1090 },
1091 }
1092 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
1093 oFsm.pAdaptFsm.commChan, meParams)
1094 //accept also nil as (error) return value for writing to LastTx
1095 // - this avoids misinterpretation of new received OMCI messages
1096 oFsm.pLastTxMeInstance = meInstance
1097 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001098 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001100 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001102 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301103 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001104 return
1105 }
1106 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001107
1108 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301110 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001111}
1112
dbainbri4d3a0dc2020-12-02 00:33:42 +00001113func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001114 const cu16StrictPrioWeight uint16 = 0xFFFF
1115 //find all upstream PrioQueues related to this T-Cont
1116 loQueueMap := ordered_map.NewOrderedMap()
1117 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001118 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001120 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1121 "prioString": gemPortAttribs.pbitString})
1122 continue
1123 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001124 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301125 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001126 //key does not yet exist
1127 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1128 }
1129 } else {
1130 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1131 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001132 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001133
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001134 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1135 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1136 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1137 // or even be finished without correct SP/WRR setting
1138
1139 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1140 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1141 // even though its T-Cont seems to be wrong ...
1142 loTrafficSchedulerEID := 0x8000
1143 //for all found queues
1144 iter := loQueueMap.IterFunc()
1145 for kv, ok := iter(); ok; kv, ok = iter() {
1146 queueIndex := (kv.Key).(uint16)
1147 meParams := me.ParamData{
1148 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301149 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001150 }
1151 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1152 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001154 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001155 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001156 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1157 } else {
1158 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001160 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1161 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001162 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001163 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1164 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1165 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001166 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001167 oFsm.pAdaptFsm.commChan, meParams)
1168 //accept also nil as (error) return value for writing to LastTx
1169 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001170 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001171
1172 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001174 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001176 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301177 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001178 return
1179 }
1180
1181 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1182 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1183 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1184 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1185
1186 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001187
1188 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001189 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301190 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001191}
1192
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001194 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301195 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001196 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001197 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001198 case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
dbainbri4d3a0dc2020-12-02 00:33:42 +00001199 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001200 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001201 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301202 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001203 logger.Debug(ctx, "uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001204 return nil
1205 }
1206 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001207 logger.Warnw(ctx, "uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001208 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001209 }
1210}