blob: 6cb96a30bee3d53ef59b4e336fd92bc8e55a9ef7 [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
685}
686
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
688 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000689 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
690
691 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
692 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
693 meParams := me.ParamData{
694 EntityID: oFsm.tcont0ID,
695 Attributes: me.AttributeValueMap{
696 "AllocId": unusedTcontAllocID,
697 },
698 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000700 oFsm.pAdaptFsm.commChan, meParams)
701 oFsm.pLastTxMeInstance = meInstance
702}
703
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
705 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000706 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
707
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000709 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
710 oFsm.pLastTxMeInstance = meInstance
711}
712
dbainbri4d3a0dc2020-12-02 00:33:42 +0000713func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
714 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000715 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
716
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000718 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
719 oFsm.pLastTxMeInstance = meInstance
720}
721
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
723 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000724 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
725 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko8b07c1b2020-11-26 10:36:31 +0000727 if oFsm.chanSet {
728 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000730 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
731 oFsm.chSuccess <- oFsm.procStep
732 oFsm.chanSet = false //reset the internal channel state
733 }
734
735 //let's reset the state machine in order to release all resources now
736 pConfigAniStateAFsm := oFsm.pAdaptFsm
737 if pConfigAniStateAFsm != nil {
738 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
739 go func(aPAFsm *AdapterFsm) {
740 if aPAFsm != nil && aPAFsm.pFsm != nil {
741 _ = aPAFsm.pFsm.Event(aniEvReset)
742 }
743 }(pConfigAniStateAFsm)
744 }
745}
746
dbainbri4d3a0dc2020-12-02 00:33:42 +0000747func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
748 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000749 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000750
mpagenko3dbcdd22020-07-22 07:38:45 +0000751 pConfigAniStateAFsm := oFsm.pAdaptFsm
752 if pConfigAniStateAFsm != nil {
753 // abort running message processing
754 fsmAbortMsg := Message{
755 Type: TestMsg,
756 Data: TestMessage{
757 TestMessageVal: AbortMessageProcessing,
758 },
759 }
760 pConfigAniStateAFsm.commChan <- fsmAbortMsg
761
762 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530763 go func(aPAFsm *AdapterFsm) {
764 if aPAFsm != nil && aPAFsm.pFsm != nil {
765 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000766 }
767 }(pConfigAniStateAFsm)
768 }
769}
770
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
772 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000773 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000774 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000775
mpagenko01e726e2020-10-23 09:45:29 +0000776 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000778}
779
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
781 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000782loop:
783 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000784 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000785 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000786 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530787 message, ok := <-oFsm.pAdaptFsm.commChan
788 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530790 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
791 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
792 break loop
793 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530795
796 switch message.Type {
797 case TestMsg:
798 msg, _ := message.Data.(TestMessage)
799 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000801 break loop
802 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000803 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530804 case OMCI:
805 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530807 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530809 "message.Type": message.Type})
810 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000811
Himani Chawla4d908332020-08-31 12:30:20 +0530812 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530814}
815
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530817 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
818 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000820 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530821 return
822 }
823 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
824 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000826 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530827 return
828 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000830 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
831 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
832 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
833 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
834 // maybe we can use just the same eventName for different state transitions like "forward"
835 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
836 switch oFsm.pLastTxMeInstance.GetName() {
837 case "Ieee8021PMapperServiceProfile":
838 { // let the FSM proceed ...
839 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
840 }
841 case "MacBridgePortConfigurationData":
842 { // let the FSM proceed ...
843 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
844 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300845 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
mpagenkofc4f56e2020-11-04 17:17:49 +0000846 { // let aniConfig Multi-Id processing proceed by stopping the wait function
847 oFsm.omciMIdsResponseReceived <- true
848 }
849 }
850 }
851 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530853 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
854 return
855 }
Himani Chawla4d908332020-08-31 12:30:20 +0530856}
857
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530859 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
860 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000862 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530863 return
864 }
865 msgObj, msgOk := msgLayer.(*omci.SetResponse)
866 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000868 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530869 return
870 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530872 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000874 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530875 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
876 return
877 }
mpagenko01e726e2020-10-23 09:45:29 +0000878 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
879 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530880 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
881 // if, then something like:
882 //oFsm.pOnuDB.StoreMe(msgObj)
883
mpagenko01e726e2020-10-23 09:45:29 +0000884 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530885 case "TCont":
886 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000887 if oFsm.requestEventOffset == 0 { //from TCont config request
888 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
889 } else { // from T-Cont reset request
890 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
891 }
Himani Chawla4d908332020-08-31 12:30:20 +0530892 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300893 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
Himani Chawla4d908332020-08-31 12:30:20 +0530894 { // let the PrioQueue init proceed by stopping the wait function
895 oFsm.omciMIdsResponseReceived <- true
896 }
897 case "Ieee8021PMapperServiceProfile":
898 { // let the FSM proceed ...
899 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
900 }
901 }
902 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000903}
904
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000906 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
907 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000909 log.Fields{"device-id": oFsm.deviceID})
910 return
911 }
912 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
913 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000914 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000915 log.Fields{"device-id": oFsm.deviceID})
916 return
917 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +0000919 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000920 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +0000921 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
922 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
923 // store error for mgmt display?
924 return
925 }
926 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
927 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
928 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
929 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
930
931 switch oFsm.pLastTxMeInstance.GetName() {
932 case "GemInterworkingTerminationPoint":
933 { // let the FSM proceed ...
934 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
935 }
936 case "GemPortNetworkCtp":
937 { // let the FSM proceed ...
938 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
939 }
940 case "Ieee8021PMapperServiceProfile":
941 { // let the FSM proceed ...
942 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
943 }
944 case "MacBridgePortConfigurationData":
945 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
946 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
947 }
948 }
949 }
950}
951
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
953 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000954 "msgType": msg.OmciMsg.MessageType})
955
956 switch msg.OmciMsg.MessageType {
957 case omci.CreateResponseType:
958 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530960
mpagenko3dbcdd22020-07-22 07:38:45 +0000961 } //CreateResponseType
962 case omci.SetResponseType:
963 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000965
mpagenko3dbcdd22020-07-22 07:38:45 +0000966 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000967 case omci.DeleteResponseType:
968 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +0000970
971 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000972 default:
973 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000974 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000975 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000976 return
977 }
978 }
979}
980
dbainbri4d3a0dc2020-12-02 00:33:42 +0000981func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000982 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
983 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000984 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000985 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
986 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000987 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000988 meParams := me.ParamData{
989 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
990 Attributes: me.AttributeValueMap{
991 "PortId": gemPortAttribs.gemPortID,
992 "TContPointer": oFsm.tcont0ID,
993 "Direction": gemPortAttribs.direction,
994 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
995 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
996 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
997 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
998 },
999 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001000 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001001 oFsm.pAdaptFsm.commChan, meParams)
1002 //accept also nil as (error) return value for writing to LastTx
1003 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001004 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +00001005
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001006 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001007 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001008 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001010 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301011 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001012 return
1013 }
1014 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001015
1016 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001017 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301018 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001019}
1020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001022 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1023 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001024 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001025 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1026 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001027 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001028
ozgecanetsia4b232302020-11-11 10:58:10 +03001029 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1030 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001031
1032 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001033 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001034 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001035 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001036 "InterworkingOption": 0, // Don't Care
1037 "ServiceProfilePointer": 0, // Don't Care
1038 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001039 },
1040 }
1041 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1042 true, oFsm.pAdaptFsm.commChan, meParams)
1043 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001044 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001045 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001046 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001047 logger.Errorw(ctx, "GemTP IW multicast create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001048 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1049 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1050 return
1051 }
1052 ipv4MulticastTable := make([]uint8, 12)
1053 //Gem Port ID
1054 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1055 //Secondary Key
1056 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1057 // Multicast IP range start This is the 224.0.0.1 address
1058 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1059 // MulticastIp range stop
1060 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1061
1062 meIPV4MCTableParams := me.ParamData{
1063 EntityID: gemPortAttribs.multicastGemID,
1064 Attributes: me.AttributeValueMap{
1065 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1066 },
1067 }
1068 meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1069 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
1070 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
ozgecanetsia4b232302020-11-11 10:58:10 +03001071
1072 } else {
1073 meParams := me.ParamData{
1074 EntityID: gemPortAttribs.gemPortID,
1075 Attributes: me.AttributeValueMap{
1076 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1077 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1078 "ServiceProfilePointer": oFsm.mapperSP0ID,
1079 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1080 "GalProfilePointer": galEthernetEID,
1081 },
1082 }
1083 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
1084 oFsm.pAdaptFsm.commChan, meParams)
1085 //accept also nil as (error) return value for writing to LastTx
1086 // - this avoids misinterpretation of new received OMCI messages
1087 oFsm.pLastTxMeInstance = meInstance
1088 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001089 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001090 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001091 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001092 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001093 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301094 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001095 return
1096 }
1097 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001098
1099 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301101 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001102}
1103
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001105 const cu16StrictPrioWeight uint16 = 0xFFFF
1106 //find all upstream PrioQueues related to this T-Cont
1107 loQueueMap := ordered_map.NewOrderedMap()
1108 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001109 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001111 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1112 "prioString": gemPortAttribs.pbitString})
1113 continue
1114 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001115 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301116 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001117 //key does not yet exist
1118 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1119 }
1120 } else {
1121 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1122 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001123 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001124
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001125 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1126 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1127 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1128 // or even be finished without correct SP/WRR setting
1129
1130 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1131 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1132 // even though its T-Cont seems to be wrong ...
1133 loTrafficSchedulerEID := 0x8000
1134 //for all found queues
1135 iter := loQueueMap.IterFunc()
1136 for kv, ok := iter(); ok; kv, ok = iter() {
1137 queueIndex := (kv.Key).(uint16)
1138 meParams := me.ParamData{
1139 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301140 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001141 }
1142 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1143 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001145 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001146 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001147 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1148 } else {
1149 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001150 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001151 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1152 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001153 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001154 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1155 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1156 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001158 oFsm.pAdaptFsm.commChan, meParams)
1159 //accept also nil as (error) return value for writing to LastTx
1160 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001161 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001162
1163 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001164 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001165 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001166 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001167 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301168 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001169 return
1170 }
1171
1172 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1173 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1174 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1175 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1176
1177 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001178
1179 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001180 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301181 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001182}
1183
dbainbri4d3a0dc2020-12-02 00:33:42 +00001184func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001185 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301186 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001187 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001188 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001189 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 +00001190 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001191 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001192 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301193 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001194 logger.Debug(ctx, "uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001195 return nil
1196 }
1197 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198 logger.Warnw(ctx, "uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001199 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001200 }
1201}