blob: fdd7830bba41c108eae0a1647241000268e45168 [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
26 "time"
27
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000028 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000029 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/opencord/omci-lib-go"
31 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/log"
33 //ic "github.com/opencord/voltha-protos/v4/go/inter_container"
34 //"github.com/opencord/voltha-protos/v4/go/openflow_13"
35 //"github.com/opencord/voltha-protos/v4/go/voltha"
mpagenko3dbcdd22020-07-22 07:38:45 +000036)
37
mpagenko1cc3cb42020-07-27 15:24:38 +000038const (
39 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000040 aniEvStart = "aniEvStart"
41 aniEvStartConfig = "aniEvStartConfig"
42 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
43 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
44 aniEvRxTcontsResp = "aniEvRxTcontsResp"
45 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
46 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
47 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
48 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
49 aniEvRemGemiw = "aniEvRemGemiw"
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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000126func newUniPonAniConfigFsm(ctx context.Context, 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 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000144 logger.Errorw(ctx, "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{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000195 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
196 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
197 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
198 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
199 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
200 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
201 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
202 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
203 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
204 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
205 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
206 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
207 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
208 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
209 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
210 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
211 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
212 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000213 },
214 )
215 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000216 logger.Errorw(ctx, "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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000221 logger.Debugw(ctx, "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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000232func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, 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 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000243 if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, 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]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000281 logger.Debugw(ctx, "Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800282 "device-id": oFsm.deviceID})
283 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Errorw(ctx, "tech profile id not in valid range", log.Fields{"device-id": oFsm.deviceID, "tp-id": oFsm.techProfileID, "num-tcont": len(tcontInstKeys)})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800285 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 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000295 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800296 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 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800311 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300312 loGemPortAttribs := ponAniGemPortAttribs{}
313
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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, 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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000340 logger.Debugw(ctx, "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
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Debugw(ctx, "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 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 }
355 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 }
358 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 logger.Warnw(ctx, "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 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 logger.Warnw(ctx, "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 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300371 //TODO this might effectively ignore the for loop starting at line 316
372 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300373 loGemPortAttribs.isMulticast = true
374 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
375 loGemPortAttribs.staticACL = gemEntry.staticACL
376 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530377
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300379 "gemPortID": loGemPortAttribs.gemPortID,
380 "isMulticast": loGemPortAttribs.isMulticast,
381 "multicastGemID": loGemPortAttribs.multicastGemID,
382 "staticACL": loGemPortAttribs.staticACL,
383 "dynamicACL": loGemPortAttribs.dynamicACL,
384 })
385
386 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000387 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300388 "gemPortID": loGemPortAttribs.gemPortID,
389 "upQueueID": loGemPortAttribs.upQueueID,
390 "downQueueID": loGemPortAttribs.downQueueID,
391 "pbitString": loGemPortAttribs.pbitString,
392 "prioQueueIndex": gemEntry.prioQueueIndex,
393 })
394 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530395
396 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
397 }
398 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
399 }
400}
401
dbainbri4d3a0dc2020-12-02 00:33:42 +0000402func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
403 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000404 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000405 // in case the used channel is not yet defined (can be re-used after restarts)
406 if oFsm.omciMIdsResponseReceived == nil {
407 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000408 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000409 } else {
410 // as we may 're-use' this instance of FSM and the connected channel
411 // make sure there is no 'lingering' request in the already existing channel:
412 // (simple loop sufficient as we are the only receiver)
413 for len(oFsm.omciMIdsResponseReceived) > 0 {
414 <-oFsm.omciMIdsResponseReceived
415 }
416 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000417 //ensure internal slices are empty (which might be set from previous run) - release memory
418 oFsm.gemPortAttribsSlice = nil
419
mpagenko3dbcdd22020-07-22 07:38:45 +0000420 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000422
423 //let the state machine run forward from here directly
424 pConfigAniStateAFsm := oFsm.pAdaptFsm
425 if pConfigAniStateAFsm != nil {
426 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000428
mpagenko3dbcdd22020-07-22 07:38:45 +0000429 }
430}
431
dbainbri4d3a0dc2020-12-02 00:33:42 +0000432func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
433 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000434 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000435 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
436 oFsm.requestEventOffset = 0 //0 offset for last config request activity
dbainbri4d3a0dc2020-12-02 00:33:42 +0000437 meInstance := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000438 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
439 //accept also nil as (error) return value for writing to LastTx
440 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000441 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000442}
443
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
445 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000446 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
447 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000448 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000449 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
450 meParams := me.ParamData{
451 EntityID: oFsm.macBPCD0ID,
452 Attributes: me.AttributeValueMap{
453 "BridgeIdPointer": bridgePtr,
454 "PortNum": 0xFF, //fixed unique ANI side indication
455 "TpType": 3, //for .1PMapper
456 "TpPointer": oFsm.mapperSP0ID,
457 },
458 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000459 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000460 oFsm.pAdaptFsm.commChan, meParams)
461 //accept also nil as (error) return value for writing to LastTx
462 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000463 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000464}
465
dbainbri4d3a0dc2020-12-02 00:33:42 +0000466func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
467 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000468 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
469 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000470 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000471 meParams := me.ParamData{
472 EntityID: oFsm.tcont0ID,
473 Attributes: me.AttributeValueMap{
474 "AllocId": oFsm.alloc0ID,
475 },
476 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000478 oFsm.pAdaptFsm.commChan, meParams)
479 //accept also nil as (error) return value for writing to LastTx
480 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000481 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000482}
483
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
485 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000486 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000488}
489
dbainbri4d3a0dc2020-12-02 00:33:42 +0000490func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
491 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000492 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000494}
495
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
497 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000498 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000500}
501
dbainbri4d3a0dc2020-12-02 00:33:42 +0000502func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300503
dbainbri4d3a0dc2020-12-02 00:33:42 +0000504 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000505 "toGemIw": 1024, /* cmp above */
506 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000507
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000509 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000510 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000511
mpagenko3dbcdd22020-07-22 07:38:45 +0000512 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000513 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530514 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000515 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000516
517 //assign the GemPorts according to the configured Prio
518 var loPrioGemPortArray [8]uint16
519 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300520 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300522 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
523 "prioString": gemPortAttribs.pbitString})
524 continue
525 }
526 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300528 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
529 "prioString": gemPortAttribs.pbitString})
530 continue
531 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000532 for i := 0; i < 8; i++ {
533 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
534 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
535 if prio == 1 { // Check this p-bit is set
536 if loPrioGemPortArray[i] == 0 {
537 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
538 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000539 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000540 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000541 "SetGemPort": loPrioGemPortArray[i]})
542 }
543 }
544 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000545 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000546 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000547 "prioString": gemPortAttribs.pbitString, "position": i})
548 }
549
550 }
551 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300552
ozgecanetsia4b232302020-11-11 10:58:10 +0300553 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530554 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300555 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530556 if value != 0 {
557 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530558 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000559 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000560 "for Prio": index,
561 "IwPtr": strconv.FormatInt(int64(value), 16),
562 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300563 } else {
564 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000565 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
566 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300567 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530568 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000569 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300570 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000571 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
572 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300573 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530574
575 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000577 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300578 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
579 // this reset needs to be performed only if the tech profile provides upstream gem ports but no priority is set
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000580 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300581 //pConfigAniStateAFsm := oFsm.pAdaptFsm
582 //if pConfigAniStateAFsm != nil {
583 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
584 // go func(aPAFsm *AdapterFsm) {
585 // if aPAFsm != nil && aPAFsm.pFsm != nil {
586 // _ = aPAFsm.pFsm.Event(aniEvReset)
587 // }
588 // }(pConfigAniStateAFsm)
589 //}
590 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000591 pConfigAniStateAFsm := oFsm.pAdaptFsm
592 if pConfigAniStateAFsm != nil {
593 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530594 go func(aPAFsm *AdapterFsm) {
595 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300596 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000597 }
598 }(pConfigAniStateAFsm)
599 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300600 } else {
601 meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
602 oFsm.pAdaptFsm.commChan, meParams)
603 //accept also nil as (error) return value for writing to LastTx
604 // - this avoids misinterpretation of new received OMCI messages
605 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000606 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000607}
608
dbainbri4d3a0dc2020-12-02 00:33:42 +0000609func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
610 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000611 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000612 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko01e726e2020-10-23 09:45:29 +0000614 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800615 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko01e726e2020-10-23 09:45:29 +0000616 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
mpagenko8b07c1b2020-11-26 10:36:31 +0000617 // but only in case the techProfile was configured (not deleted)
618 if oFsm.requestEventOffset == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000619 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
mpagenko8b07c1b2020-11-26 10:36:31 +0000620 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000621
mpagenko01e726e2020-10-23 09:45:29 +0000622 if oFsm.chanSet {
623 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000624 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000625 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
626 oFsm.chSuccess <- oFsm.procStep
627 oFsm.chanSet = false //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000628 }
mpagenko01e726e2020-10-23 09:45:29 +0000629
630 //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 +0000631}
632
dbainbri4d3a0dc2020-12-02 00:33:42 +0000633func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000634 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
635 oFsm.pUniTechProf.mutexTPState.Lock()
636 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
637 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000638 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000639 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
640 "GemIwTp-entity-id": loGemPortID})
641 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
642
643 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000645 oFsm.pAdaptFsm.commChan, loGemPortID)
646 oFsm.pLastTxMeInstance = meInstance
647}
648
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000650 oFsm.pUniTechProf.mutexTPState.Lock()
651 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
652 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000654 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
655 "GemNCTP-entity-id": loGemPortID})
656 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000658 oFsm.pAdaptFsm.commChan, loGemPortID)
659 oFsm.pLastTxMeInstance = meInstance
660}
661
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
663 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000664 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
665
666 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
667 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
668 meParams := me.ParamData{
669 EntityID: oFsm.tcont0ID,
670 Attributes: me.AttributeValueMap{
671 "AllocId": unusedTcontAllocID,
672 },
673 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000675 oFsm.pAdaptFsm.commChan, meParams)
676 oFsm.pLastTxMeInstance = meInstance
677}
678
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
680 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000681 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
682
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000684 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
685 oFsm.pLastTxMeInstance = meInstance
686}
687
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
689 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000690 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
691
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000693 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
694 oFsm.pLastTxMeInstance = meInstance
695}
696
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
698 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000699 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
700 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko8b07c1b2020-11-26 10:36:31 +0000702 if oFsm.chanSet {
703 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000705 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
706 oFsm.chSuccess <- oFsm.procStep
707 oFsm.chanSet = false //reset the internal channel state
708 }
709
710 //let's reset the state machine in order to release all resources now
711 pConfigAniStateAFsm := oFsm.pAdaptFsm
712 if pConfigAniStateAFsm != nil {
713 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
714 go func(aPAFsm *AdapterFsm) {
715 if aPAFsm != nil && aPAFsm.pFsm != nil {
716 _ = aPAFsm.pFsm.Event(aniEvReset)
717 }
718 }(pConfigAniStateAFsm)
719 }
720}
721
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
723 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000724 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000725
mpagenko3dbcdd22020-07-22 07:38:45 +0000726 pConfigAniStateAFsm := oFsm.pAdaptFsm
727 if pConfigAniStateAFsm != nil {
728 // abort running message processing
729 fsmAbortMsg := Message{
730 Type: TestMsg,
731 Data: TestMessage{
732 TestMessageVal: AbortMessageProcessing,
733 },
734 }
735 pConfigAniStateAFsm.commChan <- fsmAbortMsg
736
737 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530738 go func(aPAFsm *AdapterFsm) {
739 if aPAFsm != nil && aPAFsm.pFsm != nil {
740 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000741 }
742 }(pConfigAniStateAFsm)
743 }
744}
745
dbainbri4d3a0dc2020-12-02 00:33:42 +0000746func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
747 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000748 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000749 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000750
mpagenko01e726e2020-10-23 09:45:29 +0000751 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000753}
754
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
756 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000757loop:
758 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000759 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000760 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000761 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530762 message, ok := <-oFsm.pAdaptFsm.commChan
763 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530765 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
766 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
767 break loop
768 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530770
771 switch message.Type {
772 case TestMsg:
773 msg, _ := message.Data.(TestMessage)
774 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000776 break loop
777 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530779 case OMCI:
780 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530782 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000783 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530784 "message.Type": message.Type})
785 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000786
Himani Chawla4d908332020-08-31 12:30:20 +0530787 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530789}
790
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530792 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
793 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
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.CreateResponse)
799 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000801 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530802 return
803 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000805 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
806 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
807 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
808 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
809 // maybe we can use just the same eventName for different state transitions like "forward"
810 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
811 switch oFsm.pLastTxMeInstance.GetName() {
812 case "Ieee8021PMapperServiceProfile":
813 { // let the FSM proceed ...
814 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
815 }
816 case "MacBridgePortConfigurationData":
817 { // let the FSM proceed ...
818 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
819 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300820 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
mpagenkofc4f56e2020-11-04 17:17:49 +0000821 { // let aniConfig Multi-Id processing proceed by stopping the wait function
822 oFsm.omciMIdsResponseReceived <- true
823 }
824 }
825 }
826 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530828 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
829 return
830 }
Himani Chawla4d908332020-08-31 12:30:20 +0530831}
832
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530834 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
835 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000837 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530838 return
839 }
840 msgObj, msgOk := msgLayer.(*omci.SetResponse)
841 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000843 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530844 return
845 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530847 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000848 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000849 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530850 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
851 return
852 }
mpagenko01e726e2020-10-23 09:45:29 +0000853 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
854 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530855 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
856 // if, then something like:
857 //oFsm.pOnuDB.StoreMe(msgObj)
858
mpagenko01e726e2020-10-23 09:45:29 +0000859 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530860 case "TCont":
861 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000862 if oFsm.requestEventOffset == 0 { //from TCont config request
863 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
864 } else { // from T-Cont reset request
865 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
866 }
Himani Chawla4d908332020-08-31 12:30:20 +0530867 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300868 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
Himani Chawla4d908332020-08-31 12:30:20 +0530869 { // let the PrioQueue init proceed by stopping the wait function
870 oFsm.omciMIdsResponseReceived <- true
871 }
872 case "Ieee8021PMapperServiceProfile":
873 { // let the FSM proceed ...
874 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
875 }
876 }
877 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000878}
879
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000881 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
882 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000884 log.Fields{"device-id": oFsm.deviceID})
885 return
886 }
887 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
888 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000890 log.Fields{"device-id": oFsm.deviceID})
891 return
892 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000893 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +0000894 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +0000896 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
897 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
898 // store error for mgmt display?
899 return
900 }
901 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
902 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
903 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
904 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
905
906 switch oFsm.pLastTxMeInstance.GetName() {
907 case "GemInterworkingTerminationPoint":
908 { // let the FSM proceed ...
909 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
910 }
911 case "GemPortNetworkCtp":
912 { // let the FSM proceed ...
913 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
914 }
915 case "Ieee8021PMapperServiceProfile":
916 { // let the FSM proceed ...
917 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
918 }
919 case "MacBridgePortConfigurationData":
920 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
921 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
922 }
923 }
924 }
925}
926
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
928 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000929 "msgType": msg.OmciMsg.MessageType})
930
931 switch msg.OmciMsg.MessageType {
932 case omci.CreateResponseType:
933 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000934 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530935
mpagenko3dbcdd22020-07-22 07:38:45 +0000936 } //CreateResponseType
937 case omci.SetResponseType:
938 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000940
mpagenko3dbcdd22020-07-22 07:38:45 +0000941 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000942 case omci.DeleteResponseType:
943 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +0000945
946 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000947 default:
948 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000950 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000951 return
952 }
953 }
954}
955
dbainbri4d3a0dc2020-12-02 00:33:42 +0000956func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000957 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
958 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000960 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
961 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000962 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000963 meParams := me.ParamData{
964 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
965 Attributes: me.AttributeValueMap{
966 "PortId": gemPortAttribs.gemPortID,
967 "TContPointer": oFsm.tcont0ID,
968 "Direction": gemPortAttribs.direction,
969 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
970 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
971 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
972 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
973 },
974 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000976 oFsm.pAdaptFsm.commChan, meParams)
977 //accept also nil as (error) return value for writing to LastTx
978 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000979 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000980
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000981 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +0000982 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000983 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000984 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000985 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +0530986 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000987 return
988 }
989 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +0000990
991 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530993 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000994}
995
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000997 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
998 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001000 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1001 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001002 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001003
ozgecanetsia4b232302020-11-11 10:58:10 +03001004 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1005 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001006
1007 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001008 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001009 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001010 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001011 "InterworkingOption": 0, // Don't Care
1012 "ServiceProfilePointer": 0, // Don't Care
1013 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001014 },
1015 }
1016 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1017 true, oFsm.pAdaptFsm.commChan, meParams)
1018 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001019 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001021 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022 logger.Errorw(ctx, "GemTP IW multicast create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001023 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1024 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1025 return
1026 }
1027 ipv4MulticastTable := make([]uint8, 12)
1028 //Gem Port ID
1029 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1030 //Secondary Key
1031 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1032 // Multicast IP range start This is the 224.0.0.1 address
1033 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1034 // MulticastIp range stop
1035 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1036
1037 meIPV4MCTableParams := me.ParamData{
1038 EntityID: gemPortAttribs.multicastGemID,
1039 Attributes: me.AttributeValueMap{
1040 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1041 },
1042 }
1043 meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1044 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
1045 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
ozgecanetsia4b232302020-11-11 10:58:10 +03001046
1047 } else {
1048 meParams := me.ParamData{
1049 EntityID: gemPortAttribs.gemPortID,
1050 Attributes: me.AttributeValueMap{
1051 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1052 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1053 "ServiceProfilePointer": oFsm.mapperSP0ID,
1054 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1055 "GalProfilePointer": galEthernetEID,
1056 },
1057 }
1058 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
1059 oFsm.pAdaptFsm.commChan, meParams)
1060 //accept also nil as (error) return value for writing to LastTx
1061 // - this avoids misinterpretation of new received OMCI messages
1062 oFsm.pLastTxMeInstance = meInstance
1063 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001064 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001066 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001067 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001068 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301069 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001070 return
1071 }
1072 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001073
1074 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001075 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301076 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001077}
1078
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001080 const cu16StrictPrioWeight uint16 = 0xFFFF
1081 //find all upstream PrioQueues related to this T-Cont
1082 loQueueMap := ordered_map.NewOrderedMap()
1083 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001084 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001085 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001086 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1087 "prioString": gemPortAttribs.pbitString})
1088 continue
1089 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001090 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301091 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001092 //key does not yet exist
1093 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1094 }
1095 } else {
1096 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1097 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001098 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001099
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001100 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1101 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1102 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1103 // or even be finished without correct SP/WRR setting
1104
1105 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1106 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1107 // even though its T-Cont seems to be wrong ...
1108 loTrafficSchedulerEID := 0x8000
1109 //for all found queues
1110 iter := loQueueMap.IterFunc()
1111 for kv, ok := iter(); ok; kv, ok = iter() {
1112 queueIndex := (kv.Key).(uint16)
1113 meParams := me.ParamData{
1114 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301115 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001116 }
1117 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1118 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001120 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001121 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001122 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1123 } else {
1124 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001126 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1127 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001128 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001129 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1130 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1131 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001133 oFsm.pAdaptFsm.commChan, meParams)
1134 //accept also nil as (error) return value for writing to LastTx
1135 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001136 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001137
1138 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001139 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001140 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001141 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001142 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301143 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001144 return
1145 }
1146
1147 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1148 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1149 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1150 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1151
1152 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001153
1154 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301156 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001157}
1158
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001160 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301161 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001162 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001163 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001164 case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001166 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001167 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301168 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 logger.Debug(ctx, "uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001170 return nil
1171 }
1172 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 logger.Warnw(ctx, "uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001174 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001175 }
1176}