blob: 03bf9ea875ffe27bf678cb291ce0d781f72eed83 [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
641 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending() {
642 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
643 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
644 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
645 pConfigAniStateAFsm := oFsm.pAdaptFsm
646 if pConfigAniStateAFsm != nil {
647 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
648 go func(aPAFsm *AdapterFsm) {
649 if aPAFsm != nil && aPAFsm.pFsm != nil {
650 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvWaitFlowRem)
651 }
652 }(pConfigAniStateAFsm)
653 } else {
654 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
655 }
656 return
657 }
658
mpagenko8b07c1b2020-11-26 10:36:31 +0000659 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
660 oFsm.pUniTechProf.mutexTPState.Lock()
661 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
662 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000664 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
665 "GemIwTp-entity-id": loGemPortID})
666 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
667
668 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000669 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000670 oFsm.pAdaptFsm.commChan, loGemPortID)
671 oFsm.pLastTxMeInstance = meInstance
672}
673
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000675 oFsm.pUniTechProf.mutexTPState.Lock()
676 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
677 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000679 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
680 "GemNCTP-entity-id": loGemPortID})
681 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000683 oFsm.pAdaptFsm.commChan, loGemPortID)
684 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800685 // Mark the gem port to be removed for Performance History monitoring
686 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
687 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(loGemPortID)
688 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000689}
690
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
692 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000693 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
694
695 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
696 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
697 meParams := me.ParamData{
698 EntityID: oFsm.tcont0ID,
699 Attributes: me.AttributeValueMap{
700 "AllocId": unusedTcontAllocID,
701 },
702 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000704 oFsm.pAdaptFsm.commChan, meParams)
705 oFsm.pLastTxMeInstance = meInstance
706}
707
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
709 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000710 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
711
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000713 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
714 oFsm.pLastTxMeInstance = meInstance
715}
716
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
718 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000719 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
720
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000722 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
723 oFsm.pLastTxMeInstance = meInstance
724}
725
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
727 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000728 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
729 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko8b07c1b2020-11-26 10:36:31 +0000731 if oFsm.chanSet {
732 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000734 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
735 oFsm.chSuccess <- oFsm.procStep
736 oFsm.chanSet = false //reset the internal channel state
737 }
738
739 //let's reset the state machine in order to release all resources now
740 pConfigAniStateAFsm := oFsm.pAdaptFsm
741 if pConfigAniStateAFsm != nil {
742 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
743 go func(aPAFsm *AdapterFsm) {
744 if aPAFsm != nil && aPAFsm.pFsm != nil {
745 _ = aPAFsm.pFsm.Event(aniEvReset)
746 }
747 }(pConfigAniStateAFsm)
748 }
749}
750
dbainbri4d3a0dc2020-12-02 00:33:42 +0000751func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
752 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000753 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000754
mpagenko3dbcdd22020-07-22 07:38:45 +0000755 pConfigAniStateAFsm := oFsm.pAdaptFsm
756 if pConfigAniStateAFsm != nil {
757 // abort running message processing
758 fsmAbortMsg := Message{
759 Type: TestMsg,
760 Data: TestMessage{
761 TestMessageVal: AbortMessageProcessing,
762 },
763 }
764 pConfigAniStateAFsm.commChan <- fsmAbortMsg
765
766 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530767 go func(aPAFsm *AdapterFsm) {
768 if aPAFsm != nil && aPAFsm.pFsm != nil {
769 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000770 }
771 }(pConfigAniStateAFsm)
772 }
773}
774
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
776 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000777 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000778 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000779
mpagenko01e726e2020-10-23 09:45:29 +0000780 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000782}
783
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
785 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000786loop:
787 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000788 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000789 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000790 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530791 message, ok := <-oFsm.pAdaptFsm.commChan
792 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530794 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
795 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
796 break loop
797 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530799
800 switch message.Type {
801 case TestMsg:
802 msg, _ := message.Data.(TestMessage)
803 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000805 break loop
806 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530808 case OMCI:
809 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530811 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530813 "message.Type": message.Type})
814 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000815
Himani Chawla4d908332020-08-31 12:30:20 +0530816 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530818}
819
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530821 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
822 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000824 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530825 return
826 }
827 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
828 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000830 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530831 return
832 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000834 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
835 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
836 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
837 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
838 // maybe we can use just the same eventName for different state transitions like "forward"
839 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
840 switch oFsm.pLastTxMeInstance.GetName() {
841 case "Ieee8021PMapperServiceProfile":
842 { // let the FSM proceed ...
843 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
844 }
845 case "MacBridgePortConfigurationData":
846 { // let the FSM proceed ...
847 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
848 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300849 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
mpagenkofc4f56e2020-11-04 17:17:49 +0000850 { // let aniConfig Multi-Id processing proceed by stopping the wait function
851 oFsm.omciMIdsResponseReceived <- true
852 }
853 }
854 }
855 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530857 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
858 return
859 }
Himani Chawla4d908332020-08-31 12:30:20 +0530860}
861
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530863 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
864 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000866 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530867 return
868 }
869 msgObj, msgOk := msgLayer.(*omci.SetResponse)
870 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000872 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530873 return
874 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530876 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000878 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530879 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
880 return
881 }
mpagenko01e726e2020-10-23 09:45:29 +0000882 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
883 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530884 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
885 // if, then something like:
886 //oFsm.pOnuDB.StoreMe(msgObj)
887
mpagenko01e726e2020-10-23 09:45:29 +0000888 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530889 case "TCont":
890 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000891 if oFsm.requestEventOffset == 0 { //from TCont config request
892 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
893 } else { // from T-Cont reset request
894 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
895 }
Himani Chawla4d908332020-08-31 12:30:20 +0530896 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300897 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
Himani Chawla4d908332020-08-31 12:30:20 +0530898 { // let the PrioQueue init proceed by stopping the wait function
899 oFsm.omciMIdsResponseReceived <- true
900 }
901 case "Ieee8021PMapperServiceProfile":
902 { // let the FSM proceed ...
903 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
904 }
905 }
906 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000907}
908
dbainbri4d3a0dc2020-12-02 00:33:42 +0000909func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000910 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
911 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000912 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000913 log.Fields{"device-id": oFsm.deviceID})
914 return
915 }
916 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
917 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000919 log.Fields{"device-id": oFsm.deviceID})
920 return
921 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000922 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +0000923 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000924 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +0000925 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
926 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
927 // store error for mgmt display?
928 return
929 }
930 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
931 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
932 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
933 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
934
935 switch oFsm.pLastTxMeInstance.GetName() {
936 case "GemInterworkingTerminationPoint":
937 { // let the FSM proceed ...
938 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
939 }
940 case "GemPortNetworkCtp":
941 { // let the FSM proceed ...
942 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
943 }
944 case "Ieee8021PMapperServiceProfile":
945 { // let the FSM proceed ...
946 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
947 }
948 case "MacBridgePortConfigurationData":
949 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
950 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
951 }
952 }
953 }
954}
955
dbainbri4d3a0dc2020-12-02 00:33:42 +0000956func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
957 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000958 "msgType": msg.OmciMsg.MessageType})
959
960 switch msg.OmciMsg.MessageType {
961 case omci.CreateResponseType:
962 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530964
mpagenko3dbcdd22020-07-22 07:38:45 +0000965 } //CreateResponseType
966 case omci.SetResponseType:
967 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000968 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000969
mpagenko3dbcdd22020-07-22 07:38:45 +0000970 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000971 case omci.DeleteResponseType:
972 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000973 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +0000974
975 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000976 default:
977 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000979 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000980 return
981 }
982 }
983}
984
dbainbri4d3a0dc2020-12-02 00:33:42 +0000985func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000986 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
987 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000989 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
990 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000991 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000992 meParams := me.ParamData{
993 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
994 Attributes: me.AttributeValueMap{
995 "PortId": gemPortAttribs.gemPortID,
996 "TContPointer": oFsm.tcont0ID,
997 "Direction": gemPortAttribs.direction,
998 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
999 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1000 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1001 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1002 },
1003 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001004 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001005 oFsm.pAdaptFsm.commChan, meParams)
1006 //accept also nil as (error) return value for writing to LastTx
1007 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001008 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +00001009
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001010 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001012 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001014 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301015 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001016 return
1017 }
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001018 // Mark the gem port to be removed for Performance History monitoring
1019 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
1020 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(gemPortAttribs.gemPortID)
1021 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001022 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001023
1024 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001025 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301026 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001027}
1028
dbainbri4d3a0dc2020-12-02 00:33:42 +00001029func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001030 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1031 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001032 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001033 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1034 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001035 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001036
ozgecanetsia4b232302020-11-11 10:58:10 +03001037 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1038 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001039
1040 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001041 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001042 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001043 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001044 "InterworkingOption": 0, // Don't Care
1045 "ServiceProfilePointer": 0, // Don't Care
1046 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001047 },
1048 }
1049 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1050 true, oFsm.pAdaptFsm.commChan, meParams)
1051 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001052 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001053 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001054 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055 logger.Errorw(ctx, "GemTP IW multicast create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001056 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1057 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1058 return
1059 }
1060 ipv4MulticastTable := make([]uint8, 12)
1061 //Gem Port ID
1062 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1063 //Secondary Key
1064 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1065 // Multicast IP range start This is the 224.0.0.1 address
1066 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1067 // MulticastIp range stop
1068 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1069
1070 meIPV4MCTableParams := me.ParamData{
1071 EntityID: gemPortAttribs.multicastGemID,
1072 Attributes: me.AttributeValueMap{
1073 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1074 },
1075 }
1076 meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1077 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
1078 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
ozgecanetsia4b232302020-11-11 10:58:10 +03001079
1080 } else {
1081 meParams := me.ParamData{
1082 EntityID: gemPortAttribs.gemPortID,
1083 Attributes: me.AttributeValueMap{
1084 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1085 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1086 "ServiceProfilePointer": oFsm.mapperSP0ID,
1087 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1088 "GalProfilePointer": galEthernetEID,
1089 },
1090 }
1091 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
1092 oFsm.pAdaptFsm.commChan, meParams)
1093 //accept also nil as (error) return value for writing to LastTx
1094 // - this avoids misinterpretation of new received OMCI messages
1095 oFsm.pLastTxMeInstance = meInstance
1096 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001097 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001098 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001099 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001101 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301102 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001103 return
1104 }
1105 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001106
1107 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001108 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301109 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001110}
1111
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001113 const cu16StrictPrioWeight uint16 = 0xFFFF
1114 //find all upstream PrioQueues related to this T-Cont
1115 loQueueMap := ordered_map.NewOrderedMap()
1116 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001117 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001119 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1120 "prioString": gemPortAttribs.pbitString})
1121 continue
1122 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001123 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301124 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001125 //key does not yet exist
1126 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1127 }
1128 } else {
1129 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1130 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001131 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001132
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001133 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1134 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1135 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1136 // or even be finished without correct SP/WRR setting
1137
1138 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1139 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1140 // even though its T-Cont seems to be wrong ...
1141 loTrafficSchedulerEID := 0x8000
1142 //for all found queues
1143 iter := loQueueMap.IterFunc()
1144 for kv, ok := iter(); ok; kv, ok = iter() {
1145 queueIndex := (kv.Key).(uint16)
1146 meParams := me.ParamData{
1147 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301148 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001149 }
1150 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1151 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001152 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001153 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001154 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001155 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1156 } else {
1157 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001158 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001159 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1160 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001161 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001162 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1163 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1164 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001166 oFsm.pAdaptFsm.commChan, meParams)
1167 //accept also nil as (error) return value for writing to LastTx
1168 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001169 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001170
1171 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001173 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001174 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001175 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301176 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001177 return
1178 }
1179
1180 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1181 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1182 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1183 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1184
1185 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001186
1187 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301189 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001190}
1191
dbainbri4d3a0dc2020-12-02 00:33:42 +00001192func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001193 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301194 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001195 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001196 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001197 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 +00001198 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001199 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001200 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301201 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202 logger.Debug(ctx, "uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001203 return nil
1204 }
1205 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Warnw(ctx, "uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001207 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001208 }
1209}