blob: 34eeef6edc9bb7f4e5f426f9d723febafd685e5c [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +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"
22 "encoding/binary"
23 "errors"
24 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000025 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000026 "time"
27
28 "github.com/looplab/fsm"
29 "github.com/opencord/omci-lib-go"
30 me "github.com/opencord/omci-lib-go/generated"
31 "github.com/opencord/voltha-lib-go/v3/pkg/log"
32 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
33)
34
35const (
36 // internal predefined values
37 cDefaultDownstreamMode = 0
38 cDefaultTpid = 0x8100
Holger Hildebrandt394c5522020-09-11 11:23:01 +000039 cMaxAllowedFlows = 12 //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000040)
41
42const (
43 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
44 cFilterPrioOffset = 28
45 cFilterVidOffset = 15
46 cFilterTpidOffset = 12
47 cFilterEtherTypeOffset = 0
48 cTreatTTROffset = 30
49 cTreatPrioOffset = 16
50 cTreatVidOffset = 3
51 cTreatTpidOffset = 0
52)
53const (
54 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
55 cFilterOuterOffset = 0
56 cFilterInnerOffset = 4
57 cTreatOuterOffset = 8
58 cTreatInnerOffset = 12
59)
60const (
61 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
62 cPrioIgnoreTag uint32 = 15
63 cPrioDefaultFilter uint32 = 14
64 cPrioDoNotFilter uint32 = 8
65 cDoNotFilterVid uint32 = 4096
66 cDoNotFilterTPID uint32 = 0
67 cDoNotFilterEtherType uint32 = 0
68 cDoNotAddPrio uint32 = 15
69 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053070 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000071 cDontCareVid uint32 = 0
72 cDontCareTpid uint32 = 0
73 cSetOutputTpidCopyDei uint32 = 4
74)
75
76const (
77 // events of config PON ANI port FSM
78 vlanEvStart = "vlanEvStart"
79 vlanEvWaitTechProf = "vlanEvWaitTechProf"
80 vlanEvContinueConfig = "vlanEvContinueConfig"
81 vlanEvStartConfig = "vlanEvStartConfig"
82 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
83 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000084 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
Himani Chawla4d908332020-08-31 12:30:20 +053085 //vlanEvCleanupConfig = "vlanEvCleanupConfig"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000086 //vlanEvRxCleanVtfd = "vlanEvRxCleanVtfd"
87 //vlanEvRxCleanEvtocd = "vlanEvRxCleanEvtocd"
88 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
89 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Himani Chawla4d908332020-08-31 12:30:20 +053090 vlanEvReset = "vlanEvReset"
91 vlanEvRestart = "vlanEvRestart"
mpagenkodff5dda2020-08-28 11:52:01 +000092)
93const (
94 // states of config PON ANI port FSM
95 vlanStDisabled = "vlanStDisabled"
96 vlanStStarting = "vlanStStarting"
97 vlanStWaitingTechProf = "vlanStWaitingTechProf"
98 vlanStConfigVtfd = "vlanStConfigVtfd"
99 vlanStConfigEvtocd = "vlanStConfigEvtocd"
100 vlanStConfigDone = "vlanStConfigDone"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000101 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000102 vlanStCleanEvtocd = "vlanStCleanEvtocd"
103 vlanStCleanVtfd = "vlanStCleanVtfd"
104 vlanStCleanupDone = "vlanStCleanupDone"
105 vlanStResetting = "vlanStResetting"
106)
107
108//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
109type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530110 pDeviceHandler *deviceHandler
111 pOmciCC *omciCC
112 pOnuUniPort *onuUniPort
113 pUniTechProf *onuUniTechProf
114 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000115 techProfileID uint16
116 requestEvent OnuDeviceEvent
117 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
118 pAdaptFsm *AdapterFsm
119 acceptIncrementalEvtoOption bool
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000120 mutexFlowParams sync.Mutex
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000121 uniFlowParamsSlice []uniVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000122 numUniFlows uint8 // expected number of flows should be less than 12
123 configuredUniFlow uint8
124 numVlanFilterEntries uint8
125 vlanFilterList [12]uint16
126 vtfdID uint16
127 evtocdID uint16
mpagenkodff5dda2020-08-28 11:52:01 +0000128}
129
130//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
Himani Chawla6d2ae152020-09-02 13:11:20 +0530131func NewUniVlanConfigFsm(apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
132 apOnuDB *onuDeviceDB, aTechProfileID uint16, aRequestEvent OnuDeviceEvent, aName string,
mpagenkodff5dda2020-08-28 11:52:01 +0000133 aDeviceID string, aCommChannel chan Message,
134 aAcceptIncrementalEvto bool, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
135 instFsm := &UniVlanConfigFsm{
136 pDeviceHandler: apDeviceHandler,
137 pOmciCC: apDevOmciCC,
138 pOnuUniPort: apUniPort,
139 pUniTechProf: apUniTechProf,
140 pOnuDB: apOnuDB,
141 techProfileID: aTechProfileID,
142 requestEvent: aRequestEvent,
143 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000144 numUniFlows: 0,
145 configuredUniFlow: 0,
mpagenkodff5dda2020-08-28 11:52:01 +0000146 }
147
148 instFsm.pAdaptFsm = NewAdapterFsm(aName, aDeviceID, aCommChannel)
149 if instFsm.pAdaptFsm == nil {
150 logger.Errorw("UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
151 "device-id": aDeviceID})
152 return nil
153 }
mpagenkodff5dda2020-08-28 11:52:01 +0000154 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
155 vlanStDisabled,
156 fsm.Events{
157 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
158 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
159 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
160 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
161 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000162 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
163 Dst: vlanStConfigDone},
164 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
mpagenkodff5dda2020-08-28 11:52:01 +0000165 /*
166 {Name: vlanEvTimeoutSimple, Src: []string{
167 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
168 {Name: vlanEvTimeoutMids, Src: []string{
169 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
170 */
171 // exceptional treatment for all states except vlanStResetting
172 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000173 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenkodff5dda2020-08-28 11:52:01 +0000174 vlanStCleanEvtocd, vlanStCleanVtfd, vlanStCleanupDone},
175 Dst: vlanStResetting},
176 // the only way to get to resource-cleared disabled state again is via "resseting"
177 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
178 },
mpagenkodff5dda2020-08-28 11:52:01 +0000179 fsm.Callbacks{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000180 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
181 ("enter_" + vlanStStarting): func(e *fsm.Event) { instFsm.enterConfigStarting(e) },
182 ("enter_" + vlanStConfigVtfd): func(e *fsm.Event) { instFsm.enterConfigVtfd(e) },
183 ("enter_" + vlanStConfigEvtocd): func(e *fsm.Event) { instFsm.enterConfigEvtocd(e) },
184 ("enter_" + vlanStConfigDone): func(e *fsm.Event) { instFsm.enterVlanConfigDone(e) },
185 ("enter_" + vlanStConfigIncrFlow): func(e *fsm.Event) { instFsm.enterConfigIncrFlow(e) },
186 ("enter_" + vlanStCleanVtfd): func(e *fsm.Event) { instFsm.enterCleanVtfd(e) },
187 ("enter_" + vlanStCleanEvtocd): func(e *fsm.Event) { instFsm.enterCleanEvtocd(e) },
188 ("enter_" + vlanStCleanupDone): func(e *fsm.Event) { instFsm.enterVlanCleanupDone(e) },
189 ("enter_" + vlanStResetting): func(e *fsm.Event) { instFsm.enterResetting(e) },
190 ("enter_" + vlanStDisabled): func(e *fsm.Event) { instFsm.enterDisabled(e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000191 },
192 )
193 if instFsm.pAdaptFsm.pFsm == nil {
194 logger.Errorw("UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
195 "device-id": aDeviceID})
196 return nil
197 }
198
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000199 _ = instFsm.SetUniFlowParams(aTechProfileID, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000200
mpagenkodff5dda2020-08-28 11:52:01 +0000201 logger.Infow("UniVlanConfigFsm created", log.Fields{"device-id": aDeviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000202 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000203 return instFsm
204}
205
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000206//SetUniFlowParams verifies on existence of flow parameters to be configured
207// and appends a new flow if there is space
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000208func (oFsm *UniVlanConfigFsm) SetUniFlowParams(aTpID uint16, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
209 loFlowParams := uniVlanFlowParams{
210 TpID: aTpID,
211 MatchVid: uint32(aMatchVlan),
212 SetVid: uint32(aSetVlan),
213 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000214 }
215 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000216 loFlowParams.TagsToRemove = 1 //one tag to remove as default setting
217 loFlowParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000218
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000219 if loFlowParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000220 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000221 loFlowParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000222 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
223 } else {
224 if !oFsm.acceptIncrementalEvtoOption {
225 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000226 loFlowParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000227 }
228 }
229
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000230 if loFlowParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000231 // no prio/vid filtering requested
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000232 loFlowParams.TagsToRemove = 0 //no tag pop action
233 loFlowParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
234 if loFlowParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000235 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
236 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
237 // might collide with NoMatchVid/CopyPrio(/setVid) setting
238 // this was some precondition setting taken over from py adapter ..
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000239 loFlowParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000240 }
241 }
242 flowEntryMatch := false
243 //mutex protection is required for possible concurrent access to FSM members
244 oFsm.mutexFlowParams.Lock()
245 defer oFsm.mutexFlowParams.Unlock()
246 for _, storedUniFlowParams := range oFsm.uniFlowParamsSlice {
247 if storedUniFlowParams == loFlowParams {
248 flowEntryMatch = true
249 break
250 }
251 }
252 if flowEntryMatch {
253 logger.Debugw("UniVlanConfigFsm flow setting - flow already exists (ignore)", log.Fields{
254 "device-id": oFsm.pAdaptFsm.deviceID})
255 } else {
256 if oFsm.numUniFlows < cMaxAllowedFlows {
257 oFsm.uniFlowParamsSlice = append(oFsm.uniFlowParamsSlice, loFlowParams)
258 oFsm.numUniFlows++
259 logger.Debugw("UniVlanConfigFsm flow added", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000260 "MatchVid": strconv.FormatInt(int64(loFlowParams.MatchVid), 16),
261 "SetVid": strconv.FormatInt(int64(loFlowParams.SetVid), 16),
262 "SetPcp": loFlowParams.SetPcp, "numberofFlows": oFsm.numUniFlows,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000263 "device-id": oFsm.pAdaptFsm.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000264
265 //permanently store flow config for reconcile case
266
267 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(oFsm.pOnuUniPort.uniID, &oFsm.uniFlowParamsSlice); err != nil {
268 logger.Errorw(err.Error(), log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
269 return err
270 }
271
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000272 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
273 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
274 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
275 // calling some FSM event must be decoupled
276 go func(a_pBaseFsm *fsm.FSM) {
277 _ = a_pBaseFsm.Event(vlanEvIncrFlowConfig)
278 }(pConfigVlanStateBaseFsm)
279 } // in all other states a new entry will be automatically considered later in that state or
280 // ignored as not anymore relevant
281 } else {
282 logger.Errorw("UniVlanConfigFsm flow limit exceeded", log.Fields{
283 "device-id": oFsm.pAdaptFsm.deviceID})
284 return errors.New(" UniVlanConfigFsm flow limit exceeded")
285 }
286 }
287 return nil
288}
289
mpagenkodff5dda2020-08-28 11:52:01 +0000290func (oFsm *UniVlanConfigFsm) enterConfigStarting(e *fsm.Event) {
291 logger.Debugw("UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
292 "device-id": oFsm.pAdaptFsm.deviceID})
293
294 // this FSM is not intended for re-start, needs always new creation for a new run
295 oFsm.omciMIdsResponseReceived = make(chan bool)
296 // start go routine for processing of LockState messages
297 go oFsm.processOmciVlanMessages()
298 //let the state machine run forward from here directly
299 pConfigVlanStateAFsm := oFsm.pAdaptFsm
300 if pConfigVlanStateAFsm != nil {
301 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
302 go func(a_pAFsm *AdapterFsm) {
303 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
304 //stick to pythonAdapter numbering scheme
Himani Chawla26e555c2020-08-31 12:30:20 +0530305 oFsm.vtfdID = macBridgePortAniEID + oFsm.pOnuUniPort.entityID + oFsm.techProfileID
mpagenkodff5dda2020-08-28 11:52:01 +0000306 //cmp also usage in EVTOCDE create in omci_cc
307 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
308
Himani Chawla26e555c2020-08-31 12:30:20 +0530309 if oFsm.pUniTechProf.getTechProfileDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID) {
mpagenkodff5dda2020-08-28 11:52:01 +0000310 // let the vlan processing begin
Himani Chawla4d908332020-08-31 12:30:20 +0530311 _ = a_pAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000312 } else {
313 // set to waiting for Techprofile
Himani Chawla4d908332020-08-31 12:30:20 +0530314 _ = a_pAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000315 }
316 }
317 }(pConfigVlanStateAFsm)
318 }
319}
320
321func (oFsm *UniVlanConfigFsm) enterConfigVtfd(e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000322 //mutex protection is required for possible concurrent access to FSM members
323 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000324 if oFsm.uniFlowParamsSlice[0].SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000325 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000326 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +0000327 logger.Debugw("UniVlanConfigFsm: no VTFD config required", log.Fields{
328 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
329 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
330 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
331 pConfigVlanStateAFsm := oFsm.pAdaptFsm
332 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530333 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000334 }(pConfigVlanStateAFsm)
335 } else {
336 logger.Debugw("UniVlanConfigFsm create VTFD", log.Fields{
337 "EntitytId": strconv.FormatInt(int64(oFsm.vtfdID), 16),
338 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000339 oFsm.vlanFilterList[0] = uint16(oFsm.uniFlowParamsSlice[0].SetVid) // setVid is assumed to be masked already by the caller to 12 bit
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000340 oFsm.mutexFlowParams.Unlock()
341 vtfdFilterList := make([]uint16, 12) //needed for parameter serialization
342 vtfdFilterList[0] = oFsm.vlanFilterList[0]
343 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000344 meParams := me.ParamData{
345 EntityID: oFsm.vtfdID,
346 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000347 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
348 "ForwardOperation": uint8(0x10), //VID investigation
349 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000350 },
351 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000352 logger.Debugw("UniVlanConfigFsm sendcreate VTFD", log.Fields{
353 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000354 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
355 oFsm.pAdaptFsm.commChan, meParams)
356 //accept also nil as (error) return value for writing to LastTx
357 // - this avoids misinterpretation of new received OMCI messages
358 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
359 // send shall return (dual format) error code that can be used here for immediate error treatment
360 // (relevant to all used sendXX() methods in this (and other) FSM's)
361 oFsm.pOmciCC.pLastTxMeInstance = meInstance
362 }
363}
364
365func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(e *fsm.Event) {
366 logger.Debugw("UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
367 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000368 go oFsm.performConfigEvtocdEntries(0)
mpagenkodff5dda2020-08-28 11:52:01 +0000369}
370
371func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000372 logger.Debugw("UniVlanConfigFsm - checking on more flows", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +0000373 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000374 oFsm.configuredUniFlow++ // one (more) flow configured
375 if oFsm.numUniFlows > oFsm.configuredUniFlow {
376 //some further flows are to be configured
377 // calling some FSM event must be decoupled
378 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
379 go func(a_pBaseFsm *fsm.FSM) {
380 _ = a_pBaseFsm.Event(vlanEvIncrFlowConfig)
381 }(pConfigVlanStateBaseFsm)
382 return
383 }
384
385 logger.Debugw("UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
386 "device-id": oFsm.pAdaptFsm.deviceID})
387 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
388 // state transition notification is checked in deviceHandler
mpagenkodff5dda2020-08-28 11:52:01 +0000389 if oFsm.pDeviceHandler != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530390 oFsm.pDeviceHandler.deviceProcStatusUpdate(oFsm.requestEvent)
mpagenkodff5dda2020-08-28 11:52:01 +0000391 }
392}
393
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000394func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(e *fsm.Event) {
395 logger.Debugw("UniVlanConfigFsm - start config further incremental flow", log.Fields{
396 "in state": e.FSM.Current(), "recent flow-number": (oFsm.configuredUniFlow),
397 "device-id": oFsm.pAdaptFsm.deviceID})
398 oFsm.mutexFlowParams.Lock()
399
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400 if oFsm.uniFlowParamsSlice[oFsm.configuredUniFlow].SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000401 // meaning transparent setup - no specific VTFD setting required
402 oFsm.mutexFlowParams.Unlock()
403 logger.Debugw("UniVlanConfigFsm: no VTFD config required", log.Fields{
404 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
405 } else {
406 if oFsm.numVlanFilterEntries == 0 {
407 //no VTFD yet created
408 logger.Debugw("UniVlanConfigFsm create VTFD", log.Fields{
409 "EntitytId": strconv.FormatInt(int64(oFsm.vtfdID), 16),
410 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411 oFsm.vlanFilterList[0] = uint16(oFsm.uniFlowParamsSlice[oFsm.configuredUniFlow].SetVid) // setVid is assumed to be masked already by the caller to 12 bit
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000412 oFsm.mutexFlowParams.Unlock()
413 vtfdFilterList := make([]uint16, 12) //needed for parameter serialization
414 vtfdFilterList[0] = oFsm.vlanFilterList[0]
415 oFsm.numVlanFilterEntries = 1
416 meParams := me.ParamData{
417 EntityID: oFsm.vtfdID,
418 Attributes: me.AttributeValueMap{
419 "VlanFilterList": vtfdFilterList,
420 "ForwardOperation": uint8(0x10), //VID investigation
421 "NumberOfEntries": oFsm.numVlanFilterEntries,
422 },
423 }
424 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
425 oFsm.pAdaptFsm.commChan, meParams)
426 //accept also nil as (error) return value for writing to LastTx
427 // - this avoids misinterpretation of new received OMCI messages
428 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
429 // send shall return (dual format) error code that can be used here for immediate error treatment
430 // (relevant to all used sendXX() methods in this (and other) FSM's)
431 oFsm.pOmciCC.pLastTxMeInstance = meInstance
432 } else {
433 //VTFD already exists - just modify by 'set'
434 //TODO!!: but only if the VID is not already present, skipped by now to test basic working
435 logger.Debugw("UniVlanConfigFsm set VTFD", log.Fields{
436 "EntitytId": strconv.FormatInt(int64(oFsm.vtfdID), 16),
437 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
438 // setVid is assumed to be masked already by the caller to 12 bit
439 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440 uint16(oFsm.uniFlowParamsSlice[oFsm.configuredUniFlow].SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000441 oFsm.mutexFlowParams.Unlock()
442 vtfdFilterList := make([]uint16, 12) //needed for parameter serialization
443 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
444 vtfdFilterList[i] = oFsm.vlanFilterList[i]
445 }
446
447 oFsm.numVlanFilterEntries++
448 meParams := me.ParamData{
449 EntityID: oFsm.vtfdID,
450 Attributes: me.AttributeValueMap{
451 "VlanFilterList": vtfdFilterList,
452 "NumberOfEntries": oFsm.numVlanFilterEntries,
453 },
454 }
455 meInstance := oFsm.pOmciCC.sendSetVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
456 oFsm.pAdaptFsm.commChan, meParams)
457 //accept also nil as (error) return value for writing to LastTx
458 // - this avoids misinterpretation of new received OMCI messages
459 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
460 // send shall return (dual format) error code that can be used here for immediate error treatment
461 // (relevant to all used sendXX() methods in this (and other) FSM's)
462 oFsm.pOmciCC.pLastTxMeInstance = meInstance
463 }
464 //verify response
465 err := oFsm.waitforOmciResponse()
466 if err != nil {
467 logger.Errorw("VTFD create/set failed, aborting VlanConfig FSM!",
468 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
469 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
470 return
471 }
472 }
473 go oFsm.performConfigEvtocdEntries(oFsm.configuredUniFlow)
474}
475
mpagenkodff5dda2020-08-28 11:52:01 +0000476func (oFsm *UniVlanConfigFsm) enterCleanVtfd(e *fsm.Event) {
477 logger.Debugw("UniVlanConfigFsm Tx Delete::VTFD", log.Fields{
478 /*"EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),*/
479 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
480}
481
482func (oFsm *UniVlanConfigFsm) enterCleanEvtocd(e *fsm.Event) {
483 logger.Debugw("UniVlanConfigFsm cleanup EVTOCD", log.Fields{
484 /*"EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
485 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),*/
486 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
487}
488
489func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(e *fsm.Event) {
490 logger.Debugw("UniVlanConfigFsm - VLAN cleanup done", log.Fields{
491 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
492
493 //let's reset the state machine in order to release all resources now
494 pConfigVlanStateAFsm := oFsm.pAdaptFsm
495 if pConfigVlanStateAFsm != nil {
496 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
497 go func(a_pAFsm *AdapterFsm) {
498 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530499 _ = a_pAFsm.pFsm.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +0000500 }
501 }(pConfigVlanStateAFsm)
502 }
503}
504
505func (oFsm *UniVlanConfigFsm) enterResetting(e *fsm.Event) {
506 logger.Debugw("UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
507
508 pConfigVlanStateAFsm := oFsm.pAdaptFsm
509 if pConfigVlanStateAFsm != nil {
510 // abort running message processing
511 fsmAbortMsg := Message{
512 Type: TestMsg,
513 Data: TestMessage{
514 TestMessageVal: AbortMessageProcessing,
515 },
516 }
517 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
518
519 //try to restart the FSM to 'disabled', decouple event transfer
520 go func(a_pAFsm *AdapterFsm) {
521 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530522 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +0000523 }
524 }(pConfigVlanStateAFsm)
525 }
526}
527
528func (oFsm *UniVlanConfigFsm) enterDisabled(e *fsm.Event) {
529 logger.Debugw("UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
530 if oFsm.pDeviceHandler != nil {
531 //request removal of 'reference' in the Handler (completely clear the FSM)
532 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(oFsm.pOnuUniPort)
533 }
534}
535
536func (oFsm *UniVlanConfigFsm) processOmciVlanMessages() { //ctx context.Context?
537 logger.Debugw("Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
538loop:
539 for {
mpagenkodff5dda2020-08-28 11:52:01 +0000540 // case <-ctx.Done():
541 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.pAdaptFsm.deviceID})
542 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530543 message, ok := <-oFsm.pAdaptFsm.commChan
544 if !ok {
545 logger.Info("UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
546 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
547 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
548 break loop
549 }
550 logger.Debugw("UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
551
552 switch message.Type {
553 case TestMsg:
554 msg, _ := message.Data.(TestMessage)
555 if msg.TestMessageVal == AbortMessageProcessing {
556 logger.Infow("UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000557 break loop
558 }
Himani Chawla4d908332020-08-31 12:30:20 +0530559 logger.Warnw("UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "MessageVal": msg.TestMessageVal})
560 case OMCI:
561 msg, _ := message.Data.(OmciMessage)
562 oFsm.handleOmciVlanConfigMessage(msg)
563 default:
564 logger.Warn("UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
565 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +0000566 }
567 }
568 logger.Infow("End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
569}
570
571func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(msg OmciMessage) {
572 logger.Debugw("Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
573 "msgType": msg.OmciMsg.MessageType})
574
575 switch msg.OmciMsg.MessageType {
576 case omci.CreateResponseType:
577 {
578 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
579 if msgLayer == nil {
580 logger.Error("Omci Msg layer could not be detected for CreateResponse")
581 return
582 }
583 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
584 if !msgOk {
585 logger.Error("Omci Msg layer could not be assigned for CreateResponse")
586 return
587 }
588 logger.Debugw("CreateResponse Data", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
589 if msgObj.Result != me.Success {
590 logger.Errorw("Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
591 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
592 return
593 }
594 if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
595 msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
596 // maybe we can use just the same eventName for different state transitions like "forward"
597 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
598 switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
599 case "VlanTaggingFilterData":
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000600 {
601 if oFsm.configuredUniFlow == 0 {
602 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
603 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
604 } else { // let the MultiEntity config proceed by stopping the wait function
605 oFsm.omciMIdsResponseReceived <- true
606 }
mpagenkodff5dda2020-08-28 11:52:01 +0000607 }
608 }
609 }
610 } //CreateResponseType
611 case omci.SetResponseType:
612 {
613 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
614 if msgLayer == nil {
615 logger.Error("UniVlanConfigFsm - Omci Msg layer could not be detected for SetResponse")
616 return
617 }
618 msgObj, msgOk := msgLayer.(*omci.SetResponse)
619 if !msgOk {
620 logger.Error("UniVlanConfigFsm - Omci Msg layer could not be assigned for SetResponse")
621 return
622 }
623 logger.Debugw("UniVlanConfigFsm SetResponse Data", log.Fields{"deviceId": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
624 if msgObj.Result != me.Success {
625 logger.Errorw("UniVlanConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
626 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
627 return
628 }
629 if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
630 msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
631 switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000632 case "VlanTaggingFilterData",
633 "ExtendedVlanTaggingOperationConfigurationData":
634 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +0000635 oFsm.omciMIdsResponseReceived <- true
636 }
637 }
638 }
639 } //SetResponseType
640 default:
641 {
642 logger.Errorw("UniVlanConfigFsm - Rx OMCI unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
643 return
644 }
645 }
646}
647
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000648func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(aFlowEntryNo uint8) {
649 if aFlowEntryNo == 0 {
650 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +0000651 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
652 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
653 logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD", log.Fields{
654 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
655 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
656 "device-id": oFsm.pAdaptFsm.deviceID})
657 meParams := me.ParamData{
658 EntityID: oFsm.evtocdID,
659 Attributes: me.AttributeValueMap{
660 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
661 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
662 "DownstreamMode": uint8(cDefaultDownstreamMode),
663 },
664 }
665 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
666 oFsm.pAdaptFsm.commChan, meParams)
667 //accept also nil as (error) return value for writing to LastTx
668 // - this avoids misinterpretation of new received OMCI messages
669 oFsm.pOmciCC.pLastTxMeInstance = meInstance
670
671 //verify response
672 err := oFsm.waitforOmciResponse()
673 if err != nil {
674 logger.Errorw("Evtocd set TPID failed, aborting VlanConfig FSM!",
675 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530676 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +0000677 return
678 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000679 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +0000680
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000681 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000682 if oFsm.uniFlowParamsSlice[aFlowEntryNo].SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000683 //transparent transmission required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000684 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +0000685 logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
686 "device-id": oFsm.pAdaptFsm.deviceID})
687 sliceEvtocdRule := make([]uint8, 16)
688 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
689 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
690 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
691 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
692 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
693
694 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
695 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
696 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
697 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
698 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
699
700 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
701 0<<cTreatTTROffset| // Do not pop any tags
702 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
703 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
704 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
705
706 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
707 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
708 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
709 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
710
711 meParams := me.ParamData{
712 EntityID: oFsm.evtocdID,
713 Attributes: me.AttributeValueMap{
714 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
715 },
716 }
717 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
718 oFsm.pAdaptFsm.commChan, meParams)
719 //accept also nil as (error) return value for writing to LastTx
720 // - this avoids misinterpretation of new received OMCI messages
721 oFsm.pOmciCC.pLastTxMeInstance = meInstance
722
723 //verify response
724 err := oFsm.waitforOmciResponse()
725 if err != nil {
726 logger.Errorw("Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
727 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530728 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +0000729 return
730 }
731 } else {
732 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
733 if oFsm.acceptIncrementalEvtoOption {
734 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
735 logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
736 "device-id": oFsm.pAdaptFsm.deviceID})
737 sliceEvtocdRule := make([]uint8, 16)
738 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
739 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
740 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
741 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
742 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
743
744 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000745 oFsm.uniFlowParamsSlice[aFlowEntryNo].MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
746 oFsm.uniFlowParamsSlice[aFlowEntryNo].MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +0000747 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
748 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
749
750 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000751 oFsm.uniFlowParamsSlice[aFlowEntryNo].TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +0000752 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
753 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
754 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
755
756 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000757 oFsm.uniFlowParamsSlice[aFlowEntryNo].SetPcp<<cTreatPrioOffset| // as configured in flow
758 oFsm.uniFlowParamsSlice[aFlowEntryNo].SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +0000759 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000760 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +0000761
762 meParams := me.ParamData{
763 EntityID: oFsm.evtocdID,
764 Attributes: me.AttributeValueMap{
765 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
766 },
767 }
768 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
769 oFsm.pAdaptFsm.commChan, meParams)
770 //accept also nil as (error) return value for writing to LastTx
771 // - this avoids misinterpretation of new received OMCI messages
772 oFsm.pOmciCC.pLastTxMeInstance = meInstance
773
774 //verify response
775 err := oFsm.waitforOmciResponse()
776 if err != nil {
777 logger.Errorw("Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
778 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530779 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +0000780 return
781 }
782 } else {
783 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
784 { // just for local var's
785 // this defines stacking scenario: untagged->singletagged
786 logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
787 "device-id": oFsm.pAdaptFsm.deviceID})
788 sliceEvtocdRule := make([]uint8, 16)
789 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
790 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
791 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
792 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
793 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
794
795 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
796 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
797 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
798 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
799 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
800
801 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
802 0<<cTreatTTROffset| // Do not pop any tags
803 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
804 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
805 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
806
807 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
808 0<<cTreatPrioOffset| // vlan prio set to 0
809 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000810 oFsm.uniFlowParamsSlice[aFlowEntryNo].SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +0000811 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
812
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000813 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +0000814 meParams := me.ParamData{
815 EntityID: oFsm.evtocdID,
816 Attributes: me.AttributeValueMap{
817 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
818 },
819 }
820 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
821 oFsm.pAdaptFsm.commChan, meParams)
822 //accept also nil as (error) return value for writing to LastTx
823 // - this avoids misinterpretation of new received OMCI messages
824 oFsm.pOmciCC.pLastTxMeInstance = meInstance
825
826 //verify response
827 err := oFsm.waitforOmciResponse()
828 if err != nil {
829 logger.Errorw("Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
830 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530831 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +0000832 return
833 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000834 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +0000835 { // just for local var's
836 // this defines 'stacking' scenario: priotagged->singletagged
837 logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
838 "device-id": oFsm.pAdaptFsm.deviceID})
839 sliceEvtocdRule := make([]uint8, 16)
840 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
841 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
842 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
843 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
844 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
845
846 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
847 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
848 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
849 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
850 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
851
852 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
853 1<<cTreatTTROffset| // pop the prio-tag
854 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
855 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
856 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
857
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000858 oFsm.mutexFlowParams.Lock()
mpagenkodff5dda2020-08-28 11:52:01 +0000859 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
860 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
861 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000862 oFsm.uniFlowParamsSlice[aFlowEntryNo].SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +0000863 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000864 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +0000865
866 meParams := me.ParamData{
867 EntityID: oFsm.evtocdID,
868 Attributes: me.AttributeValueMap{
869 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
870 },
871 }
872 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
873 oFsm.pAdaptFsm.commChan, meParams)
874 //accept also nil as (error) return value for writing to LastTx
875 // - this avoids misinterpretation of new received OMCI messages
876 oFsm.pOmciCC.pLastTxMeInstance = meInstance
877
878 //verify response
879 err := oFsm.waitforOmciResponse()
880 if err != nil {
881 logger.Errorw("Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
882 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530883 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
mpagenkodff5dda2020-08-28 11:52:01 +0000884 return
885 }
886 } //just for local var's
887 }
888 }
889
890 // if Config has been done for all GemPort instances let the FSM proceed
891 logger.Debugw("EVTOCD set loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530892 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
mpagenkodff5dda2020-08-28 11:52:01 +0000893}
894
895func (oFsm *UniVlanConfigFsm) waitforOmciResponse() error {
896 select {
Himani Chawla26e555c2020-08-31 12:30:20 +0530897 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +0000898 // case <-ctx.Done():
899 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
900 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
901 logger.Warnw("UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530902 return errors.New("uniVlanConfigFsm multi entity timeout")
mpagenkodff5dda2020-08-28 11:52:01 +0000903 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +0530904 if success {
mpagenkodff5dda2020-08-28 11:52:01 +0000905 logger.Debug("UniVlanConfigFsm multi entity response received")
906 return nil
907 }
908 // should not happen so far
909 logger.Warnw("UniVlanConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530910 return errors.New("uniVlanConfigFsm multi entity responseError")
mpagenkodff5dda2020-08-28 11:52:01 +0000911 }
912}