blob: e04f8c7de65e1272e50c138b8b580c366d71fae1 [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.
565 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530566 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000567 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300568 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
569 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530570
571 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000573 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300574 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
575 // 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 +0000576 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300577 //pConfigAniStateAFsm := oFsm.pAdaptFsm
578 //if pConfigAniStateAFsm != nil {
579 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
580 // go func(aPAFsm *AdapterFsm) {
581 // if aPAFsm != nil && aPAFsm.pFsm != nil {
582 // _ = aPAFsm.pFsm.Event(aniEvReset)
583 // }
584 // }(pConfigAniStateAFsm)
585 //}
586 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000587 pConfigAniStateAFsm := oFsm.pAdaptFsm
588 if pConfigAniStateAFsm != nil {
589 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530590 go func(aPAFsm *AdapterFsm) {
591 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300592 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000593 }
594 }(pConfigAniStateAFsm)
595 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300596 } else {
597 meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
598 oFsm.pAdaptFsm.commChan, meParams)
599 //accept also nil as (error) return value for writing to LastTx
600 // - this avoids misinterpretation of new received OMCI messages
601 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000602 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000603}
604
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
606 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000607 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000608 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000609 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko01e726e2020-10-23 09:45:29 +0000610 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800611 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko01e726e2020-10-23 09:45:29 +0000612 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
mpagenko8b07c1b2020-11-26 10:36:31 +0000613 // but only in case the techProfile was configured (not deleted)
614 if oFsm.requestEventOffset == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000615 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
mpagenko8b07c1b2020-11-26 10:36:31 +0000616 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000617
mpagenko01e726e2020-10-23 09:45:29 +0000618 if oFsm.chanSet {
619 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000621 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
622 oFsm.chSuccess <- oFsm.procStep
623 oFsm.chanSet = false //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000624 }
mpagenko01e726e2020-10-23 09:45:29 +0000625
626 //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 +0000627}
628
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000630 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
631 oFsm.pUniTechProf.mutexTPState.Lock()
632 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
633 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000635 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
636 "GemIwTp-entity-id": loGemPortID})
637 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
638
639 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000640 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000641 oFsm.pAdaptFsm.commChan, loGemPortID)
642 oFsm.pLastTxMeInstance = meInstance
643}
644
dbainbri4d3a0dc2020-12-02 00:33:42 +0000645func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000646 oFsm.pUniTechProf.mutexTPState.Lock()
647 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
648 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000650 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
651 "GemNCTP-entity-id": loGemPortID})
652 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000654 oFsm.pAdaptFsm.commChan, loGemPortID)
655 oFsm.pLastTxMeInstance = meInstance
656}
657
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
659 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000660 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
661
662 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
663 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
664 meParams := me.ParamData{
665 EntityID: oFsm.tcont0ID,
666 Attributes: me.AttributeValueMap{
667 "AllocId": unusedTcontAllocID,
668 },
669 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000671 oFsm.pAdaptFsm.commChan, meParams)
672 oFsm.pLastTxMeInstance = meInstance
673}
674
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
676 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000677 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
678
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000680 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
681 oFsm.pLastTxMeInstance = meInstance
682}
683
dbainbri4d3a0dc2020-12-02 00:33:42 +0000684func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
685 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000686 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
687
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000689 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
690 oFsm.pLastTxMeInstance = meInstance
691}
692
dbainbri4d3a0dc2020-12-02 00:33:42 +0000693func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
694 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000695 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
696 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko8b07c1b2020-11-26 10:36:31 +0000698 if oFsm.chanSet {
699 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000700 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000701 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
702 oFsm.chSuccess <- oFsm.procStep
703 oFsm.chanSet = false //reset the internal channel state
704 }
705
706 //let's reset the state machine in order to release all resources now
707 pConfigAniStateAFsm := oFsm.pAdaptFsm
708 if pConfigAniStateAFsm != nil {
709 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
710 go func(aPAFsm *AdapterFsm) {
711 if aPAFsm != nil && aPAFsm.pFsm != nil {
712 _ = aPAFsm.pFsm.Event(aniEvReset)
713 }
714 }(pConfigAniStateAFsm)
715 }
716}
717
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
719 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000720 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000721
mpagenko3dbcdd22020-07-22 07:38:45 +0000722 pConfigAniStateAFsm := oFsm.pAdaptFsm
723 if pConfigAniStateAFsm != nil {
724 // abort running message processing
725 fsmAbortMsg := Message{
726 Type: TestMsg,
727 Data: TestMessage{
728 TestMessageVal: AbortMessageProcessing,
729 },
730 }
731 pConfigAniStateAFsm.commChan <- fsmAbortMsg
732
733 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530734 go func(aPAFsm *AdapterFsm) {
735 if aPAFsm != nil && aPAFsm.pFsm != nil {
736 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000737 }
738 }(pConfigAniStateAFsm)
739 }
740}
741
dbainbri4d3a0dc2020-12-02 00:33:42 +0000742func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
743 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000744 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000745 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000746
mpagenko01e726e2020-10-23 09:45:29 +0000747 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000748 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000749}
750
dbainbri4d3a0dc2020-12-02 00:33:42 +0000751func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
752 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000753loop:
754 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000755 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000756 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000757 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530758 message, ok := <-oFsm.pAdaptFsm.commChan
759 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530761 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
762 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
763 break loop
764 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530766
767 switch message.Type {
768 case TestMsg:
769 msg, _ := message.Data.(TestMessage)
770 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000772 break loop
773 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530775 case OMCI:
776 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530778 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530780 "message.Type": message.Type})
781 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000782
Himani Chawla4d908332020-08-31 12:30:20 +0530783 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530785}
786
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530788 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
789 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000790 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000791 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530792 return
793 }
794 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
795 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000797 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530798 return
799 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000801 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
802 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
803 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
804 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
805 // maybe we can use just the same eventName for different state transitions like "forward"
806 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
807 switch oFsm.pLastTxMeInstance.GetName() {
808 case "Ieee8021PMapperServiceProfile":
809 { // let the FSM proceed ...
810 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
811 }
812 case "MacBridgePortConfigurationData":
813 { // let the FSM proceed ...
814 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
815 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300816 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
mpagenkofc4f56e2020-11-04 17:17:49 +0000817 { // let aniConfig Multi-Id processing proceed by stopping the wait function
818 oFsm.omciMIdsResponseReceived <- true
819 }
820 }
821 }
822 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530824 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
825 return
826 }
Himani Chawla4d908332020-08-31 12:30:20 +0530827}
828
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530830 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
831 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000833 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530834 return
835 }
836 msgObj, msgOk := msgLayer.(*omci.SetResponse)
837 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000838 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000839 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530840 return
841 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530843 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000845 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530846 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
847 return
848 }
mpagenko01e726e2020-10-23 09:45:29 +0000849 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
850 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530851 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
852 // if, then something like:
853 //oFsm.pOnuDB.StoreMe(msgObj)
854
mpagenko01e726e2020-10-23 09:45:29 +0000855 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530856 case "TCont":
857 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000858 if oFsm.requestEventOffset == 0 { //from TCont config request
859 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
860 } else { // from T-Cont reset request
861 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
862 }
Himani Chawla4d908332020-08-31 12:30:20 +0530863 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300864 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
Himani Chawla4d908332020-08-31 12:30:20 +0530865 { // let the PrioQueue init proceed by stopping the wait function
866 oFsm.omciMIdsResponseReceived <- true
867 }
868 case "Ieee8021PMapperServiceProfile":
869 { // let the FSM proceed ...
870 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
871 }
872 }
873 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000874}
875
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000877 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
878 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000879 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000880 log.Fields{"device-id": oFsm.deviceID})
881 return
882 }
883 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
884 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000886 log.Fields{"device-id": oFsm.deviceID})
887 return
888 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +0000890 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +0000892 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
893 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
894 // store error for mgmt display?
895 return
896 }
897 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
898 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
899 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
900 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
901
902 switch oFsm.pLastTxMeInstance.GetName() {
903 case "GemInterworkingTerminationPoint":
904 { // let the FSM proceed ...
905 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
906 }
907 case "GemPortNetworkCtp":
908 { // let the FSM proceed ...
909 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
910 }
911 case "Ieee8021PMapperServiceProfile":
912 { // let the FSM proceed ...
913 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
914 }
915 case "MacBridgePortConfigurationData":
916 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
917 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
918 }
919 }
920 }
921}
922
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
924 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000925 "msgType": msg.OmciMsg.MessageType})
926
927 switch msg.OmciMsg.MessageType {
928 case omci.CreateResponseType:
929 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000930 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530931
mpagenko3dbcdd22020-07-22 07:38:45 +0000932 } //CreateResponseType
933 case omci.SetResponseType:
934 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000935 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000936
mpagenko3dbcdd22020-07-22 07:38:45 +0000937 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000938 case omci.DeleteResponseType:
939 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +0000941
942 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000943 default:
944 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000946 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000947 return
948 }
949 }
950}
951
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000953 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
954 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000955 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000956 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
957 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000958 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000959 meParams := me.ParamData{
960 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
961 Attributes: me.AttributeValueMap{
962 "PortId": gemPortAttribs.gemPortID,
963 "TContPointer": oFsm.tcont0ID,
964 "Direction": gemPortAttribs.direction,
965 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
966 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
967 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
968 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
969 },
970 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000971 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000972 oFsm.pAdaptFsm.commChan, meParams)
973 //accept also nil as (error) return value for writing to LastTx
974 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000975 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000976
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000977 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000979 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000981 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +0530982 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000983 return
984 }
985 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +0000986
987 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530989 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000990}
991
dbainbri4d3a0dc2020-12-02 00:33:42 +0000992func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000993 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
994 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000996 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
997 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000998 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000999
ozgecanetsia4b232302020-11-11 10:58:10 +03001000 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1001 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001002
1003 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001004 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001005 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001006 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001007 "InterworkingOption": 0, // Don't Care
1008 "ServiceProfilePointer": 0, // Don't Care
1009 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001010 },
1011 }
1012 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1013 true, oFsm.pAdaptFsm.commChan, meParams)
1014 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001015 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001017 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001018 logger.Errorw(ctx, "GemTP IW multicast create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001019 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1020 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1021 return
1022 }
1023 ipv4MulticastTable := make([]uint8, 12)
1024 //Gem Port ID
1025 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1026 //Secondary Key
1027 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1028 // Multicast IP range start This is the 224.0.0.1 address
1029 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1030 // MulticastIp range stop
1031 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1032
1033 meIPV4MCTableParams := me.ParamData{
1034 EntityID: gemPortAttribs.multicastGemID,
1035 Attributes: me.AttributeValueMap{
1036 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1037 },
1038 }
1039 meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1040 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
1041 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
ozgecanetsia4b232302020-11-11 10:58:10 +03001042
1043 } else {
1044 meParams := me.ParamData{
1045 EntityID: gemPortAttribs.gemPortID,
1046 Attributes: me.AttributeValueMap{
1047 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1048 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1049 "ServiceProfilePointer": oFsm.mapperSP0ID,
1050 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1051 "GalProfilePointer": galEthernetEID,
1052 },
1053 }
1054 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
1055 oFsm.pAdaptFsm.commChan, meParams)
1056 //accept also nil as (error) return value for writing to LastTx
1057 // - this avoids misinterpretation of new received OMCI messages
1058 oFsm.pLastTxMeInstance = meInstance
1059 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001060 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001062 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001063 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001064 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301065 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001066 return
1067 }
1068 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001069
1070 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001071 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301072 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001073}
1074
dbainbri4d3a0dc2020-12-02 00:33:42 +00001075func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001076 const cu16StrictPrioWeight uint16 = 0xFFFF
1077 //find all upstream PrioQueues related to this T-Cont
1078 loQueueMap := ordered_map.NewOrderedMap()
1079 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001080 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001081 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001082 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1083 "prioString": gemPortAttribs.pbitString})
1084 continue
1085 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001086 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301087 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001088 //key does not yet exist
1089 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1090 }
1091 } else {
1092 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1093 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001094 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001095
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001096 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1097 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1098 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1099 // or even be finished without correct SP/WRR setting
1100
1101 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1102 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1103 // even though its T-Cont seems to be wrong ...
1104 loTrafficSchedulerEID := 0x8000
1105 //for all found queues
1106 iter := loQueueMap.IterFunc()
1107 for kv, ok := iter(); ok; kv, ok = iter() {
1108 queueIndex := (kv.Key).(uint16)
1109 meParams := me.ParamData{
1110 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301111 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001112 }
1113 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1114 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001116 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001117 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001118 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1119 } else {
1120 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001122 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1123 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001124 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001125 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1126 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1127 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001128 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001129 oFsm.pAdaptFsm.commChan, meParams)
1130 //accept also nil as (error) return value for writing to LastTx
1131 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001132 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001133
1134 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001135 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001136 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001137 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001138 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301139 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001140 return
1141 }
1142
1143 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1144 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1145 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1146 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1147
1148 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001149
1150 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301152 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001153}
1154
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001156 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301157 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001158 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001159 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001160 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 +00001161 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001162 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001163 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301164 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 logger.Debug(ctx, "uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001166 return nil
1167 }
1168 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 logger.Warnw(ctx, "uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001170 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001171 }
1172}