blob: f908ea0a06d3e1f0729e664a004312c91e6283d2 [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
26 "time"
27
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000028 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000029 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/opencord/omci-lib-go"
31 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/log"
33 //ic "github.com/opencord/voltha-protos/v4/go/inter_container"
34 //"github.com/opencord/voltha-protos/v4/go/openflow_13"
35 //"github.com/opencord/voltha-protos/v4/go/voltha"
mpagenko3dbcdd22020-07-22 07:38:45 +000036)
37
mpagenko1cc3cb42020-07-27 15:24:38 +000038const (
39 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000040 aniEvStart = "aniEvStart"
41 aniEvStartConfig = "aniEvStartConfig"
42 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
43 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
44 aniEvRxTcontsResp = "aniEvRxTcontsResp"
45 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
46 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
47 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
48 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
49 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080050 aniEvWaitFlowRem = "aniEvWaitFlowRem"
51 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000052 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
53 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
54 aniEvRemTcontPath = "aniEvRemTcontPath"
55 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
56 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
57 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
58 aniEvTimeoutSimple = "aniEvTimeoutSimple"
59 aniEvTimeoutMids = "aniEvTimeoutMids"
60 aniEvReset = "aniEvReset"
61 aniEvRestart = "aniEvRestart"
mpagenko1cc3cb42020-07-27 15:24:38 +000062)
63const (
64 // states of config PON ANI port FSM
65 aniStDisabled = "aniStDisabled"
66 aniStStarting = "aniStStarting"
67 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
68 aniStCreatingMBPCD = "aniStCreatingMBPCD"
69 aniStSettingTconts = "aniStSettingTconts"
70 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
71 aniStCreatingGemIWs = "aniStCreatingGemIWs"
72 aniStSettingPQs = "aniStSettingPQs"
73 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
74 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000075 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080076 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000077 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
78 aniStResetTcont = "aniStResetTcont"
79 aniStRemDot1PMapper = "aniStRemDot1PMapper"
80 aniStRemAniBPCD = "aniStRemAniBPCD"
81 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000082 aniStResetting = "aniStResetting"
83)
84
Girish Gowdra041dcb32020-11-16 16:54:30 -080085const (
86 tpIDOffset = 64
87)
88
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000089type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030090 gemPortID uint16
91 upQueueID uint16
92 downQueueID uint16
93 direction uint8
94 qosPolicy string
95 weight uint8
96 pbitString string
97 isMulticast bool
98 multicastGemID uint16
99 staticACL string
100 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000101}
102
Himani Chawla6d2ae152020-09-02 13:11:20 +0530103//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
104type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000105 pDeviceHandler *deviceHandler
106 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530107 pOmciCC *omciCC
108 pOnuUniPort *onuUniPort
109 pUniTechProf *onuUniTechProf
110 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800111 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000112 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000113 requestEvent OnuDeviceEvent
Himani Chawla4d908332020-08-31 12:30:20 +0530114 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000115 pAdaptFsm *AdapterFsm
116 chSuccess chan<- uint8
117 procStep uint8
118 chanSet bool
119 mapperSP0ID uint16
120 macBPCD0ID uint16
121 tcont0ID uint16
122 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000123 gemPortAttribsSlice []ponAniGemPortAttribs
mpagenko01e726e2020-10-23 09:45:29 +0000124 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000125 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenko3dbcdd22020-07-22 07:38:45 +0000126}
127
Himani Chawla6d2ae152020-09-02 13:11:20 +0530128//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 +0000129func newUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800130 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000131 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530132 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000133 pDeviceHandler: apDeviceHandler,
134 deviceID: apDeviceHandler.deviceID,
135 pOmciCC: apDevOmciCC,
136 pOnuUniPort: apUniPort,
137 pUniTechProf: apUniTechProf,
138 pOnuDB: apOnuDB,
139 techProfileID: aTechProfileID,
140 requestEvent: aRequestEvent,
141 chanSet: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000142 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000143 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
144
mpagenko01e726e2020-10-23 09:45:29 +0000145 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000146 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000147 logger.Errorw(ctx, "uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000148 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000149 return nil
150 }
151
152 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000153 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000154 fsm.Events{
155
mpagenko1cc3cb42020-07-27 15:24:38 +0000156 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000157
158 //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 +0000159 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000160 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000161 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
162 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000163 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000164 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000165 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000166 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000167 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000168 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000169 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000170
mpagenko8b07c1b2020-11-26 10:36:31 +0000171 //for removing Gem related resources
172 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800173 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
174 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000175 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
176 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStConfigDone},
177
178 //for removing TCONT related resources
179 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
180 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStRemDot1PMapper},
181 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
182 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
183
184 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
185 aniStRemovingGemIW, aniStRemovingGemNCTP,
186 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000187 {Name: aniEvTimeoutMids, Src: []string{
188 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000189
mpagenko1cc3cb42020-07-27 15:24:38 +0000190 // exceptional treatment for all states except aniStResetting
191 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
192 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
mpagenko8b07c1b2020-11-26 10:36:31 +0000193 aniStConfigDone, aniStRemovingGemIW, aniStRemovingGemNCTP,
194 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000195 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000196 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
mpagenko3dbcdd22020-07-22 07:38:45 +0000197 },
198
199 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000200 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
201 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
202 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
203 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
204 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
205 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
206 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
207 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
208 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
209 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
210 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
211 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
212 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
213 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
214 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
215 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
216 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
217 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000218 },
219 )
220 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000221 logger.Errorw(ctx, "uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000222 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000223 return nil
224 }
225
dbainbri4d3a0dc2020-12-02 00:33:42 +0000226 logger.Debugw(ctx, "uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000227 return instFsm
228}
229
Himani Chawla6d2ae152020-09-02 13:11:20 +0530230//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
231func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000232 oFsm.chSuccess = aChSuccess
233 oFsm.procStep = aProcStep
234 oFsm.chanSet = true
235}
236
dbainbri4d3a0dc2020-12-02 00:33:42 +0000237func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530238 if aPAFsm != nil && aPAFsm.pFsm != nil {
239 //stick to pythonAdapter numbering scheme
240 //index 0 in naming refers to possible usage of multiple instances (later)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800241 oFsm.mapperSP0ID = ieeeMapperServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) + uint16(oFsm.techProfileID)
242 oFsm.macBPCD0ID = macBridgePortAniEID + uint16(oFsm.pOnuUniPort.entityID) + uint16(oFsm.techProfileID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530243
Girish Gowdra041dcb32020-11-16 16:54:30 -0800244 /*
245 // Find a free TCONT Instance ID and use it
246 foundFreeTcontInstID := false
247 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000248 if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.TContClassID); len(tcontInstKeys) > 0 {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800249
250 // FIXME: Ideally the ME configurations on the ONU should constantly be MIB Synced back to the ONU DB
251 // So, as soon as we use up a TCONT Entity on the ONU, the DB at ONU adapter should know that the TCONT
252 // entity is used up via MIB Sync procedure and it will not use it for subsequent TCONT on that ONU.
253 // But, it seems, due to the absence of the constant mib-sync procedure, the TCONT Entities show up as
254 // free even though they are already reserved on the ONU. It seems the mib is synced only once, initially
255 // when the ONU is discovered.
256 /*
257 for _, tcontInstID := range tcontInstKeys {
258 tconInst := oFsm.pOnuDB.GetMe(me.TContClassID, tcontInstID)
259 returnVal := tconInst["AllocId"]
260 if returnVal != nil {
261 if allocID, err := oFsm.pOnuDB.getUint16Attrib(returnVal); err == nil {
262 // If the TCONT Instance ID is set to 0xff or 0xffff, it means it is free to use.
263 if allocID == 0xff || allocID == 0xffff {
264 foundFreeTcontInstID = true
265 oFsm.tcont0ID = uint16(tcontInstID)
266 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
267 "device-id": oFsm.deviceID})
268 break
269 }
270 } else {
271 logger.Errorw("error-converting-alloc-id-to-uint16", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
272 }
273 } else {
274 logger.Errorw("error-extracting-alloc-id-attribute", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
275 }
276 }
277 */
278
279 // Ensure that the techProfileID is in a valid range so that we can allocate a free Tcont for it.
280 if oFsm.techProfileID >= tpIDOffset && oFsm.techProfileID < uint8(tpIDOffset+len(tcontInstKeys)) {
281 // For now, as a dirty workaround, use the tpIDOffset to index the TcontEntityID to be used.
282 // The first TP ID for the ONU will get the first TcontEntityID, the next will get second and so on.
283 // Here the assumption is TP ID will always start from 64 (this is also true to Technology Profile Specification) and the
284 // TP ID will increment in single digit
285 oFsm.tcont0ID = tcontInstKeys[oFsm.techProfileID-tpIDOffset]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000286 logger.Debugw(ctx, "Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800287 "device-id": oFsm.deviceID})
288 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 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 -0800290 if oFsm.chanSet {
291 // indicate processing error/abort to the caller
292 oFsm.chSuccess <- 0
293 oFsm.chanSet = false //reset the internal channel state
294 }
295 //reset the state machine to enable usage on subsequent requests
296 _ = aPAFsm.pFsm.Event(aniEvReset)
297 return
298 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530299 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800301 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530302 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800303 /*
304 if !foundFreeTcontInstID {
305 // This should never happen. If it does, the behavior is unpredictable.
306 logger.Warnw("No free TCONT instances found", log.Fields{"device-id": oFsm.deviceID})
307 }*/
308
309 // Access critical state with lock
310 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000311 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
312 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
Girish Gowdra041dcb32020-11-16 16:54:30 -0800313 oFsm.pUniTechProf.mutexTPState.Unlock()
314
Himani Chawla26e555c2020-08-31 12:30:20 +0530315 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800316 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300317 loGemPortAttribs := ponAniGemPortAttribs{}
318
Himani Chawla26e555c2020-08-31 12:30:20 +0530319 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
320
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530322
323 loGemPortAttribs.gemPortID = gemEntry.gemPortID
324 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
325 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
326 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
327 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
328
329 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
330 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
331 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
332 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
333 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
334 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
335
336 usQueueFound := false
337 dsQueueFound := false
338 for _, mgmtEntityID := range queueInstKeys {
339 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
340 returnVal := meAttributes["RelatedPort"]
341 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530342 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530343 if relatedPort == usQrelPortMask {
344 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000346 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 usQueueFound = true
348 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
349 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000351 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530352 dsQueueFound = true
353 }
354 if usQueueFound && dsQueueFound {
355 break
356 }
357 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000358 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 }
360 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 }
363 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000365 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530366 }
367 }
368 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530370 }
371 loGemPortAttribs.direction = gemEntry.direction
372 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
373 loGemPortAttribs.weight = gemEntry.queueWeight
374 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia4b232302020-11-11 10:58:10 +0300375 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300376 //TODO this might effectively ignore the for loop starting at line 316
377 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300378 loGemPortAttribs.isMulticast = true
379 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
380 loGemPortAttribs.staticACL = gemEntry.staticACL
381 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530382
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300384 "gemPortID": loGemPortAttribs.gemPortID,
385 "isMulticast": loGemPortAttribs.isMulticast,
386 "multicastGemID": loGemPortAttribs.multicastGemID,
387 "staticACL": loGemPortAttribs.staticACL,
388 "dynamicACL": loGemPortAttribs.dynamicACL,
389 })
390
391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000392 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300393 "gemPortID": loGemPortAttribs.gemPortID,
394 "upQueueID": loGemPortAttribs.upQueueID,
395 "downQueueID": loGemPortAttribs.downQueueID,
396 "pbitString": loGemPortAttribs.pbitString,
397 "prioQueueIndex": gemEntry.prioQueueIndex,
398 })
399 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530400
401 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
402 }
403 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
404 }
405}
406
dbainbri4d3a0dc2020-12-02 00:33:42 +0000407func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
408 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000409 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000410 // in case the used channel is not yet defined (can be re-used after restarts)
411 if oFsm.omciMIdsResponseReceived == nil {
412 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000413 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000414 } else {
415 // as we may 're-use' this instance of FSM and the connected channel
416 // make sure there is no 'lingering' request in the already existing channel:
417 // (simple loop sufficient as we are the only receiver)
418 for len(oFsm.omciMIdsResponseReceived) > 0 {
419 <-oFsm.omciMIdsResponseReceived
420 }
421 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000422 //ensure internal slices are empty (which might be set from previous run) - release memory
423 oFsm.gemPortAttribsSlice = nil
424
mpagenko3dbcdd22020-07-22 07:38:45 +0000425 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000426 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000427
428 //let the state machine run forward from here directly
429 pConfigAniStateAFsm := oFsm.pAdaptFsm
430 if pConfigAniStateAFsm != nil {
431 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000432 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000433
mpagenko3dbcdd22020-07-22 07:38:45 +0000434 }
435}
436
dbainbri4d3a0dc2020-12-02 00:33:42 +0000437func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
438 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000439 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000440 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
441 oFsm.requestEventOffset = 0 //0 offset for last config request activity
dbainbri4d3a0dc2020-12-02 00:33:42 +0000442 meInstance := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000443 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
444 //accept also nil as (error) return value for writing to LastTx
445 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000446 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000447}
448
dbainbri4d3a0dc2020-12-02 00:33:42 +0000449func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
450 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000451 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
452 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000453 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000454 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
455 meParams := me.ParamData{
456 EntityID: oFsm.macBPCD0ID,
457 Attributes: me.AttributeValueMap{
458 "BridgeIdPointer": bridgePtr,
459 "PortNum": 0xFF, //fixed unique ANI side indication
460 "TpType": 3, //for .1PMapper
461 "TpPointer": oFsm.mapperSP0ID,
462 },
463 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000464 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000465 oFsm.pAdaptFsm.commChan, meParams)
466 //accept also nil as (error) return value for writing to LastTx
467 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000468 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000469}
470
dbainbri4d3a0dc2020-12-02 00:33:42 +0000471func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
472 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000473 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
474 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000475 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000476 meParams := me.ParamData{
477 EntityID: oFsm.tcont0ID,
478 Attributes: me.AttributeValueMap{
479 "AllocId": oFsm.alloc0ID,
480 },
481 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000483 oFsm.pAdaptFsm.commChan, meParams)
484 //accept also nil as (error) return value for writing to LastTx
485 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000486 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000487}
488
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
490 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000491 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000493}
494
dbainbri4d3a0dc2020-12-02 00:33:42 +0000495func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
496 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000497 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000498 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000499}
500
dbainbri4d3a0dc2020-12-02 00:33:42 +0000501func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
502 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000503 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000504 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000505}
506
dbainbri4d3a0dc2020-12-02 00:33:42 +0000507func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300508
dbainbri4d3a0dc2020-12-02 00:33:42 +0000509 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000510 "toGemIw": 1024, /* cmp above */
511 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000512
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000514 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000515 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000516
mpagenko3dbcdd22020-07-22 07:38:45 +0000517 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000518 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530519 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000520 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000521
522 //assign the GemPorts according to the configured Prio
523 var loPrioGemPortArray [8]uint16
524 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300525 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300527 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
528 "prioString": gemPortAttribs.pbitString})
529 continue
530 }
531 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000532 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300533 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
534 "prioString": gemPortAttribs.pbitString})
535 continue
536 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000537 for i := 0; i < 8; i++ {
538 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
539 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
540 if prio == 1 { // Check this p-bit is set
541 if loPrioGemPortArray[i] == 0 {
542 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
543 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000544 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000545 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000546 "SetGemPort": loPrioGemPortArray[i]})
547 }
548 }
549 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000550 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000551 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000552 "prioString": gemPortAttribs.pbitString, "position": i})
553 }
554
555 }
556 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300557
ozgecanetsia4b232302020-11-11 10:58:10 +0300558 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530559 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300560 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530561 if value != 0 {
562 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530563 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000565 "for Prio": index,
566 "IwPtr": strconv.FormatInt(int64(value), 16),
567 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300568 } else {
569 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000570 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
571 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300572 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530573 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000574 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300575 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000576 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
577 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300578 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530579
580 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000582 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300583 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
584 // 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 +0000585 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300586 //pConfigAniStateAFsm := oFsm.pAdaptFsm
587 //if pConfigAniStateAFsm != nil {
588 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
589 // go func(aPAFsm *AdapterFsm) {
590 // if aPAFsm != nil && aPAFsm.pFsm != nil {
591 // _ = aPAFsm.pFsm.Event(aniEvReset)
592 // }
593 // }(pConfigAniStateAFsm)
594 //}
595 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000596 pConfigAniStateAFsm := oFsm.pAdaptFsm
597 if pConfigAniStateAFsm != nil {
598 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530599 go func(aPAFsm *AdapterFsm) {
600 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300601 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000602 }
603 }(pConfigAniStateAFsm)
604 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300605 } else {
606 meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
607 oFsm.pAdaptFsm.commChan, meParams)
608 //accept also nil as (error) return value for writing to LastTx
609 // - this avoids misinterpretation of new received OMCI messages
610 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000611 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000612}
613
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
615 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000616 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000617 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko01e726e2020-10-23 09:45:29 +0000619 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800620 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko01e726e2020-10-23 09:45:29 +0000621 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
mpagenko8b07c1b2020-11-26 10:36:31 +0000622 // but only in case the techProfile was configured (not deleted)
623 if oFsm.requestEventOffset == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000624 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
mpagenko8b07c1b2020-11-26 10:36:31 +0000625 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000626
mpagenko01e726e2020-10-23 09:45:29 +0000627 if oFsm.chanSet {
628 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000630 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
631 oFsm.chSuccess <- oFsm.procStep
632 oFsm.chanSet = false //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000633 }
mpagenko01e726e2020-10-23 09:45:29 +0000634
635 //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 +0000636}
637
dbainbri4d3a0dc2020-12-02 00:33:42 +0000638func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -0800639
640 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending() {
641 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
642 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
643 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
644 pConfigAniStateAFsm := oFsm.pAdaptFsm
645 if pConfigAniStateAFsm != nil {
646 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
647 go func(aPAFsm *AdapterFsm) {
648 if aPAFsm != nil && aPAFsm.pFsm != nil {
649 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvWaitFlowRem)
650 }
651 }(pConfigAniStateAFsm)
652 } else {
653 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
654 }
655 return
656 }
657
mpagenko8b07c1b2020-11-26 10:36:31 +0000658 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
659 oFsm.pUniTechProf.mutexTPState.Lock()
660 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
661 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000663 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
664 "GemIwTp-entity-id": loGemPortID})
665 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
666
667 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000669 oFsm.pAdaptFsm.commChan, loGemPortID)
670 oFsm.pLastTxMeInstance = meInstance
671}
672
dbainbri4d3a0dc2020-12-02 00:33:42 +0000673func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000674 oFsm.pUniTechProf.mutexTPState.Lock()
675 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
676 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000678 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
679 "GemNCTP-entity-id": loGemPortID})
680 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000682 oFsm.pAdaptFsm.commChan, loGemPortID)
683 oFsm.pLastTxMeInstance = meInstance
684}
685
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
687 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000688 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
689
690 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
691 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
692 meParams := me.ParamData{
693 EntityID: oFsm.tcont0ID,
694 Attributes: me.AttributeValueMap{
695 "AllocId": unusedTcontAllocID,
696 },
697 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 meInstance := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000699 oFsm.pAdaptFsm.commChan, meParams)
700 oFsm.pLastTxMeInstance = meInstance
701}
702
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
704 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000705 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
706
dbainbri4d3a0dc2020-12-02 00:33:42 +0000707 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000708 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
709 oFsm.pLastTxMeInstance = meInstance
710}
711
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
713 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000714 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
715
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000717 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
718 oFsm.pLastTxMeInstance = meInstance
719}
720
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
722 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000723 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
724 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000725 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko8b07c1b2020-11-26 10:36:31 +0000726 if oFsm.chanSet {
727 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000729 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
730 oFsm.chSuccess <- oFsm.procStep
731 oFsm.chanSet = false //reset the internal channel state
732 }
733
734 //let's reset the state machine in order to release all resources now
735 pConfigAniStateAFsm := oFsm.pAdaptFsm
736 if pConfigAniStateAFsm != nil {
737 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
738 go func(aPAFsm *AdapterFsm) {
739 if aPAFsm != nil && aPAFsm.pFsm != nil {
740 _ = aPAFsm.pFsm.Event(aniEvReset)
741 }
742 }(pConfigAniStateAFsm)
743 }
744}
745
dbainbri4d3a0dc2020-12-02 00:33:42 +0000746func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
747 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000748 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000749
mpagenko3dbcdd22020-07-22 07:38:45 +0000750 pConfigAniStateAFsm := oFsm.pAdaptFsm
751 if pConfigAniStateAFsm != nil {
752 // abort running message processing
753 fsmAbortMsg := Message{
754 Type: TestMsg,
755 Data: TestMessage{
756 TestMessageVal: AbortMessageProcessing,
757 },
758 }
759 pConfigAniStateAFsm.commChan <- fsmAbortMsg
760
761 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530762 go func(aPAFsm *AdapterFsm) {
763 if aPAFsm != nil && aPAFsm.pFsm != nil {
764 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000765 }
766 }(pConfigAniStateAFsm)
767 }
768}
769
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
771 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000772 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000773 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000774
mpagenko01e726e2020-10-23 09:45:29 +0000775 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000777}
778
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
780 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000781loop:
782 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000783 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000784 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000785 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530786 message, ok := <-oFsm.pAdaptFsm.commChan
787 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530789 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
790 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
791 break loop
792 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530794
795 switch message.Type {
796 case TestMsg:
797 msg, _ := message.Data.(TestMessage)
798 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000800 break loop
801 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530803 case OMCI:
804 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530806 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530808 "message.Type": message.Type})
809 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000810
Himani Chawla4d908332020-08-31 12:30:20 +0530811 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530813}
814
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530816 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
817 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000819 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530820 return
821 }
822 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
823 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000825 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530826 return
827 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000828 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000829 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
830 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
831 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
832 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
833 // maybe we can use just the same eventName for different state transitions like "forward"
834 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
835 switch oFsm.pLastTxMeInstance.GetName() {
836 case "Ieee8021PMapperServiceProfile":
837 { // let the FSM proceed ...
838 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
839 }
840 case "MacBridgePortConfigurationData":
841 { // let the FSM proceed ...
842 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
843 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300844 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
mpagenkofc4f56e2020-11-04 17:17:49 +0000845 { // let aniConfig Multi-Id processing proceed by stopping the wait function
846 oFsm.omciMIdsResponseReceived <- true
847 }
848 }
849 }
850 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530852 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
853 return
854 }
Himani Chawla4d908332020-08-31 12:30:20 +0530855}
856
dbainbri4d3a0dc2020-12-02 00:33:42 +0000857func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530858 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
859 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000861 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530862 return
863 }
864 msgObj, msgOk := msgLayer.(*omci.SetResponse)
865 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000867 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530868 return
869 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530871 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000873 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530874 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
875 return
876 }
mpagenko01e726e2020-10-23 09:45:29 +0000877 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
878 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530879 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
880 // if, then something like:
881 //oFsm.pOnuDB.StoreMe(msgObj)
882
mpagenko01e726e2020-10-23 09:45:29 +0000883 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530884 case "TCont":
885 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000886 if oFsm.requestEventOffset == 0 { //from TCont config request
887 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
888 } else { // from T-Cont reset request
889 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
890 }
Himani Chawla4d908332020-08-31 12:30:20 +0530891 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300892 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
Himani Chawla4d908332020-08-31 12:30:20 +0530893 { // let the PrioQueue init proceed by stopping the wait function
894 oFsm.omciMIdsResponseReceived <- true
895 }
896 case "Ieee8021PMapperServiceProfile":
897 { // let the FSM proceed ...
898 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
899 }
900 }
901 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000902}
903
dbainbri4d3a0dc2020-12-02 00:33:42 +0000904func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000905 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
906 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000907 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000908 log.Fields{"device-id": oFsm.deviceID})
909 return
910 }
911 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
912 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000913 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +0000914 log.Fields{"device-id": oFsm.deviceID})
915 return
916 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000917 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +0000918 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000919 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +0000920 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
921 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
922 // store error for mgmt display?
923 return
924 }
925 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
926 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
927 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
928 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
929
930 switch oFsm.pLastTxMeInstance.GetName() {
931 case "GemInterworkingTerminationPoint":
932 { // let the FSM proceed ...
933 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
934 }
935 case "GemPortNetworkCtp":
936 { // let the FSM proceed ...
937 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
938 }
939 case "Ieee8021PMapperServiceProfile":
940 { // let the FSM proceed ...
941 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
942 }
943 case "MacBridgePortConfigurationData":
944 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
945 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
946 }
947 }
948 }
949}
950
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
952 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000953 "msgType": msg.OmciMsg.MessageType})
954
955 switch msg.OmciMsg.MessageType {
956 case omci.CreateResponseType:
957 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000958 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +0530959
mpagenko3dbcdd22020-07-22 07:38:45 +0000960 } //CreateResponseType
961 case omci.SetResponseType:
962 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000964
mpagenko3dbcdd22020-07-22 07:38:45 +0000965 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000966 case omci.DeleteResponseType:
967 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000968 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +0000969
970 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000971 default:
972 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000973 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000974 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000975 return
976 }
977 }
978}
979
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000981 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
982 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000983 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000984 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
985 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000986 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000987 meParams := me.ParamData{
988 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
989 Attributes: me.AttributeValueMap{
990 "PortId": gemPortAttribs.gemPortID,
991 "TContPointer": oFsm.tcont0ID,
992 "Direction": gemPortAttribs.direction,
993 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
994 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
995 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
996 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
997 },
998 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001000 oFsm.pAdaptFsm.commChan, meParams)
1001 //accept also nil as (error) return value for writing to LastTx
1002 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001003 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +00001004
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001005 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001007 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001009 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301010 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001011 return
1012 }
1013 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001014
1015 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301017 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001018}
1019
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001021 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1022 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001023 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001024 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1025 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001026 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001027
ozgecanetsia4b232302020-11-11 10:58:10 +03001028 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1029 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001030
1031 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001032 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001033 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001034 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001035 "InterworkingOption": 0, // Don't Care
1036 "ServiceProfilePointer": 0, // Don't Care
1037 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001038 },
1039 }
1040 meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1041 true, oFsm.pAdaptFsm.commChan, meParams)
1042 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001043 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001045 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046 logger.Errorw(ctx, "GemTP IW multicast create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001047 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1048 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1049 return
1050 }
1051 ipv4MulticastTable := make([]uint8, 12)
1052 //Gem Port ID
1053 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1054 //Secondary Key
1055 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1056 // Multicast IP range start This is the 224.0.0.1 address
1057 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1058 // MulticastIp range stop
1059 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1060
1061 meIPV4MCTableParams := me.ParamData{
1062 EntityID: gemPortAttribs.multicastGemID,
1063 Attributes: me.AttributeValueMap{
1064 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1065 },
1066 }
1067 meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
1068 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
1069 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
ozgecanetsia4b232302020-11-11 10:58:10 +03001070
1071 } else {
1072 meParams := me.ParamData{
1073 EntityID: gemPortAttribs.gemPortID,
1074 Attributes: me.AttributeValueMap{
1075 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1076 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1077 "ServiceProfilePointer": oFsm.mapperSP0ID,
1078 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1079 "GalProfilePointer": galEthernetEID,
1080 },
1081 }
1082 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
1083 oFsm.pAdaptFsm.commChan, meParams)
1084 //accept also nil as (error) return value for writing to LastTx
1085 // - this avoids misinterpretation of new received OMCI messages
1086 oFsm.pLastTxMeInstance = meInstance
1087 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001088 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001090 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001092 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301093 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001094 return
1095 }
1096 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001097
1098 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301100 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001101}
1102
dbainbri4d3a0dc2020-12-02 00:33:42 +00001103func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001104 const cu16StrictPrioWeight uint16 = 0xFFFF
1105 //find all upstream PrioQueues related to this T-Cont
1106 loQueueMap := ordered_map.NewOrderedMap()
1107 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001108 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001110 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1111 "prioString": gemPortAttribs.pbitString})
1112 continue
1113 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001114 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301115 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001116 //key does not yet exist
1117 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1118 }
1119 } else {
1120 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1121 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001122 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001123
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001124 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1125 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1126 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1127 // or even be finished without correct SP/WRR setting
1128
1129 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1130 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1131 // even though its T-Cont seems to be wrong ...
1132 loTrafficSchedulerEID := 0x8000
1133 //for all found queues
1134 iter := loQueueMap.IterFunc()
1135 for kv, ok := iter(); ok; kv, ok = iter() {
1136 queueIndex := (kv.Key).(uint16)
1137 meParams := me.ParamData{
1138 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301139 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001140 }
1141 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1142 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001143 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001144 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001145 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001146 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1147 } else {
1148 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001150 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1151 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001152 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001153 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1154 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1155 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001157 oFsm.pAdaptFsm.commChan, meParams)
1158 //accept also nil as (error) return value for writing to LastTx
1159 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001160 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001161
1162 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001163 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001164 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001166 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301167 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001168 return
1169 }
1170
1171 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1172 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1173 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1174 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1175
1176 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001177
1178 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001179 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301180 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001181}
1182
dbainbri4d3a0dc2020-12-02 00:33:42 +00001183func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001184 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301185 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001186 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001187 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001188 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 +00001189 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001190 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001191 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301192 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193 logger.Debug(ctx, "uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001194 return nil
1195 }
1196 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001197 logger.Warnw(ctx, "uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001198 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001199 }
1200}