blob: 0f44d8460891c1c1d893e1971cd1a147ed73355f [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"
Himani Chawla4d908332020-08-31 12:30:20 +053022 "fmt"
mpagenko3dbcdd22020-07-22 07:38:45 +000023 "strconv"
24 "time"
25
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000026 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000027 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000028 "github.com/opencord/omci-lib-go"
29 me "github.com/opencord/omci-lib-go/generated"
30 "github.com/opencord/voltha-lib-go/v3/pkg/log"
31 //ic "github.com/opencord/voltha-protos/v3/go/inter_container"
32 //"github.com/opencord/voltha-protos/v3/go/openflow_13"
33 //"github.com/opencord/voltha-protos/v3/go/voltha"
34)
35
mpagenko1cc3cb42020-07-27 15:24:38 +000036const (
37 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000038 aniEvStart = "aniEvStart"
39 aniEvStartConfig = "aniEvStartConfig"
40 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
41 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
42 aniEvRxTcontsResp = "aniEvRxTcontsResp"
43 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
44 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
45 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
46 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
47 aniEvRemGemiw = "aniEvRemGemiw"
48 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
49 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
50 aniEvRemTcontPath = "aniEvRemTcontPath"
51 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
52 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
53 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
54 aniEvTimeoutSimple = "aniEvTimeoutSimple"
55 aniEvTimeoutMids = "aniEvTimeoutMids"
56 aniEvReset = "aniEvReset"
57 aniEvRestart = "aniEvRestart"
mpagenko1cc3cb42020-07-27 15:24:38 +000058)
59const (
60 // states of config PON ANI port FSM
61 aniStDisabled = "aniStDisabled"
62 aniStStarting = "aniStStarting"
63 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
64 aniStCreatingMBPCD = "aniStCreatingMBPCD"
65 aniStSettingTconts = "aniStSettingTconts"
66 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
67 aniStCreatingGemIWs = "aniStCreatingGemIWs"
68 aniStSettingPQs = "aniStSettingPQs"
69 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
70 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000071 aniStRemovingGemIW = "aniStRemovingGemIW"
72 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
73 aniStResetTcont = "aniStResetTcont"
74 aniStRemDot1PMapper = "aniStRemDot1PMapper"
75 aniStRemAniBPCD = "aniStRemAniBPCD"
76 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000077 aniStResetting = "aniStResetting"
78)
79
Girish Gowdra041dcb32020-11-16 16:54:30 -080080const (
81 tpIDOffset = 64
82)
83
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000084type ponAniGemPortAttribs struct {
85 gemPortID uint16
86 upQueueID uint16
87 downQueueID uint16
88 direction uint8
89 qosPolicy string
90 weight uint8
91 pbitString string
92}
93
Himani Chawla6d2ae152020-09-02 13:11:20 +053094//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
95type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +000096 pDeviceHandler *deviceHandler
97 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +053098 pOmciCC *omciCC
99 pOnuUniPort *onuUniPort
100 pUniTechProf *onuUniTechProf
101 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800102 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000103 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000104 requestEvent OnuDeviceEvent
Himani Chawla4d908332020-08-31 12:30:20 +0530105 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000106 pAdaptFsm *AdapterFsm
107 chSuccess chan<- uint8
108 procStep uint8
109 chanSet bool
110 mapperSP0ID uint16
111 macBPCD0ID uint16
112 tcont0ID uint16
113 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000114 gemPortAttribsSlice []ponAniGemPortAttribs
mpagenko01e726e2020-10-23 09:45:29 +0000115 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000116 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenko3dbcdd22020-07-22 07:38:45 +0000117}
118
Himani Chawla6d2ae152020-09-02 13:11:20 +0530119//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
120func newUniPonAniConfigFsm(apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800121 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000122 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530123 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000124 pDeviceHandler: apDeviceHandler,
125 deviceID: apDeviceHandler.deviceID,
126 pOmciCC: apDevOmciCC,
127 pOnuUniPort: apUniPort,
128 pUniTechProf: apUniTechProf,
129 pOnuDB: apOnuDB,
130 techProfileID: aTechProfileID,
131 requestEvent: aRequestEvent,
132 chanSet: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000133 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000134 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
135
mpagenko01e726e2020-10-23 09:45:29 +0000136 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000137 if instFsm.pAdaptFsm == nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530138 logger.Errorw("uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000139 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000140 return nil
141 }
142
143 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000144 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000145 fsm.Events{
146
mpagenko1cc3cb42020-07-27 15:24:38 +0000147 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000148
149 //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 +0000150 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000151 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000152 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
153 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000154 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000155 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000156 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000157 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000158 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000159 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000160 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000161
mpagenko8b07c1b2020-11-26 10:36:31 +0000162 //for removing Gem related resources
163 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
164 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
165 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStConfigDone},
166
167 //for removing TCONT related resources
168 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
169 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStRemDot1PMapper},
170 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
171 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
172
173 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
174 aniStRemovingGemIW, aniStRemovingGemNCTP,
175 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000176 {Name: aniEvTimeoutMids, Src: []string{
177 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000178
mpagenko1cc3cb42020-07-27 15:24:38 +0000179 // exceptional treatment for all states except aniStResetting
180 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
181 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
mpagenko8b07c1b2020-11-26 10:36:31 +0000182 aniStConfigDone, aniStRemovingGemIW, aniStRemovingGemNCTP,
183 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000184 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000185 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
mpagenko3dbcdd22020-07-22 07:38:45 +0000186 },
187
188 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000189 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
190 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(e) },
191 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(e) },
192 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(e) },
193 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(e) },
194 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(e) },
195 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(e) },
196 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(e) },
197 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(e) },
198 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(e) },
mpagenko8b07c1b2020-11-26 10:36:31 +0000199 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(e) },
200 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(e) },
201 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(e) },
202 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(e) },
203 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(e) },
204 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(e) },
mpagenko1cc3cb42020-07-27 15:24:38 +0000205 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(e) },
206 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000207 },
208 )
209 if instFsm.pAdaptFsm.pFsm == nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530210 logger.Errorw("uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000211 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000212 return nil
213 }
214
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000215 logger.Debugw("uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000216 return instFsm
217}
218
Himani Chawla6d2ae152020-09-02 13:11:20 +0530219//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
220func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000221 oFsm.chSuccess = aChSuccess
222 oFsm.procStep = aProcStep
223 oFsm.chanSet = true
224}
225
Himani Chawla6d2ae152020-09-02 13:11:20 +0530226func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530227 if aPAFsm != nil && aPAFsm.pFsm != nil {
228 //stick to pythonAdapter numbering scheme
229 //index 0 in naming refers to possible usage of multiple instances (later)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800230 oFsm.mapperSP0ID = ieeeMapperServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) + uint16(oFsm.techProfileID)
231 oFsm.macBPCD0ID = macBridgePortAniEID + uint16(oFsm.pOnuUniPort.entityID) + uint16(oFsm.techProfileID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530232
Girish Gowdra041dcb32020-11-16 16:54:30 -0800233 /*
234 // Find a free TCONT Instance ID and use it
235 foundFreeTcontInstID := false
236 */
Himani Chawla6d2ae152020-09-02 13:11:20 +0530237 if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.TContClassID); len(tcontInstKeys) > 0 {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800238
239 // FIXME: Ideally the ME configurations on the ONU should constantly be MIB Synced back to the ONU DB
240 // So, as soon as we use up a TCONT Entity on the ONU, the DB at ONU adapter should know that the TCONT
241 // entity is used up via MIB Sync procedure and it will not use it for subsequent TCONT on that ONU.
242 // But, it seems, due to the absence of the constant mib-sync procedure, the TCONT Entities show up as
243 // free even though they are already reserved on the ONU. It seems the mib is synced only once, initially
244 // when the ONU is discovered.
245 /*
246 for _, tcontInstID := range tcontInstKeys {
247 tconInst := oFsm.pOnuDB.GetMe(me.TContClassID, tcontInstID)
248 returnVal := tconInst["AllocId"]
249 if returnVal != nil {
250 if allocID, err := oFsm.pOnuDB.getUint16Attrib(returnVal); err == nil {
251 // If the TCONT Instance ID is set to 0xff or 0xffff, it means it is free to use.
252 if allocID == 0xff || allocID == 0xffff {
253 foundFreeTcontInstID = true
254 oFsm.tcont0ID = uint16(tcontInstID)
255 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
256 "device-id": oFsm.deviceID})
257 break
258 }
259 } else {
260 logger.Errorw("error-converting-alloc-id-to-uint16", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
261 }
262 } else {
263 logger.Errorw("error-extracting-alloc-id-attribute", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
264 }
265 }
266 */
267
268 // Ensure that the techProfileID is in a valid range so that we can allocate a free Tcont for it.
269 if oFsm.techProfileID >= tpIDOffset && oFsm.techProfileID < uint8(tpIDOffset+len(tcontInstKeys)) {
270 // For now, as a dirty workaround, use the tpIDOffset to index the TcontEntityID to be used.
271 // The first TP ID for the ONU will get the first TcontEntityID, the next will get second and so on.
272 // Here the assumption is TP ID will always start from 64 (this is also true to Technology Profile Specification) and the
273 // TP ID will increment in single digit
274 oFsm.tcont0ID = tcontInstKeys[oFsm.techProfileID-tpIDOffset]
275 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
276 "device-id": oFsm.deviceID})
277 } else {
278 logger.Errorw("tech profile id not in valid range", log.Fields{"device-id": oFsm.deviceID, "tp-id": oFsm.techProfileID, "num-tcont": len(tcontInstKeys)})
279 if oFsm.chanSet {
280 // indicate processing error/abort to the caller
281 oFsm.chSuccess <- 0
282 oFsm.chanSet = false //reset the internal channel state
283 }
284 //reset the state machine to enable usage on subsequent requests
285 _ = aPAFsm.pFsm.Event(aniEvReset)
286 return
287 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530288 } else {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800289 logger.Errorw("No TCont instances found", log.Fields{"device-id": oFsm.deviceID})
290 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530291 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800292 /*
293 if !foundFreeTcontInstID {
294 // This should never happen. If it does, the behavior is unpredictable.
295 logger.Warnw("No free TCONT instances found", log.Fields{"device-id": oFsm.deviceID})
296 }*/
297
298 // Access critical state with lock
299 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000300 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
301 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
Girish Gowdra041dcb32020-11-16 16:54:30 -0800302 oFsm.pUniTechProf.mutexTPState.Unlock()
303
Himani Chawla26e555c2020-08-31 12:30:20 +0530304 loGemPortAttribs := ponAniGemPortAttribs{}
305 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800306
307 for _, gemEntry := range mapGemPortParams {
Himani Chawla26e555c2020-08-31 12:30:20 +0530308 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
309
Himani Chawla6d2ae152020-09-02 13:11:20 +0530310 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530311
312 loGemPortAttribs.gemPortID = gemEntry.gemPortID
313 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
314 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
315 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
316 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
317
318 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
319 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
320 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
321 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
322 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
323 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
324
325 usQueueFound := false
326 dsQueueFound := false
327 for _, mgmtEntityID := range queueInstKeys {
328 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
329 returnVal := meAttributes["RelatedPort"]
330 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530331 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530332 if relatedPort == usQrelPortMask {
333 loGemPortAttribs.upQueueID = mgmtEntityID
334 logger.Debugw("UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000335 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530336 usQueueFound = true
337 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
338 loGemPortAttribs.downQueueID = mgmtEntityID
339 logger.Debugw("DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000340 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530341 dsQueueFound = true
342 }
343 if usQueueFound && dsQueueFound {
344 break
345 }
346 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000347 logger.Warnw("Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 }
349 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000350 logger.Warnw("'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 }
352 } else {
353 logger.Warnw("No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000354 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 }
356 }
357 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000358 logger.Warnw("No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 }
360 loGemPortAttribs.direction = gemEntry.direction
361 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
362 loGemPortAttribs.weight = gemEntry.queueWeight
363 loGemPortAttribs.pbitString = gemEntry.pbitString
364
365 logger.Debugw("prio-related GemPort attributes:", log.Fields{
366 "gemPortID": loGemPortAttribs.gemPortID,
367 "upQueueID": loGemPortAttribs.upQueueID,
368 "downQueueID": loGemPortAttribs.downQueueID,
369 "pbitString": loGemPortAttribs.pbitString,
370 "prioQueueIndex": gemEntry.prioQueueIndex,
371 })
372
373 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
374 }
375 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
376 }
377}
378
Himani Chawla6d2ae152020-09-02 13:11:20 +0530379func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000380 logger.Debugw("UniPonAniConfigFsm start", log.Fields{
381 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000382 // in case the used channel is not yet defined (can be re-used after restarts)
383 if oFsm.omciMIdsResponseReceived == nil {
384 oFsm.omciMIdsResponseReceived = make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530385 logger.Debug("uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000386 } else {
387 // as we may 're-use' this instance of FSM and the connected channel
388 // make sure there is no 'lingering' request in the already existing channel:
389 // (simple loop sufficient as we are the only receiver)
390 for len(oFsm.omciMIdsResponseReceived) > 0 {
391 <-oFsm.omciMIdsResponseReceived
392 }
393 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000394 //ensure internal slices are empty (which might be set from previous run) - release memory
395 oFsm.gemPortAttribsSlice = nil
396
mpagenko3dbcdd22020-07-22 07:38:45 +0000397 // start go routine for processing of LockState messages
mpagenkodff5dda2020-08-28 11:52:01 +0000398 go oFsm.processOmciAniMessages()
mpagenko3dbcdd22020-07-22 07:38:45 +0000399
400 //let the state machine run forward from here directly
401 pConfigAniStateAFsm := oFsm.pAdaptFsm
402 if pConfigAniStateAFsm != nil {
403 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 go oFsm.prepareAndEnterConfigState(pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000405
mpagenko3dbcdd22020-07-22 07:38:45 +0000406 }
407}
408
Himani Chawla6d2ae152020-09-02 13:11:20 +0530409func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(e *fsm.Event) {
410 logger.Debugw("uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000411 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000412 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
413 oFsm.requestEventOffset = 0 //0 offset for last config request activity
mpagenko3dbcdd22020-07-22 07:38:45 +0000414 meInstance := oFsm.pOmciCC.sendCreateDot1PMapper(context.TODO(), ConstDefaultOmciTimeout, true,
415 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
416 //accept also nil as (error) return value for writing to LastTx
417 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000418 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000419}
420
Himani Chawla6d2ae152020-09-02 13:11:20 +0530421func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(e *fsm.Event) {
422 logger.Debugw("uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000423 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
424 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000425 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000426 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
427 meParams := me.ParamData{
428 EntityID: oFsm.macBPCD0ID,
429 Attributes: me.AttributeValueMap{
430 "BridgeIdPointer": bridgePtr,
431 "PortNum": 0xFF, //fixed unique ANI side indication
432 "TpType": 3, //for .1PMapper
433 "TpPointer": oFsm.mapperSP0ID,
434 },
435 }
436 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
437 oFsm.pAdaptFsm.commChan, meParams)
438 //accept also nil as (error) return value for writing to LastTx
439 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000440 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000441}
442
Himani Chawla6d2ae152020-09-02 13:11:20 +0530443func (oFsm *uniPonAniConfigFsm) enterSettingTconts(e *fsm.Event) {
444 logger.Debugw("uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000445 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
446 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000447 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000448 meParams := me.ParamData{
449 EntityID: oFsm.tcont0ID,
450 Attributes: me.AttributeValueMap{
451 "AllocId": oFsm.alloc0ID,
452 },
453 }
454 meInstance := oFsm.pOmciCC.sendSetTcontVar(context.TODO(), ConstDefaultOmciTimeout, true,
455 oFsm.pAdaptFsm.commChan, meParams)
456 //accept also nil as (error) return value for writing to LastTx
457 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000458 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000459}
460
Himani Chawla6d2ae152020-09-02 13:11:20 +0530461func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(e *fsm.Event) {
462 logger.Debugw("uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000463 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000464 go oFsm.performCreatingGemNCTPs()
465}
466
Himani Chawla6d2ae152020-09-02 13:11:20 +0530467func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(e *fsm.Event) {
468 logger.Debugw("uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000469 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000470 go oFsm.performCreatingGemIWs()
471}
472
Himani Chawla6d2ae152020-09-02 13:11:20 +0530473func (oFsm *uniPonAniConfigFsm) enterSettingPQs(e *fsm.Event) {
474 logger.Debugw("uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000475 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000476 go oFsm.performSettingPQs()
477}
478
Himani Chawla6d2ae152020-09-02 13:11:20 +0530479func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(e *fsm.Event) {
480 logger.Debugw("uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000481 "toGemIw": 1024, /* cmp above */
482 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000483
Himani Chawla6d2ae152020-09-02 13:11:20 +0530484 logger.Debugw("uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000485 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000486 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000487
mpagenko3dbcdd22020-07-22 07:38:45 +0000488 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000489 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530490 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000491 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000492
493 //assign the GemPorts according to the configured Prio
494 var loPrioGemPortArray [8]uint16
495 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
496 for i := 0; i < 8; i++ {
497 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
498 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
499 if prio == 1 { // Check this p-bit is set
500 if loPrioGemPortArray[i] == 0 {
501 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
502 } else {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530503 logger.Warnw("uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000504 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000505 "SetGemPort": loPrioGemPortArray[i]})
506 }
507 }
508 } else {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530509 logger.Warnw("uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000510 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000511 "prioString": gemPortAttribs.pbitString, "position": i})
512 }
513
514 }
515 }
516 var foundIwPtr bool = false
Himani Chawla4d908332020-08-31 12:30:20 +0530517 for index, value := range loPrioGemPortArray {
518 if value != 0 {
519 foundIwPtr = true
520 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530521 meParams.Attributes[meAttribute] = value
mpagenko01e726e2020-10-23 09:45:29 +0000522 logger.Debugw("UniPonAniConfigFsm Set::1pMapper", log.Fields{
523 "for Prio": index,
524 "IwPtr": strconv.FormatInt(int64(value), 16),
525 "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530526 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000527 }
Himani Chawla4d908332020-08-31 12:30:20 +0530528
529 if !foundIwPtr {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000530 logger.Errorw("UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000531 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000532 //let's reset the state machine in order to release all resources now
533 pConfigAniStateAFsm := oFsm.pAdaptFsm
534 if pConfigAniStateAFsm != nil {
535 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530536 go func(aPAFsm *AdapterFsm) {
537 if aPAFsm != nil && aPAFsm.pFsm != nil {
538 _ = aPAFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000539 }
540 }(pConfigAniStateAFsm)
541 }
542 }
543
mpagenko3dbcdd22020-07-22 07:38:45 +0000544 meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
545 oFsm.pAdaptFsm.commChan, meParams)
546 //accept also nil as (error) return value for writing to LastTx
547 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000548 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000549}
550
Himani Chawla6d2ae152020-09-02 13:11:20 +0530551func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000552 logger.Debugw("uniPonAniConfigFsm ani config done", log.Fields{
553 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000554 //use DeviceHandler event notification directly
mpagenko8b07c1b2020-11-26 10:36:31 +0000555 oFsm.pDeviceHandler.deviceProcStatusUpdate(OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
mpagenko01e726e2020-10-23 09:45:29 +0000556 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800557 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko01e726e2020-10-23 09:45:29 +0000558 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
mpagenko8b07c1b2020-11-26 10:36:31 +0000559 // but only in case the techProfile was configured (not deleted)
560 if oFsm.requestEventOffset == 0 {
561 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(oFsm.pOnuUniPort)
562 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000563
mpagenko01e726e2020-10-23 09:45:29 +0000564 if oFsm.chanSet {
565 // indicate processing done to the caller
566 logger.Debugw("uniPonAniConfigFsm processingDone on channel", log.Fields{
567 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
568 oFsm.chSuccess <- oFsm.procStep
569 oFsm.chanSet = false //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000570 }
mpagenko01e726e2020-10-23 09:45:29 +0000571
572 //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 +0000573}
574
mpagenko8b07c1b2020-11-26 10:36:31 +0000575func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(e *fsm.Event) {
576 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
577 oFsm.pUniTechProf.mutexTPState.Lock()
578 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
579 oFsm.pUniTechProf.mutexTPState.Unlock()
580 logger.Debugw("uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
581 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
582 "GemIwTp-entity-id": loGemPortID})
583 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
584
585 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
586 meInstance := oFsm.pOmciCC.sendDeleteGemIWTP(context.TODO(), ConstDefaultOmciTimeout, true,
587 oFsm.pAdaptFsm.commChan, loGemPortID)
588 oFsm.pLastTxMeInstance = meInstance
589}
590
591func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(e *fsm.Event) {
592 oFsm.pUniTechProf.mutexTPState.Lock()
593 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
594 oFsm.pUniTechProf.mutexTPState.Unlock()
595 logger.Debugw("uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
596 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
597 "GemNCTP-entity-id": loGemPortID})
598 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
599 meInstance := oFsm.pOmciCC.sendDeleteGemNCTP(context.TODO(), ConstDefaultOmciTimeout, true,
600 oFsm.pAdaptFsm.commChan, loGemPortID)
601 oFsm.pLastTxMeInstance = meInstance
602}
603
604func (oFsm *uniPonAniConfigFsm) enterResettingTcont(e *fsm.Event) {
605 logger.Debugw("uniPonAniConfigFsm - start resetting the TCont", log.Fields{
606 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
607
608 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
609 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
610 meParams := me.ParamData{
611 EntityID: oFsm.tcont0ID,
612 Attributes: me.AttributeValueMap{
613 "AllocId": unusedTcontAllocID,
614 },
615 }
616 meInstance := oFsm.pOmciCC.sendSetTcontVar(context.TODO(), ConstDefaultOmciTimeout, true,
617 oFsm.pAdaptFsm.commChan, meParams)
618 oFsm.pLastTxMeInstance = meInstance
619}
620
621func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(e *fsm.Event) {
622 logger.Debugw("uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
623 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
624
625 meInstance := oFsm.pOmciCC.sendDeleteDot1PMapper(context.TODO(), ConstDefaultOmciTimeout, true,
626 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
627 oFsm.pLastTxMeInstance = meInstance
628}
629
630func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(e *fsm.Event) {
631 logger.Debugw("uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
632 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
633
634 meInstance := oFsm.pOmciCC.sendDeleteMBPConfigData(context.TODO(), ConstDefaultOmciTimeout, true,
635 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
636 oFsm.pLastTxMeInstance = meInstance
637}
638
639func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(e *fsm.Event) {
640 logger.Debugw("uniPonAniConfigFsm ani removal done", log.Fields{
641 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
642 //use DeviceHandler event notification directly
643 oFsm.pDeviceHandler.deviceProcStatusUpdate(OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
644 if oFsm.chanSet {
645 // indicate processing done to the caller
646 logger.Debugw("uniPonAniConfigFsm processingDone on channel", log.Fields{
647 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
648 oFsm.chSuccess <- oFsm.procStep
649 oFsm.chanSet = false //reset the internal channel state
650 }
651
652 //let's reset the state machine in order to release all resources now
653 pConfigAniStateAFsm := oFsm.pAdaptFsm
654 if pConfigAniStateAFsm != nil {
655 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
656 go func(aPAFsm *AdapterFsm) {
657 if aPAFsm != nil && aPAFsm.pFsm != nil {
658 _ = aPAFsm.pFsm.Event(aniEvReset)
659 }
660 }(pConfigAniStateAFsm)
661 }
662}
663
Himani Chawla6d2ae152020-09-02 13:11:20 +0530664func (oFsm *uniPonAniConfigFsm) enterResettingState(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000665 logger.Debugw("uniPonAniConfigFsm resetting", log.Fields{
666 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000667
mpagenko3dbcdd22020-07-22 07:38:45 +0000668 pConfigAniStateAFsm := oFsm.pAdaptFsm
669 if pConfigAniStateAFsm != nil {
670 // abort running message processing
671 fsmAbortMsg := Message{
672 Type: TestMsg,
673 Data: TestMessage{
674 TestMessageVal: AbortMessageProcessing,
675 },
676 }
677 pConfigAniStateAFsm.commChan <- fsmAbortMsg
678
679 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530680 go func(aPAFsm *AdapterFsm) {
681 if aPAFsm != nil && aPAFsm.pFsm != nil {
682 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000683 }
684 }(pConfigAniStateAFsm)
685 }
686}
687
Himani Chawla6d2ae152020-09-02 13:11:20 +0530688func (oFsm *uniPonAniConfigFsm) enterDisabledState(e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000689 logger.Debugw("uniPonAniConfigFsm enters disabled state", log.Fields{
690 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000691 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +0000692
mpagenko01e726e2020-10-23 09:45:29 +0000693 //remove all TechProf related internal data to allow for new configuration (e.g. with disable/enable procedure)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800694 oFsm.pUniTechProf.clearAniSideConfig(oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko1cc3cb42020-07-27 15:24:38 +0000695}
696
Himani Chawla6d2ae152020-09-02 13:11:20 +0530697func (oFsm *uniPonAniConfigFsm) processOmciAniMessages( /*ctx context.Context*/ ) {
mpagenko01e726e2020-10-23 09:45:29 +0000698 logger.Debugw("Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000699loop:
700 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000701 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +0000702 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000703 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530704 message, ok := <-oFsm.pAdaptFsm.commChan
705 if !ok {
mpagenko01e726e2020-10-23 09:45:29 +0000706 logger.Info("UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530707 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
708 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
709 break loop
710 }
mpagenko01e726e2020-10-23 09:45:29 +0000711 logger.Debugw("UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530712
713 switch message.Type {
714 case TestMsg:
715 msg, _ := message.Data.(TestMessage)
716 if msg.TestMessageVal == AbortMessageProcessing {
mpagenko01e726e2020-10-23 09:45:29 +0000717 logger.Infow("UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000718 break loop
719 }
mpagenko01e726e2020-10-23 09:45:29 +0000720 logger.Warnw("UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +0530721 case OMCI:
722 msg, _ := message.Data.(OmciMessage)
723 oFsm.handleOmciAniConfigMessage(msg)
724 default:
mpagenko01e726e2020-10-23 09:45:29 +0000725 logger.Warn("UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +0530726 "message.Type": message.Type})
727 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000728
Himani Chawla4d908332020-08-31 12:30:20 +0530729 }
mpagenko01e726e2020-10-23 09:45:29 +0000730 logger.Infow("End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530731}
732
Himani Chawla6d2ae152020-09-02 13:11:20 +0530733func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530734 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
735 if msgLayer == nil {
Andrea Campanella6515c582020-10-05 11:25:00 +0200736 logger.Errorw("Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000737 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530738 return
739 }
740 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
741 if !msgOk {
Andrea Campanella6515c582020-10-05 11:25:00 +0200742 logger.Errorw("Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000743 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530744 return
745 }
mpagenko01e726e2020-10-23 09:45:29 +0000746 logger.Debugw("CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +0000747 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
748 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
749 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
750 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
751 // maybe we can use just the same eventName for different state transitions like "forward"
752 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
753 switch oFsm.pLastTxMeInstance.GetName() {
754 case "Ieee8021PMapperServiceProfile":
755 { // let the FSM proceed ...
756 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
757 }
758 case "MacBridgePortConfigurationData":
759 { // let the FSM proceed ...
760 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
761 }
762 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint":
763 { // let aniConfig Multi-Id processing proceed by stopping the wait function
764 oFsm.omciMIdsResponseReceived <- true
765 }
766 }
767 }
768 } else {
Himani Chawla4d908332020-08-31 12:30:20 +0530769 logger.Errorw("Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
770 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
771 return
772 }
Himani Chawla4d908332020-08-31 12:30:20 +0530773}
774
Himani Chawla6d2ae152020-09-02 13:11:20 +0530775func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530776 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
777 if msgLayer == nil {
Andrea Campanella6515c582020-10-05 11:25:00 +0200778 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000779 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530780 return
781 }
782 msgObj, msgOk := msgLayer.(*omci.SetResponse)
783 if !msgOk {
Andrea Campanella6515c582020-10-05 11:25:00 +0200784 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +0000785 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530786 return
787 }
mpagenko01e726e2020-10-23 09:45:29 +0000788 logger.Debugw("UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +0530789 if msgObj.Result != me.Success {
Andrea Campanella6515c582020-10-05 11:25:00 +0200790 logger.Errorw("UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +0000791 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +0530792 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
793 return
794 }
mpagenko01e726e2020-10-23 09:45:29 +0000795 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
796 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
Himani Chawla4d908332020-08-31 12:30:20 +0530797 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
798 // if, then something like:
799 //oFsm.pOnuDB.StoreMe(msgObj)
800
mpagenko01e726e2020-10-23 09:45:29 +0000801 switch oFsm.pLastTxMeInstance.GetName() {
Himani Chawla4d908332020-08-31 12:30:20 +0530802 case "TCont":
803 { // let the FSM proceed ...
mpagenko8b07c1b2020-11-26 10:36:31 +0000804 if oFsm.requestEventOffset == 0 { //from TCont config request
805 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
806 } else { // from T-Cont reset request
807 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
808 }
Himani Chawla4d908332020-08-31 12:30:20 +0530809 }
810 case "PriorityQueue":
811 { // let the PrioQueue init proceed by stopping the wait function
812 oFsm.omciMIdsResponseReceived <- true
813 }
814 case "Ieee8021PMapperServiceProfile":
815 { // let the FSM proceed ...
816 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
817 }
818 }
819 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000820}
821
mpagenko8b07c1b2020-11-26 10:36:31 +0000822func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(msg OmciMessage) {
823 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
824 if msgLayer == nil {
825 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
826 log.Fields{"device-id": oFsm.deviceID})
827 return
828 }
829 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
830 if !msgOk {
831 logger.Errorw("UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
832 log.Fields{"device-id": oFsm.deviceID})
833 return
834 }
835 logger.Debugw("UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
836 if msgObj.Result != me.Success {
837 logger.Errorw("UniPonAniConfigFsm - Omci DeleteResponse Error",
838 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
839 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
840 // store error for mgmt display?
841 return
842 }
843 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
844 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
845 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
846 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
847
848 switch oFsm.pLastTxMeInstance.GetName() {
849 case "GemInterworkingTerminationPoint":
850 { // let the FSM proceed ...
851 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
852 }
853 case "GemPortNetworkCtp":
854 { // let the FSM proceed ...
855 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
856 }
857 case "Ieee8021PMapperServiceProfile":
858 { // let the FSM proceed ...
859 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
860 }
861 case "MacBridgePortConfigurationData":
862 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
863 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
864 }
865 }
866 }
867}
868
Himani Chawla6d2ae152020-09-02 13:11:20 +0530869func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(msg OmciMessage) {
mpagenko01e726e2020-10-23 09:45:29 +0000870 logger.Debugw("Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000871 "msgType": msg.OmciMsg.MessageType})
872
873 switch msg.OmciMsg.MessageType {
874 case omci.CreateResponseType:
875 {
Himani Chawla4d908332020-08-31 12:30:20 +0530876 oFsm.handleOmciAniConfigCreateResponseMessage(msg)
877
mpagenko3dbcdd22020-07-22 07:38:45 +0000878 } //CreateResponseType
879 case omci.SetResponseType:
880 {
Himani Chawla4d908332020-08-31 12:30:20 +0530881 oFsm.handleOmciAniConfigSetResponseMessage(msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000882
mpagenko3dbcdd22020-07-22 07:38:45 +0000883 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +0000884 case omci.DeleteResponseType:
885 {
886 oFsm.handleOmciAniConfigDeleteResponseMessage(msg)
887
888 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +0000889 default:
890 {
Andrea Campanella6515c582020-10-05 11:25:00 +0200891 logger.Errorw("uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +0000892 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000893 return
894 }
895 }
896}
897
Himani Chawla6d2ae152020-09-02 13:11:20 +0530898func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000899 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
900 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530901 logger.Debugw("uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000902 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
903 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000904 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000905 meParams := me.ParamData{
906 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
907 Attributes: me.AttributeValueMap{
908 "PortId": gemPortAttribs.gemPortID,
909 "TContPointer": oFsm.tcont0ID,
910 "Direction": gemPortAttribs.direction,
911 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
912 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
913 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
914 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
915 },
916 }
917 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
918 oFsm.pAdaptFsm.commChan, meParams)
919 //accept also nil as (error) return value for writing to LastTx
920 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000921 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000922
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000923 //verify response
924 err := oFsm.waitforOmciResponse()
925 if err != nil {
926 logger.Errorw("GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000927 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +0530928 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000929 return
930 }
931 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +0000932
933 // if Config has been done for all GemPort instances let the FSM proceed
mpagenko01e726e2020-10-23 09:45:29 +0000934 logger.Debugw("GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530935 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000936}
937
Himani Chawla6d2ae152020-09-02 13:11:20 +0530938func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000939 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
940 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530941 logger.Debugw("uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000942 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
943 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000944 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000945 meParams := me.ParamData{
946 EntityID: gemPortAttribs.gemPortID,
947 Attributes: me.AttributeValueMap{
948 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
949 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
950 "ServiceProfilePointer": oFsm.mapperSP0ID,
951 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
952 "GalProfilePointer": galEthernetEID,
953 },
954 }
955 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
956 oFsm.pAdaptFsm.commChan, meParams)
957 //accept also nil as (error) return value for writing to LastTx
958 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000959 oFsm.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000960
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000961 //verify response
962 err := oFsm.waitforOmciResponse()
963 if err != nil {
964 logger.Errorw("GemIwTp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000965 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +0530966 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000967 return
968 }
969 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +0000970
971 // if Config has been done for all GemPort instances let the FSM proceed
mpagenko01e726e2020-10-23 09:45:29 +0000972 logger.Debugw("GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530973 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000974}
975
Himani Chawla6d2ae152020-09-02 13:11:20 +0530976func (oFsm *uniPonAniConfigFsm) performSettingPQs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000977 const cu16StrictPrioWeight uint16 = 0xFFFF
978 //find all upstream PrioQueues related to this T-Cont
979 loQueueMap := ordered_map.NewOrderedMap()
980 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
981 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +0530982 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000983 //key does not yet exist
984 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
985 }
986 } else {
987 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
988 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000989 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000990
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000991 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
992 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
993 // complete chain is not valid, then some error should be thrown and configuration can be aborted
994 // or even be finished without correct SP/WRR setting
995
996 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
997 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
998 // even though its T-Cont seems to be wrong ...
999 loTrafficSchedulerEID := 0x8000
1000 //for all found queues
1001 iter := loQueueMap.IterFunc()
1002 for kv, ok := iter(); ok; kv, ok = iter() {
1003 queueIndex := (kv.Key).(uint16)
1004 meParams := me.ParamData{
1005 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301006 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001007 }
1008 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1009 //StrictPrio indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301010 logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001011 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001012 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001013 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1014 } else {
1015 //WRR indication
Himani Chawla6d2ae152020-09-02 13:11:20 +05301016 logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001017 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1018 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001019 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001020 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1021 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1022 }
1023 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(context.TODO(), ConstDefaultOmciTimeout, true,
1024 oFsm.pAdaptFsm.commChan, meParams)
1025 //accept also nil as (error) return value for writing to LastTx
1026 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001027 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001028
1029 //verify response
1030 err := oFsm.waitforOmciResponse()
1031 if err != nil {
1032 logger.Errorw("PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001033 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301034 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001035 return
1036 }
1037
1038 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1039 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1040 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1041 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1042
1043 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001044
1045 // if Config has been done for all PrioQueue instances let the FSM proceed
mpagenko01e726e2020-10-23 09:45:29 +00001046 logger.Debugw("PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301047 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001048}
1049
Himani Chawla6d2ae152020-09-02 13:11:20 +05301050func (oFsm *uniPonAniConfigFsm) waitforOmciResponse() error {
mpagenko3dbcdd22020-07-22 07:38:45 +00001051 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301052 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001053 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001054 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001055 case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
mpagenko01e726e2020-10-23 09:45:29 +00001056 logger.Warnw("UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
1057 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001058 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301059 if success {
Himani Chawla6d2ae152020-09-02 13:11:20 +05301060 logger.Debug("uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +00001061 return nil
1062 }
1063 // should not happen so far
mpagenko01e726e2020-10-23 09:45:29 +00001064 logger.Warnw("uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
1065 return fmt.Errorf("uniPonAniConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001066 }
1067}