blob: 70b5f6738492660b907d4b88defd55b6376f12c2 [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"
32 "github.com/opencord/voltha-lib-go/v3/pkg/log"
33 //ic "github.com/opencord/voltha-protos/v3/go/inter_container"
34 //"github.com/opencord/voltha-protos/v3/go/openflow_13"
35 //"github.com/opencord/voltha-protos/v3/go/voltha"
36)
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"
50 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
51 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
52 aniEvRemTcontPath = "aniEvRemTcontPath"
53 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
54 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
55 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
56 aniEvTimeoutSimple = "aniEvTimeoutSimple"
57 aniEvTimeoutMids = "aniEvTimeoutMids"
58 aniEvReset = "aniEvReset"
59 aniEvRestart = "aniEvRestart"
mpagenko1cc3cb42020-07-27 15:24:38 +000060)
61const (
62 // states of config PON ANI port FSM
63 aniStDisabled = "aniStDisabled"
64 aniStStarting = "aniStStarting"
65 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
66 aniStCreatingMBPCD = "aniStCreatingMBPCD"
67 aniStSettingTconts = "aniStSettingTconts"
68 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
69 aniStCreatingGemIWs = "aniStCreatingGemIWs"
70 aniStSettingPQs = "aniStSettingPQs"
71 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
72 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000073 aniStRemovingGemIW = "aniStRemovingGemIW"
74 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
75 aniStResetTcont = "aniStResetTcont"
76 aniStRemDot1PMapper = "aniStRemDot1PMapper"
77 aniStRemAniBPCD = "aniStRemAniBPCD"
78 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000079 aniStResetting = "aniStResetting"
80)
81
Girish Gowdra041dcb32020-11-16 16:54:30 -080082const (
83 tpIDOffset = 64
84)
85
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000086type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030087 gemPortID uint16
88 upQueueID uint16
89 downQueueID uint16
90 direction uint8
91 qosPolicy string
92 weight uint8
93 pbitString string
94 isMulticast bool
95 multicastGemID uint16
96 staticACL string
97 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000098}
99
Himani Chawla6d2ae152020-09-02 13:11:20 +0530100//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
101type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000102 pDeviceHandler *deviceHandler
103 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530104 pOmciCC *omciCC
105 pOnuUniPort *onuUniPort
106 pUniTechProf *onuUniTechProf
107 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800108 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000109 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000110 requestEvent OnuDeviceEvent
Himani Chawla4d908332020-08-31 12:30:20 +0530111 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000112 pAdaptFsm *AdapterFsm
113 chSuccess chan<- uint8
114 procStep uint8
115 chanSet bool
116 mapperSP0ID uint16
117 macBPCD0ID uint16
118 tcont0ID uint16
119 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000120 gemPortAttribsSlice []ponAniGemPortAttribs
mpagenko01e726e2020-10-23 09:45:29 +0000121 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000122 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenko3dbcdd22020-07-22 07:38:45 +0000123}
124
Himani Chawla6d2ae152020-09-02 13:11:20 +0530125//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
126func newUniPonAniConfigFsm(apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800127 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000128 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530129 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000130 pDeviceHandler: apDeviceHandler,
131 deviceID: apDeviceHandler.deviceID,
132 pOmciCC: apDevOmciCC,
133 pOnuUniPort: apUniPort,
134 pUniTechProf: apUniTechProf,
135 pOnuDB: apOnuDB,
136 techProfileID: aTechProfileID,
137 requestEvent: aRequestEvent,
138 chanSet: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000139 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000140 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
141
mpagenko01e726e2020-10-23 09:45:29 +0000142 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000143 if instFsm.pAdaptFsm == nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530144 logger.Errorw("uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000145 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000146 return nil
147 }
148
149 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000150 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000151 fsm.Events{
152
mpagenko1cc3cb42020-07-27 15:24:38 +0000153 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000154
155 //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 +0000156 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000157 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000158 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
159 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000160 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000161 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000162 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000163 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000164 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000165 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000166 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000167
mpagenko8b07c1b2020-11-26 10:36:31 +0000168 //for removing Gem related resources
169 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
170 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
171 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStConfigDone},
172
173 //for removing TCONT related resources
174 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
175 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStRemDot1PMapper},
176 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
177 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
178
179 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
180 aniStRemovingGemIW, aniStRemovingGemNCTP,
181 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000182 {Name: aniEvTimeoutMids, Src: []string{
183 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000184
mpagenko1cc3cb42020-07-27 15:24:38 +0000185 // exceptional treatment for all states except aniStResetting
186 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
187 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
mpagenko8b07c1b2020-11-26 10:36:31 +0000188 aniStConfigDone, aniStRemovingGemIW, aniStRemovingGemNCTP,
189 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000190 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000191 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
mpagenko3dbcdd22020-07-22 07:38:45 +0000192 },
193
194 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000195 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
196 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(e) },
197 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(e) },
198 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(e) },
199 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(e) },
200 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(e) },
201 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(e) },
202 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(e) },
203 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(e) },
204 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(e) },
mpagenko8b07c1b2020-11-26 10:36:31 +0000205 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(e) },
206 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(e) },
207 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(e) },
208 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(e) },
209 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(e) },
210 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(e) },
mpagenko1cc3cb42020-07-27 15:24:38 +0000211 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(e) },
212 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000213 },
214 )
215 if instFsm.pAdaptFsm.pFsm == nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530216 logger.Errorw("uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000217 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000218 return nil
219 }
220
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000221 logger.Debugw("uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000222 return instFsm
223}
224
Himani Chawla6d2ae152020-09-02 13:11:20 +0530225//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
226func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000227 oFsm.chSuccess = aChSuccess
228 oFsm.procStep = aProcStep
229 oFsm.chanSet = true
230}
231
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530233 if aPAFsm != nil && aPAFsm.pFsm != nil {
234 //stick to pythonAdapter numbering scheme
235 //index 0 in naming refers to possible usage of multiple instances (later)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800236 oFsm.mapperSP0ID = ieeeMapperServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) + uint16(oFsm.techProfileID)
237 oFsm.macBPCD0ID = macBridgePortAniEID + uint16(oFsm.pOnuUniPort.entityID) + uint16(oFsm.techProfileID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530238
Girish Gowdra041dcb32020-11-16 16:54:30 -0800239 /*
240 // Find a free TCONT Instance ID and use it
241 foundFreeTcontInstID := false
242 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530243 if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.TContClassID); len(tcontInstKeys) > 0 {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800244
245 // FIXME: Ideally the ME configurations on the ONU should constantly be MIB Synced back to the ONU DB
246 // So, as soon as we use up a TCONT Entity on the ONU, the DB at ONU adapter should know that the TCONT
247 // entity is used up via MIB Sync procedure and it will not use it for subsequent TCONT on that ONU.
248 // But, it seems, due to the absence of the constant mib-sync procedure, the TCONT Entities show up as
249 // free even though they are already reserved on the ONU. It seems the mib is synced only once, initially
250 // when the ONU is discovered.
251 /*
252 for _, tcontInstID := range tcontInstKeys {
253 tconInst := oFsm.pOnuDB.GetMe(me.TContClassID, tcontInstID)
254 returnVal := tconInst["AllocId"]
255 if returnVal != nil {
256 if allocID, err := oFsm.pOnuDB.getUint16Attrib(returnVal); err == nil {
257 // If the TCONT Instance ID is set to 0xff or 0xffff, it means it is free to use.
258 if allocID == 0xff || allocID == 0xffff {
259 foundFreeTcontInstID = true
260 oFsm.tcont0ID = uint16(tcontInstID)
261 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
262 "device-id": oFsm.deviceID})
263 break
264 }
265 } else {
266 logger.Errorw("error-converting-alloc-id-to-uint16", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
267 }
268 } else {
269 logger.Errorw("error-extracting-alloc-id-attribute", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
270 }
271 }
272 */
273
274 // Ensure that the techProfileID is in a valid range so that we can allocate a free Tcont for it.
275 if oFsm.techProfileID >= tpIDOffset && oFsm.techProfileID < uint8(tpIDOffset+len(tcontInstKeys)) {
276 // For now, as a dirty workaround, use the tpIDOffset to index the TcontEntityID to be used.
277 // The first TP ID for the ONU will get the first TcontEntityID, the next will get second and so on.
278 // Here the assumption is TP ID will always start from 64 (this is also true to Technology Profile Specification) and the
279 // TP ID will increment in single digit
280 oFsm.tcont0ID = tcontInstKeys[oFsm.techProfileID-tpIDOffset]
281 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
282 "device-id": oFsm.deviceID})
283 } else {
284 logger.Errorw("tech profile id not in valid range", log.Fields{"device-id": oFsm.deviceID, "tp-id": oFsm.techProfileID, "num-tcont": len(tcontInstKeys)})
285 if oFsm.chanSet {
286 // indicate processing error/abort to the caller
287 oFsm.chSuccess <- 0
288 oFsm.chanSet = false //reset the internal channel state
289 }
290 //reset the state machine to enable usage on subsequent requests
291 _ = aPAFsm.pFsm.Event(aniEvReset)
292 return
293 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530294 } else {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800295 logger.Errorw("No TCont instances found", log.Fields{"device-id": oFsm.deviceID})
296 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530297 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800298 /*
299 if !foundFreeTcontInstID {
300 // This should never happen. If it does, the behavior is unpredictable.
301 logger.Warnw("No free TCONT instances found", log.Fields{"device-id": oFsm.deviceID})
302 }*/
303
304 // Access critical state with lock
305 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000306 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
307 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
Girish Gowdra041dcb32020-11-16 16:54:30 -0800308 oFsm.pUniTechProf.mutexTPState.Unlock()
309
Himani Chawla26e555c2020-08-31 12:30:20 +0530310 loGemPortAttribs := ponAniGemPortAttribs{}
311 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800312
313 for _, gemEntry := range mapGemPortParams {
Himani Chawla26e555c2020-08-31 12:30:20 +0530314 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
315
Himani Chawla6d2ae152020-09-02 13:11:20 +0530316 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530317
318 loGemPortAttribs.gemPortID = gemEntry.gemPortID
319 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
320 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
321 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
322 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
323
324 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
325 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
326 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
327 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
328 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
329 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
330
331 usQueueFound := false
332 dsQueueFound := false
333 for _, mgmtEntityID := range queueInstKeys {
334 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
335 returnVal := meAttributes["RelatedPort"]
336 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530337 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530338 if relatedPort == usQrelPortMask {
339 loGemPortAttribs.upQueueID = mgmtEntityID
340 logger.Debugw("UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000341 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 usQueueFound = true
343 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
344 loGemPortAttribs.downQueueID = mgmtEntityID
345 logger.Debugw("DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000346 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 dsQueueFound = true
348 }
349 if usQueueFound && dsQueueFound {
350 break
351 }
352 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000353 logger.Warnw("Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 }
355 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000356 logger.Warnw("'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 }
358 } else {
359 logger.Warnw("No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000360 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 }
362 }
363 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000364 logger.Warnw("No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 }
366 loGemPortAttribs.direction = gemEntry.direction
367 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
368 loGemPortAttribs.weight = gemEntry.queueWeight
369 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia4b232302020-11-11 10:58:10 +0300370 if gemEntry.isMulticast {
371 loGemPortAttribs.isMulticast = true
372 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
373 loGemPortAttribs.staticACL = gemEntry.staticACL
374 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
375 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530376
377 logger.Debugw("prio-related GemPort attributes:", log.Fields{
378 "gemPortID": loGemPortAttribs.gemPortID,
379 "upQueueID": loGemPortAttribs.upQueueID,
380 "downQueueID": loGemPortAttribs.downQueueID,
381 "pbitString": loGemPortAttribs.pbitString,
382 "prioQueueIndex": gemEntry.prioQueueIndex,
ozgecanetsia4b232302020-11-11 10:58:10 +0300383 "isMulticast": loGemPortAttribs.isMulticast,
384 "multicastGemID": loGemPortAttribs.multicastGemID,
385 "staticACL": loGemPortAttribs.staticACL,
386 "dynamicACL": loGemPortAttribs.dynamicACL,
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 })
388
389 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
390 }
391 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
392 }
393}
394
Himani Chawla6d2ae152020-09-02 13:11:20 +0530395func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000396 logger.Debugw("UniPonAniConfigFsm start", log.Fields{
397 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000398 // in case the used channel is not yet defined (can be re-used after restarts)
399 if oFsm.omciMIdsResponseReceived == nil {
400 oFsm.omciMIdsResponseReceived = make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530401 logger.Debug("uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000402 } else {
403 // as we may 're-use' this instance of FSM and the connected channel
404 // make sure there is no 'lingering' request in the already existing channel:
405 // (simple loop sufficient as we are the only receiver)
406 for len(oFsm.omciMIdsResponseReceived) > 0 {
407 <-oFsm.omciMIdsResponseReceived
408 }
409 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000410 //ensure internal slices are empty (which might be set from previous run) - release memory
411 oFsm.gemPortAttribsSlice = nil
412
mpagenko3dbcdd22020-07-22 07:38:45 +0000413 // start go routine for processing of LockState messages
mpagenkodff5dda2020-08-28 11:52:01 +0000414 go oFsm.processOmciAniMessages()
mpagenko3dbcdd22020-07-22 07:38:45 +0000415
416 //let the state machine run forward from here directly
417 pConfigAniStateAFsm := oFsm.pAdaptFsm
418 if pConfigAniStateAFsm != nil {
419 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530420 go oFsm.prepareAndEnterConfigState(pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000421
mpagenko3dbcdd22020-07-22 07:38:45 +0000422 }
423}
424
Himani Chawla6d2ae152020-09-02 13:11:20 +0530425func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(e *fsm.Event) {
426 logger.Debugw("uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000427 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000428 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
429 oFsm.requestEventOffset = 0 //0 offset for last config request activity
mpagenko3dbcdd22020-07-22 07:38:45 +0000430 meInstance := oFsm.pOmciCC.sendCreateDot1PMapper(context.TODO(), ConstDefaultOmciTimeout, true,
431 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
432 //accept also nil as (error) return value for writing to LastTx
433 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000434 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000435}
436
Himani Chawla6d2ae152020-09-02 13:11:20 +0530437func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(e *fsm.Event) {
438 logger.Debugw("uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000439 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
440 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000441 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000442 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
443 meParams := me.ParamData{
444 EntityID: oFsm.macBPCD0ID,
445 Attributes: me.AttributeValueMap{
446 "BridgeIdPointer": bridgePtr,
447 "PortNum": 0xFF, //fixed unique ANI side indication
448 "TpType": 3, //for .1PMapper
449 "TpPointer": oFsm.mapperSP0ID,
450 },
451 }
452 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
453 oFsm.pAdaptFsm.commChan, meParams)
454 //accept also nil as (error) return value for writing to LastTx
455 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000456 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000457}
458
Himani Chawla6d2ae152020-09-02 13:11:20 +0530459func (oFsm *uniPonAniConfigFsm) enterSettingTconts(e *fsm.Event) {
460 logger.Debugw("uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000461 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
462 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000463 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000464 meParams := me.ParamData{
465 EntityID: oFsm.tcont0ID,
466 Attributes: me.AttributeValueMap{
467 "AllocId": oFsm.alloc0ID,
468 },
469 }
470 meInstance := oFsm.pOmciCC.sendSetTcontVar(context.TODO(), ConstDefaultOmciTimeout, true,
471 oFsm.pAdaptFsm.commChan, meParams)
472 //accept also nil as (error) return value for writing to LastTx
473 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000474 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000475}
476
Himani Chawla6d2ae152020-09-02 13:11:20 +0530477func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(e *fsm.Event) {
478 logger.Debugw("uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000479 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000480 go oFsm.performCreatingGemNCTPs()
481}
482
Himani Chawla6d2ae152020-09-02 13:11:20 +0530483func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(e *fsm.Event) {
484 logger.Debugw("uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000485 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000486 go oFsm.performCreatingGemIWs()
487}
488
Himani Chawla6d2ae152020-09-02 13:11:20 +0530489func (oFsm *uniPonAniConfigFsm) enterSettingPQs(e *fsm.Event) {
490 logger.Debugw("uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000491 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000492 go oFsm.performSettingPQs()
493}
494
Himani Chawla6d2ae152020-09-02 13:11:20 +0530495func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(e *fsm.Event) {
496 logger.Debugw("uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000497 "toGemIw": 1024, /* cmp above */
498 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000499
Himani Chawla6d2ae152020-09-02 13:11:20 +0530500 logger.Debugw("uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000501 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000502 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000503
mpagenko3dbcdd22020-07-22 07:38:45 +0000504 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000505 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530506 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000507 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000508
509 //assign the GemPorts according to the configured Prio
510 var loPrioGemPortArray [8]uint16
511 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
512 for i := 0; i < 8; i++ {
513 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
514 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
515 if prio == 1 { // Check this p-bit is set
516 if loPrioGemPortArray[i] == 0 {
517 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
518 } else {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530519 logger.Warnw("uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000520 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000521 "SetGemPort": loPrioGemPortArray[i]})
522 }
523 }
524 } else {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530525 logger.Warnw("uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000526 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000527 "prioString": gemPortAttribs.pbitString, "position": i})
528 }
529
530 }
531 }
ozgecanetsia4b232302020-11-11 10:58:10 +0300532 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530533 for index, value := range loPrioGemPortArray {
534 if value != 0 {
535 foundIwPtr = true
536 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530537 meParams.Attributes[meAttribute] = value
mpagenko01e726e2020-10-23 09:45:29 +0000538 logger.Debugw("UniPonAniConfigFsm Set::1pMapper", log.Fields{
539 "for Prio": index,
540 "IwPtr": strconv.FormatInt(int64(value), 16),
541 "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530542 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000543 }
Himani Chawla4d908332020-08-31 12:30:20 +0530544
545 if !foundIwPtr {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000546 logger.Errorw("UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000547 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000548 //let's reset the state machine in order to release all resources now
549 pConfigAniStateAFsm := oFsm.pAdaptFsm
550 if pConfigAniStateAFsm != nil {
551 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530552 go func(aPAFsm *AdapterFsm) {
553 if aPAFsm != nil && aPAFsm.pFsm != nil {
554 _ = aPAFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000555 }
556 }(pConfigAniStateAFsm)
557 }
558 }
559
mpagenko3dbcdd22020-07-22 07:38:45 +0000560 meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
561 oFsm.pAdaptFsm.commChan, meParams)
562 //accept also nil as (error) return value for writing to LastTx
563 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000564 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000565}
566
Himani Chawla6d2ae152020-09-02 13:11:20 +0530567func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000568 logger.Debugw("uniPonAniConfigFsm ani config done", log.Fields{
569 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000570 //use DeviceHandler event notification directly
mpagenko8b07c1b2020-11-26 10:36:31 +0000571 oFsm.pDeviceHandler.deviceProcStatusUpdate(OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko01e726e2020-10-23 09:45:29 +0000572 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800573 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko01e726e2020-10-23 09:45:29 +0000574 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
mpagenko8b07c1b2020-11-26 10:36:31 +0000575 // but only in case the techProfile was configured (not deleted)
576 if oFsm.requestEventOffset == 0 {
577 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(oFsm.pOnuUniPort)
578 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000579
mpagenko01e726e2020-10-23 09:45:29 +0000580 if oFsm.chanSet {
581 // indicate processing done to the caller
582 logger.Debugw("uniPonAniConfigFsm processingDone on channel", log.Fields{
583 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
584 oFsm.chSuccess <- oFsm.procStep
585 oFsm.chanSet = false //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000586 }
mpagenko01e726e2020-10-23 09:45:29 +0000587
588 //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 +0000589}
590
mpagenko8b07c1b2020-11-26 10:36:31 +0000591func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(e *fsm.Event) {
592 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
593 oFsm.pUniTechProf.mutexTPState.Lock()
594 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
595 oFsm.pUniTechProf.mutexTPState.Unlock()
596 logger.Debugw("uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
597 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
598 "GemIwTp-entity-id": loGemPortID})
599 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
600
601 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
602 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(context.TODO(), ConstDefaultOmciTimeout, true,
603 oFsm.pAdaptFsm.commChan, loGemPortID)
604 oFsm.pLastTxMeInstance = meInstance
605}
606
607func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(e *fsm.Event) {
608 oFsm.pUniTechProf.mutexTPState.Lock()
609 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
610 oFsm.pUniTechProf.mutexTPState.Unlock()
611 logger.Debugw("uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
612 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
613 "GemNCTP-entity-id": loGemPortID})
614 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
615 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(context.TODO(), ConstDefaultOmciTimeout, true,
616 oFsm.pAdaptFsm.commChan, loGemPortID)
617 oFsm.pLastTxMeInstance = meInstance
618}
619
620func (oFsm *uniPonAniConfigFsm) enterResettingTcont(e *fsm.Event) {
621 logger.Debugw("uniPonAniConfigFsm - start resetting the TCont", log.Fields{
622 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
623
624 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
625 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
626 meParams := me.ParamData{
627 EntityID: oFsm.tcont0ID,
628 Attributes: me.AttributeValueMap{
629 "AllocId": unusedTcontAllocID,
630 },
631 }
632 meInstance := oFsm.pOmciCC.sendSetTcontVar(context.TODO(), ConstDefaultOmciTimeout, true,
633 oFsm.pAdaptFsm.commChan, meParams)
634 oFsm.pLastTxMeInstance = meInstance
635}
636
637func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(e *fsm.Event) {
638 logger.Debugw("uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
639 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
640
641 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(context.TODO(), ConstDefaultOmciTimeout, true,
642 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
643 oFsm.pLastTxMeInstance = meInstance
644}
645
646func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(e *fsm.Event) {
647 logger.Debugw("uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
648 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
649
650 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(context.TODO(), ConstDefaultOmciTimeout, true,
651 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
652 oFsm.pLastTxMeInstance = meInstance
653}
654
655func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(e *fsm.Event) {
656 logger.Debugw("uniPonAniConfigFsm ani removal done", log.Fields{
657 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
658 //use DeviceHandler event notification directly
659 oFsm.pDeviceHandler.deviceProcStatusUpdate(OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
660 if oFsm.chanSet {
661 // indicate processing done to the caller
662 logger.Debugw("uniPonAniConfigFsm processingDone on channel", log.Fields{
663 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
664 oFsm.chSuccess <- oFsm.procStep
665 oFsm.chanSet = false //reset the internal channel state
666 }
667
668 //let's reset the state machine in order to release all resources now
669 pConfigAniStateAFsm := oFsm.pAdaptFsm
670 if pConfigAniStateAFsm != nil {
671 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
672 go func(aPAFsm *AdapterFsm) {
673 if aPAFsm != nil && aPAFsm.pFsm != nil {
674 _ = aPAFsm.pFsm.Event(aniEvReset)
675 }
676 }(pConfigAniStateAFsm)
677 }
678}
679
Himani Chawla6d2ae152020-09-02 13:11:20 +0530680func (oFsm *uniPonAniConfigFsm) enterResettingState(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000681 logger.Debugw("uniPonAniConfigFsm resetting", log.Fields{
682 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000683
mpagenko3dbcdd22020-07-22 07:38:45 +0000684 pConfigAniStateAFsm := oFsm.pAdaptFsm
685 if pConfigAniStateAFsm != nil {
686 // abort running message processing
687 fsmAbortMsg := Message{
688 Type: TestMsg,
689 Data: TestMessage{
690 TestMessageVal: AbortMessageProcessing,
691 },
692 }
693 pConfigAniStateAFsm.commChan <- fsmAbortMsg
694
695 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530696 go func(aPAFsm *AdapterFsm) {
697 if aPAFsm != nil && aPAFsm.pFsm != nil {
698 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000699 }
700 }(pConfigAniStateAFsm)
701 }
702}
703
Himani Chawla6d2ae152020-09-02 13:11:20 +0530704func (oFsm *uniPonAniConfigFsm) enterDisabledState(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000705 logger.Debugw("uniPonAniConfigFsm enters disabled state", log.Fields{
706 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000707 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000708
mpagenko01e726e2020-10-23 09:45:29 +0000709 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800710 oFsm.pUniTechProf.clearAniSideConfig(oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000711}
712
Himani Chawla6d2ae152020-09-02 13:11:20 +0530713func (oFsm *uniPonAniConfigFsm) processOmciAniMessages( /*ctx context.Context*/ ) {
mpagenko01e726e2020-10-23 09:45:29 +0000714 logger.Debugw("Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000715loop:
716 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000717 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000718 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000719 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530720 message, ok := <-oFsm.pAdaptFsm.commChan
721 if !ok {
mpagenko01e726e2020-10-23 09:45:29 +0000722 logger.Info("UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530723 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
724 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
725 break loop
726 }
mpagenko01e726e2020-10-23 09:45:29 +0000727 logger.Debugw("UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530728
729 switch message.Type {
730 case TestMsg:
731 msg, _ := message.Data.(TestMessage)
732 if msg.TestMessageVal == AbortMessageProcessing {
mpagenko01e726e2020-10-23 09:45:29 +0000733 logger.Infow("UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000734 break loop
735 }
mpagenko01e726e2020-10-23 09:45:29 +0000736 logger.Warnw("UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530737 case OMCI:
738 msg, _ := message.Data.(OmciMessage)
739 oFsm.handleOmciAniConfigMessage(msg)
740 default:
mpagenko01e726e2020-10-23 09:45:29 +0000741 logger.Warn("UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530742 "message.Type": message.Type})
743 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000744
Himani Chawla4d908332020-08-31 12:30:20 +0530745 }
mpagenko01e726e2020-10-23 09:45:29 +0000746 logger.Infow("End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530747}
748
Himani Chawla6d2ae152020-09-02 13:11:20 +0530749func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530750 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
751 if msgLayer == nil {
Andrea Campanella6515c582020-10-05 11:25:00 +0200752 logger.Errorw("Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000753 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530754 return
755 }
756 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
757 if !msgOk {
Andrea Campanella6515c582020-10-05 11:25:00 +0200758 logger.Errorw("Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000759 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530760 return
761 }
mpagenko01e726e2020-10-23 09:45:29 +0000762 logger.Debugw("CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000763 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
764 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
765 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
766 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
767 // maybe we can use just the same eventName for different state transitions like "forward"
768 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
769 switch oFsm.pLastTxMeInstance.GetName() {
770 case "Ieee8021PMapperServiceProfile":
771 { // let the FSM proceed ...
772 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
773 }
774 case "MacBridgePortConfigurationData":
775 { // let the FSM proceed ...
776 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
777 }
778 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint":
779 { // let aniConfig Multi-Id processing proceed by stopping the wait function
780 oFsm.omciMIdsResponseReceived <- true
781 }
782 }
783 }
784 } else {
Himani Chawla4d908332020-08-31 12:30:20 +0530785 logger.Errorw("Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
786 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
787 return
788 }
Himani Chawla4d908332020-08-31 12:30:20 +0530789}
790
Himani Chawla6d2ae152020-09-02 13:11:20 +0530791func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530792 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
793 if msgLayer == nil {
Andrea Campanella6515c582020-10-05 11:25:00 +0200794 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000795 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530796 return
797 }
798 msgObj, msgOk := msgLayer.(*omci.SetResponse)
799 if !msgOk {
Andrea Campanella6515c582020-10-05 11:25:00 +0200800 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000801 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530802 return
803 }
mpagenko01e726e2020-10-23 09:45:29 +0000804 logger.Debugw("UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530805 if msgObj.Result != me.Success {
Andrea Campanella6515c582020-10-05 11:25:00 +0200806 logger.Errorw("UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000807 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530808 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
809 return
810 }
mpagenko01e726e2020-10-23 09:45:29 +0000811 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
812 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530813 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
814 // if, then something like:
815 //oFsm.pOnuDB.StoreMe(msgObj)
816
mpagenko01e726e2020-10-23 09:45:29 +0000817 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530818 case "TCont":
819 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000820 if oFsm.requestEventOffset == 0 { //from TCont config request
821 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
822 } else { // from T-Cont reset request
823 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
824 }
Himani Chawla4d908332020-08-31 12:30:20 +0530825 }
826 case "PriorityQueue":
827 { // let the PrioQueue init proceed by stopping the wait function
828 oFsm.omciMIdsResponseReceived <- true
829 }
830 case "Ieee8021PMapperServiceProfile":
831 { // let the FSM proceed ...
832 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
833 }
834 }
835 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000836}
837
mpagenko8b07c1b2020-11-26 10:36:31 +0000838func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(msg OmciMessage) {
839 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
840 if msgLayer == nil {
841 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
842 log.Fields{"device-id": oFsm.deviceID})
843 return
844 }
845 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
846 if !msgOk {
847 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
848 log.Fields{"device-id": oFsm.deviceID})
849 return
850 }
851 logger.Debugw("UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
852 if msgObj.Result != me.Success {
853 logger.Errorw("UniPonAniConfigFsm - Omci DeleteResponse Error",
854 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
855 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
856 // store error for mgmt display?
857 return
858 }
859 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
860 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
861 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
862 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
863
864 switch oFsm.pLastTxMeInstance.GetName() {
865 case "GemInterworkingTerminationPoint":
866 { // let the FSM proceed ...
867 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
868 }
869 case "GemPortNetworkCtp":
870 { // let the FSM proceed ...
871 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
872 }
873 case "Ieee8021PMapperServiceProfile":
874 { // let the FSM proceed ...
875 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
876 }
877 case "MacBridgePortConfigurationData":
878 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
879 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
880 }
881 }
882 }
883}
884
Himani Chawla6d2ae152020-09-02 13:11:20 +0530885func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(msg OmciMessage) {
mpagenko01e726e2020-10-23 09:45:29 +0000886 logger.Debugw("Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000887 "msgType": msg.OmciMsg.MessageType})
888
889 switch msg.OmciMsg.MessageType {
890 case omci.CreateResponseType:
891 {
Himani Chawla4d908332020-08-31 12:30:20 +0530892 oFsm.handleOmciAniConfigCreateResponseMessage(msg)
893
mpagenko3dbcdd22020-07-22 07:38:45 +0000894 } //CreateResponseType
895 case omci.SetResponseType:
896 {
Himani Chawla4d908332020-08-31 12:30:20 +0530897 oFsm.handleOmciAniConfigSetResponseMessage(msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000898
mpagenko3dbcdd22020-07-22 07:38:45 +0000899 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000900 case omci.DeleteResponseType:
901 {
902 oFsm.handleOmciAniConfigDeleteResponseMessage(msg)
903
904 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000905 default:
906 {
Andrea Campanella6515c582020-10-05 11:25:00 +0200907 logger.Errorw("uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000908 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000909 return
910 }
911 }
912}
913
Himani Chawla6d2ae152020-09-02 13:11:20 +0530914func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000915 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
916 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530917 logger.Debugw("uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000918 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
919 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000920 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000921 meParams := me.ParamData{
922 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
923 Attributes: me.AttributeValueMap{
924 "PortId": gemPortAttribs.gemPortID,
925 "TContPointer": oFsm.tcont0ID,
926 "Direction": gemPortAttribs.direction,
927 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
928 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
929 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
930 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
931 },
932 }
933 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
934 oFsm.pAdaptFsm.commChan, meParams)
935 //accept also nil as (error) return value for writing to LastTx
936 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000937 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000938
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000939 //verify response
940 err := oFsm.waitforOmciResponse()
941 if err != nil {
942 logger.Errorw("GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000943 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +0530944 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000945 return
946 }
947 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +0000948
949 // if Config has been done for all GemPort instances let the FSM proceed
mpagenko01e726e2020-10-23 09:45:29 +0000950 logger.Debugw("GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530951 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000952}
953
Himani Chawla6d2ae152020-09-02 13:11:20 +0530954func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000955 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
956 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530957 logger.Debugw("uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000958 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
959 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000960 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000961
ozgecanetsia4b232302020-11-11 10:58:10 +0300962 //TODO if the port has only downstream direction the isMulticast flag can be removed.
963 if gemPortAttribs.isMulticast {
964 ipv4MulticastTable := make([]uint8, 12)
965 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.gemPortID)
966 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
967 // This is the 224.0.0.1 address
968 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4allsys))
969 // this is the 255.255.255.255 address
970 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4bcast))
971
972 meParams := me.ParamData{
973 EntityID: gemPortAttribs.gemPortID,
974 Attributes: me.AttributeValueMap{
975 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID,
976 "InterworkingOption": 0, // Don't Care
977 "ServiceProfilePointer": 0, // Don't Care
978 "GalProfilePointer": galEthernetEID,
979 "Ipv4MulticastAddressTable": ipv4MulticastTable,
980 },
981 }
982 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
983 true, oFsm.pAdaptFsm.commChan, meParams)
984 oFsm.pLastTxMeInstance = meInstance
985
986 } else {
987 meParams := me.ParamData{
988 EntityID: gemPortAttribs.gemPortID,
989 Attributes: me.AttributeValueMap{
990 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
991 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
992 "ServiceProfilePointer": oFsm.mapperSP0ID,
993 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
994 "GalProfilePointer": galEthernetEID,
995 },
996 }
997 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
998 oFsm.pAdaptFsm.commChan, meParams)
999 //accept also nil as (error) return value for writing to LastTx
1000 // - this avoids misinterpretation of new received OMCI messages
1001 oFsm.pLastTxMeInstance = meInstance
1002 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001003 //verify response
1004 err := oFsm.waitforOmciResponse()
1005 if err != nil {
ozgecanetsia4b232302020-11-11 10:58:10 +03001006 logger.Errorw("GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001007 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301008 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001009 return
1010 }
1011 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001012
1013 // if Config has been done for all GemPort instances let the FSM proceed
mpagenko01e726e2020-10-23 09:45:29 +00001014 logger.Debugw("GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301015 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001016}
1017
Himani Chawla6d2ae152020-09-02 13:11:20 +05301018func (oFsm *uniPonAniConfigFsm) performSettingPQs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001019 const cu16StrictPrioWeight uint16 = 0xFFFF
1020 //find all upstream PrioQueues related to this T-Cont
1021 loQueueMap := ordered_map.NewOrderedMap()
1022 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1023 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301024 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001025 //key does not yet exist
1026 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1027 }
1028 } else {
1029 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1030 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001031 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001032
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001033 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1034 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1035 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1036 // or even be finished without correct SP/WRR setting
1037
1038 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1039 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1040 // even though its T-Cont seems to be wrong ...
1041 loTrafficSchedulerEID := 0x8000
1042 //for all found queues
1043 iter := loQueueMap.IterFunc()
1044 for kv, ok := iter(); ok; kv, ok = iter() {
1045 queueIndex := (kv.Key).(uint16)
1046 meParams := me.ParamData{
1047 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301048 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001049 }
1050 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1051 //StrictPrio indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301052 logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001053 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001054 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001055 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1056 } else {
1057 //WRR indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301058 logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001059 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1060 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001061 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001062 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1063 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1064 }
1065 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(context.TODO(), ConstDefaultOmciTimeout, true,
1066 oFsm.pAdaptFsm.commChan, meParams)
1067 //accept also nil as (error) return value for writing to LastTx
1068 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001069 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001070
1071 //verify response
1072 err := oFsm.waitforOmciResponse()
1073 if err != nil {
1074 logger.Errorw("PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001075 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301076 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001077 return
1078 }
1079
1080 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1081 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1082 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1083 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1084
1085 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001086
1087 // if Config has been done for all PrioQueue instances let the FSM proceed
mpagenko01e726e2020-10-23 09:45:29 +00001088 logger.Debugw("PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301089 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001090}
1091
Himani Chawla6d2ae152020-09-02 13:11:20 +05301092func (oFsm *uniPonAniConfigFsm) waitforOmciResponse() error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001093 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301094 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001095 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001096 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001097 case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
mpagenko01e726e2020-10-23 09:45:29 +00001098 logger.Warnw("UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
1099 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001100 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301101 if success {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301102 logger.Debug("uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001103 return nil
1104 }
1105 // should not happen so far
mpagenko01e726e2020-10-23 09:45:29 +00001106 logger.Warnw("uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
1107 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001108 }
1109}