blob: b8f49ca4532a9fac927e2cbc6b85095ebbfaf8c5 [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
mpagenko3dbcdd22020-07-22 07:38:45 +0000426 // start go routine for processing of LockState 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()
642 //FlowRemovePending shall only be evaluated in case we are not already waiting for some TechProfile deletion
643 if !oFsm.pUniTechProf.mapUniTpIndication[oFsm.uniTpKey].techProfileToDelete &&
644 oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending() {
645 oFsm.pUniTechProf.mutexTPState.Unlock()
Girish Gowdra26a40922021-01-29 17:14:34 -0800646 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
647 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
648 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
649 pConfigAniStateAFsm := oFsm.pAdaptFsm
650 if pConfigAniStateAFsm != nil {
651 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
652 go func(aPAFsm *AdapterFsm) {
653 if aPAFsm != nil && aPAFsm.pFsm != nil {
654 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvWaitFlowRem)
655 }
656 }(pConfigAniStateAFsm)
657 } else {
658 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
659 }
660 return
661 }
662
mpagenko8b07c1b2020-11-26 10:36:31 +0000663 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000664 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
665 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000666 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000667 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
668 "GemIwTp-entity-id": loGemPortID})
669 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
670
671 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000673 oFsm.pAdaptFsm.commChan, loGemPortID)
674 oFsm.pLastTxMeInstance = meInstance
675}
676
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000678 oFsm.pUniTechProf.mutexTPState.Lock()
679 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
680 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000682 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
683 "GemNCTP-entity-id": loGemPortID})
684 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000686 oFsm.pAdaptFsm.commChan, loGemPortID)
687 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800688 // Mark the gem port to be removed for Performance History monitoring
689 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
690 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(loGemPortID)
691 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000692}
693
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
695 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000696 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
697
698 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
699 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
700 meParams := me.ParamData{
701 EntityID: oFsm.tcont0ID,
702 Attributes: me.AttributeValueMap{
703 "AllocId": unusedTcontAllocID,
704 },
705 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000707 oFsm.pAdaptFsm.commChan, meParams)
708 oFsm.pLastTxMeInstance = meInstance
709}
710
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
712 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000713 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
714
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000716 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
717 oFsm.pLastTxMeInstance = meInstance
718}
719
dbainbri4d3a0dc2020-12-02 00:33:42 +0000720func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
721 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000722 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
723
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000725 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
726 oFsm.pLastTxMeInstance = meInstance
727}
728
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
730 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000731 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
732 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko8b07c1b2020-11-26 10:36:31 +0000734 if oFsm.chanSet {
735 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000736 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000737 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
738 oFsm.chSuccess <- oFsm.procStep
739 oFsm.chanSet = false //reset the internal channel state
740 }
741
742 //let's reset the state machine in order to release all resources now
743 pConfigAniStateAFsm := oFsm.pAdaptFsm
744 if pConfigAniStateAFsm != nil {
745 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
746 go func(aPAFsm *AdapterFsm) {
747 if aPAFsm != nil && aPAFsm.pFsm != nil {
748 _ = aPAFsm.pFsm.Event(aniEvReset)
749 }
750 }(pConfigAniStateAFsm)
751 }
752}
753
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
755 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000756 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000757
mpagenko3dbcdd22020-07-22 07:38:45 +0000758 pConfigAniStateAFsm := oFsm.pAdaptFsm
759 if pConfigAniStateAFsm != nil {
760 // abort running message processing
761 fsmAbortMsg := Message{
762 Type: TestMsg,
763 Data: TestMessage{
764 TestMessageVal: AbortMessageProcessing,
765 },
766 }
767 pConfigAniStateAFsm.commChan <- fsmAbortMsg
768
769 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530770 go func(aPAFsm *AdapterFsm) {
771 if aPAFsm != nil && aPAFsm.pFsm != nil {
772 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000773 }
774 }(pConfigAniStateAFsm)
775 }
776}
777
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
779 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000780 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000781 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000782
mpagenko01e726e2020-10-23 09:45:29 +0000783 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000785}
786
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
788 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000789loop:
790 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000791 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000792 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000793 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530794 message, ok := <-oFsm.pAdaptFsm.commChan
795 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530797 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
798 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
799 break loop
800 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530802
803 switch message.Type {
804 case TestMsg:
805 msg, _ := message.Data.(TestMessage)
806 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000808 break loop
809 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530811 case OMCI:
812 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530814 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530816 "message.Type": message.Type})
817 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000818
Himani Chawla4d908332020-08-31 12:30:20 +0530819 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530821}
822
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530824 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
825 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000827 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530828 return
829 }
830 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
831 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000833 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530834 return
835 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000837 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
838 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
839 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
840 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
841 // maybe we can use just the same eventName for different state transitions like "forward"
842 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
843 switch oFsm.pLastTxMeInstance.GetName() {
844 case "Ieee8021PMapperServiceProfile":
845 { // let the FSM proceed ...
846 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
847 }
848 case "MacBridgePortConfigurationData":
849 { // let the FSM proceed ...
850 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
851 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300852 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
mpagenkofc4f56e2020-11-04 17:17:49 +0000853 { // let aniConfig Multi-Id processing proceed by stopping the wait function
854 oFsm.omciMIdsResponseReceived <- true
855 }
856 }
857 }
858 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530860 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
861 return
862 }
Himani Chawla4d908332020-08-31 12:30:20 +0530863}
864
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530866 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
867 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000869 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530870 return
871 }
872 msgObj, msgOk := msgLayer.(*omci.SetResponse)
873 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000875 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530876 return
877 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530879 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000881 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530882 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
883 return
884 }
mpagenko01e726e2020-10-23 09:45:29 +0000885 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
886 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530887 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
888 // if, then something like:
889 //oFsm.pOnuDB.StoreMe(msgObj)
890
mpagenko01e726e2020-10-23 09:45:29 +0000891 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530892 case "TCont":
893 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000894 if oFsm.requestEventOffset == 0 { //from TCont config request
895 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
896 } else { // from T-Cont reset request
897 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
898 }
Himani Chawla4d908332020-08-31 12:30:20 +0530899 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300900 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
Himani Chawla4d908332020-08-31 12:30:20 +0530901 { // let the PrioQueue init proceed by stopping the wait function
902 oFsm.omciMIdsResponseReceived <- true
903 }
904 case "Ieee8021PMapperServiceProfile":
905 { // let the FSM proceed ...
906 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
907 }
908 }
909 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000910}
911
dbainbri4d3a0dc2020-12-02 00:33:42 +0000912func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000913 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
914 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000915 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000916 log.Fields{"device-id": oFsm.deviceID})
917 return
918 }
919 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
920 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000921 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000922 log.Fields{"device-id": oFsm.deviceID})
923 return
924 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +0000926 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +0000928 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
929 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
930 // store error for mgmt display?
931 return
932 }
933 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
934 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
935 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
936 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
937
938 switch oFsm.pLastTxMeInstance.GetName() {
939 case "GemInterworkingTerminationPoint":
940 { // let the FSM proceed ...
941 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
942 }
943 case "GemPortNetworkCtp":
944 { // let the FSM proceed ...
945 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
946 }
947 case "Ieee8021PMapperServiceProfile":
948 { // let the FSM proceed ...
949 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
950 }
951 case "MacBridgePortConfigurationData":
952 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
953 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
954 }
955 }
956 }
957}
958
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
960 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000961 "msgType": msg.OmciMsg.MessageType})
962
963 switch msg.OmciMsg.MessageType {
964 case omci.CreateResponseType:
965 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530967
mpagenko3dbcdd22020-07-22 07:38:45 +0000968 } //CreateResponseType
969 case omci.SetResponseType:
970 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000971 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000972
mpagenko3dbcdd22020-07-22 07:38:45 +0000973 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000974 case omci.DeleteResponseType:
975 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000976 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +0000977
978 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000979 default:
980 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000981 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000982 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000983 return
984 }
985 }
986}
987
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000989 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
990 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000991 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000992 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
993 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000994 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000995 meParams := me.ParamData{
996 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
997 Attributes: me.AttributeValueMap{
998 "PortId": gemPortAttribs.gemPortID,
999 "TContPointer": oFsm.tcont0ID,
1000 "Direction": gemPortAttribs.direction,
1001 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1002 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1003 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1004 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1005 },
1006 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001007 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001008 oFsm.pAdaptFsm.commChan, meParams)
1009 //accept also nil as (error) return value for writing to LastTx
1010 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001011 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +00001012
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001013 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001015 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001017 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301018 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001019 return
1020 }
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001021 // Mark the gem port to be removed for Performance History monitoring
1022 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
1023 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(gemPortAttribs.gemPortID)
1024 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001025 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001026
1027 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001028 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301029 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001030}
1031
dbainbri4d3a0dc2020-12-02 00:33:42 +00001032func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001033 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1034 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001035 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001036 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1037 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001038 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001039
ozgecanetsia4b232302020-11-11 10:58:10 +03001040 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1041 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001042
1043 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001044 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001045 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001046 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001047 "InterworkingOption": 0, // Don't Care
1048 "ServiceProfilePointer": 0, // Don't Care
1049 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001050 },
1051 }
1052 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1053 true, oFsm.pAdaptFsm.commChan, meParams)
1054 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001055 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001056 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001057 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 logger.Errorw(ctx, "GemTP IW multicast create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001059 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1060 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1061 return
1062 }
1063 ipv4MulticastTable := make([]uint8, 12)
1064 //Gem Port ID
1065 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1066 //Secondary Key
1067 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1068 // Multicast IP range start This is the 224.0.0.1 address
1069 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1070 // MulticastIp range stop
1071 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1072
1073 meIPV4MCTableParams := me.ParamData{
1074 EntityID: gemPortAttribs.multicastGemID,
1075 Attributes: me.AttributeValueMap{
1076 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1077 },
1078 }
1079 meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1080 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
1081 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
ozgecanetsia4b232302020-11-11 10:58:10 +03001082
1083 } else {
1084 meParams := me.ParamData{
1085 EntityID: gemPortAttribs.gemPortID,
1086 Attributes: me.AttributeValueMap{
1087 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1088 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1089 "ServiceProfilePointer": oFsm.mapperSP0ID,
1090 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1091 "GalProfilePointer": galEthernetEID,
1092 },
1093 }
1094 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
1095 oFsm.pAdaptFsm.commChan, meParams)
1096 //accept also nil as (error) return value for writing to LastTx
1097 // - this avoids misinterpretation of new received OMCI messages
1098 oFsm.pLastTxMeInstance = meInstance
1099 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001100 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001102 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001103 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001104 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301105 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001106 return
1107 }
1108 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001109
1110 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301112 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001113}
1114
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001116 const cu16StrictPrioWeight uint16 = 0xFFFF
1117 //find all upstream PrioQueues related to this T-Cont
1118 loQueueMap := ordered_map.NewOrderedMap()
1119 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001120 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001122 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1123 "prioString": gemPortAttribs.pbitString})
1124 continue
1125 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001126 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301127 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001128 //key does not yet exist
1129 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1130 }
1131 } else {
1132 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1133 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001134 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001135
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001136 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1137 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1138 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1139 // or even be finished without correct SP/WRR setting
1140
1141 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1142 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1143 // even though its T-Cont seems to be wrong ...
1144 loTrafficSchedulerEID := 0x8000
1145 //for all found queues
1146 iter := loQueueMap.IterFunc()
1147 for kv, ok := iter(); ok; kv, ok = iter() {
1148 queueIndex := (kv.Key).(uint16)
1149 meParams := me.ParamData{
1150 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301151 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001152 }
1153 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1154 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001156 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001157 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001158 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1159 } else {
1160 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001161 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001162 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1163 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001164 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001165 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1166 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1167 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001168 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001169 oFsm.pAdaptFsm.commChan, meParams)
1170 //accept also nil as (error) return value for writing to LastTx
1171 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001172 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001173
1174 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001176 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001177 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001178 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301179 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001180 return
1181 }
1182
1183 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1184 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1185 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1186 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1187
1188 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001189
1190 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001191 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301192 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001193}
1194
dbainbri4d3a0dc2020-12-02 00:33:42 +00001195func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001196 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301197 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001198 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001199 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001200 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 +00001201 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001202 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001203 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301204 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Debug(ctx, "uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001206 return nil
1207 }
1208 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001209 logger.Warnw(ctx, "uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001210 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001211 }
1212}