blob: 010378848c16dda6752ebe8b53ef66457e82f598 [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"
22 "errors"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
mpagenko3dbcdd22020-07-22 07:38:45 +000024 "strconv"
25 "time"
26
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000027 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000028 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000029 "github.com/opencord/omci-lib-go"
30 me "github.com/opencord/omci-lib-go/generated"
31 "github.com/opencord/voltha-lib-go/v3/pkg/log"
32 //ic "github.com/opencord/voltha-protos/v3/go/inter_container"
33 //"github.com/opencord/voltha-protos/v3/go/openflow_13"
34 //"github.com/opencord/voltha-protos/v3/go/voltha"
35)
36
mpagenko1cc3cb42020-07-27 15:24:38 +000037const (
38 // events of config PON ANI port FSM
39 aniEvStart = "uniEvStart"
40 aniEvStartConfig = "aniEvStartConfig"
mpagenkodff5dda2020-08-28 11:52:01 +000041 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
mpagenko1cc3cb42020-07-27 15:24:38 +000042 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
43 aniEvRxTcontsResp = "aniEvRxTcontsResp"
44 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
45 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
46 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
mpagenkodff5dda2020-08-28 11:52:01 +000047 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
mpagenko1cc3cb42020-07-27 15:24:38 +000048 aniEvTimeoutSimple = "aniEvTimeoutSimple"
49 aniEvTimeoutMids = "aniEvTimeoutMids"
50 aniEvReset = "aniEvReset"
51 aniEvRestart = "aniEvRestart"
52)
53const (
54 // states of config PON ANI port FSM
55 aniStDisabled = "aniStDisabled"
56 aniStStarting = "aniStStarting"
57 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
58 aniStCreatingMBPCD = "aniStCreatingMBPCD"
59 aniStSettingTconts = "aniStSettingTconts"
60 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
61 aniStCreatingGemIWs = "aniStCreatingGemIWs"
62 aniStSettingPQs = "aniStSettingPQs"
63 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
64 aniStConfigDone = "aniStConfigDone"
65 aniStResetting = "aniStResetting"
66)
67
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000068type ponAniGemPortAttribs struct {
69 gemPortID uint16
70 upQueueID uint16
71 downQueueID uint16
72 direction uint8
73 qosPolicy string
74 weight uint8
75 pbitString string
76}
77
Himani Chawla6d2ae152020-09-02 13:11:20 +053078//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
79type uniPonAniConfigFsm struct {
80 pOmciCC *omciCC
81 pOnuUniPort *onuUniPort
82 pUniTechProf *onuUniTechProf
83 pOnuDB *onuDeviceDB
mpagenko3dbcdd22020-07-22 07:38:45 +000084 techProfileID uint16
85 requestEvent OnuDeviceEvent
Himani Chawla4d908332020-08-31 12:30:20 +053086 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +000087 pAdaptFsm *AdapterFsm
mpagenko1cc3cb42020-07-27 15:24:38 +000088 aniConfigCompleted bool
mpagenko3dbcdd22020-07-22 07:38:45 +000089 chSuccess chan<- uint8
90 procStep uint8
91 chanSet bool
92 mapperSP0ID uint16
93 macBPCD0ID uint16
94 tcont0ID uint16
95 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000096 gemPortAttribsSlice []ponAniGemPortAttribs
mpagenko3dbcdd22020-07-22 07:38:45 +000097}
98
Himani Chawla6d2ae152020-09-02 13:11:20 +053099//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
100func newUniPonAniConfigFsm(apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
101 apOnuDB *onuDeviceDB, aTechProfileID uint16, aRequestEvent OnuDeviceEvent, aName string,
102 aDeviceID string, aCommChannel chan Message) *uniPonAniConfigFsm {
103 instFsm := &uniPonAniConfigFsm{
mpagenko1cc3cb42020-07-27 15:24:38 +0000104 pOmciCC: apDevOmciCC,
105 pOnuUniPort: apUniPort,
106 pUniTechProf: apUniTechProf,
107 pOnuDB: apOnuDB,
108 techProfileID: aTechProfileID,
109 requestEvent: aRequestEvent,
110 aniConfigCompleted: false,
111 chanSet: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000112 }
113 instFsm.pAdaptFsm = NewAdapterFsm(aName, aDeviceID, aCommChannel)
114 if instFsm.pAdaptFsm == nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530115 logger.Errorw("uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000116 "device-id": aDeviceID})
117 return nil
118 }
119
120 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000121 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000122 fsm.Events{
123
mpagenko1cc3cb42020-07-27 15:24:38 +0000124 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000125
126 //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 +0000127 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000128 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000129 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
130 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000131 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000132 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000133 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000134 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000135 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000136 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000137 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000138
mpagenko1cc3cb42020-07-27 15:24:38 +0000139 {Name: aniEvTimeoutSimple, Src: []string{
140 aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper}, Dst: aniStStarting},
141 {Name: aniEvTimeoutMids, Src: []string{
142 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000143
mpagenko1cc3cb42020-07-27 15:24:38 +0000144 // exceptional treatment for all states except aniStResetting
145 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
146 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
147 aniStConfigDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000148 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000149 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
mpagenko3dbcdd22020-07-22 07:38:45 +0000150 },
151
152 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000153 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
154 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(e) },
155 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(e) },
156 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(e) },
157 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(e) },
158 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(e) },
159 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(e) },
160 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(e) },
161 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(e) },
162 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(e) },
163 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(e) },
164 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000165 },
166 )
167 if instFsm.pAdaptFsm.pFsm == nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530168 logger.Errorw("uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000169 "device-id": aDeviceID})
170 return nil
171 }
172
Himani Chawla6d2ae152020-09-02 13:11:20 +0530173 logger.Infow("uniPonAniConfigFsm created", log.Fields{"device-id": aDeviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000174 return instFsm
175}
176
Himani Chawla6d2ae152020-09-02 13:11:20 +0530177//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
178func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000179 oFsm.chSuccess = aChSuccess
180 oFsm.procStep = aProcStep
181 oFsm.chanSet = true
182}
183
Himani Chawla6d2ae152020-09-02 13:11:20 +0530184func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530185 if aPAFsm != nil && aPAFsm.pFsm != nil {
186 //stick to pythonAdapter numbering scheme
187 //index 0 in naming refers to possible usage of multiple instances (later)
188 oFsm.mapperSP0ID = ieeeMapperServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) + oFsm.techProfileID
189 oFsm.macBPCD0ID = macBridgePortAniEID + uint16(oFsm.pOnuUniPort.entityID) + oFsm.techProfileID
190
191 // For the time being: if there are multiple T-Conts on the ONU the first one from the entityID-ordered list is used
192 // TODO!: if more T-Conts have to be supported (tcontXID!), then use the first instances of the entity-ordered list
193 // or use the py code approach, which might be a bit more complicated, but also more secure, as it
194 // ensures that the selected T-Cont also has queues (which I would assume per definition from ONU, but who knows ...)
195 // so this approach would search the (sorted) upstream PrioQueue list and use the T-Cont (if available) from highest Bytes
196 // or sndHighByte of relatedPort Attribute (T-Cont Reference) and in case of multiple TConts find the next free TContIndex
197 // that way from PrioQueue.relatedPort list
Himani Chawla6d2ae152020-09-02 13:11:20 +0530198 if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.TContClassID); len(tcontInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530199 oFsm.tcont0ID = tcontInstKeys[0]
200 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
201 "device-id": oFsm.pAdaptFsm.deviceID})
202 } else {
203 logger.Warnw("No TCont instances found", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
204 }
205 oFsm.alloc0ID = (*(oFsm.pUniTechProf.mapPonAniConfig[oFsm.pOnuUniPort.uniID]))[0].tcontParams.allocID
206 loGemPortAttribs := ponAniGemPortAttribs{}
207 //for all TechProfile set GemIndices
208 for _, gemEntry := range (*(oFsm.pUniTechProf.mapPonAniConfig[oFsm.pOnuUniPort.uniID]))[0].mapGemPortParams {
209 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
210
Himani Chawla6d2ae152020-09-02 13:11:20 +0530211 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530212
213 loGemPortAttribs.gemPortID = gemEntry.gemPortID
214 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
215 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
216 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
217 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
218
219 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
220 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
221 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
222 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
223 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
224 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
225
226 usQueueFound := false
227 dsQueueFound := false
228 for _, mgmtEntityID := range queueInstKeys {
229 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
230 returnVal := meAttributes["RelatedPort"]
231 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530233 if relatedPort == usQrelPortMask {
234 loGemPortAttribs.upQueueID = mgmtEntityID
235 logger.Debugw("UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
236 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.pAdaptFsm.deviceID})
237 usQueueFound = true
238 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
239 loGemPortAttribs.downQueueID = mgmtEntityID
240 logger.Debugw("DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
241 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.pAdaptFsm.deviceID})
242 dsQueueFound = true
243 }
244 if usQueueFound && dsQueueFound {
245 break
246 }
247 } else {
248 logger.Warnw("Could not convert attribute value", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
249 }
250 } else {
251 logger.Warnw("'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
252 }
253 } else {
254 logger.Warnw("No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
255 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.pAdaptFsm.deviceID})
256 }
257 }
258 } else {
259 logger.Warnw("No PriorityQueue instances found", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
260 }
261 loGemPortAttribs.direction = gemEntry.direction
262 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
263 loGemPortAttribs.weight = gemEntry.queueWeight
264 loGemPortAttribs.pbitString = gemEntry.pbitString
265
266 logger.Debugw("prio-related GemPort attributes:", log.Fields{
267 "gemPortID": loGemPortAttribs.gemPortID,
268 "upQueueID": loGemPortAttribs.upQueueID,
269 "downQueueID": loGemPortAttribs.downQueueID,
270 "pbitString": loGemPortAttribs.pbitString,
271 "prioQueueIndex": gemEntry.prioQueueIndex,
272 })
273
274 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
275 }
276 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
277 }
278}
279
Himani Chawla6d2ae152020-09-02 13:11:20 +0530280func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(e *fsm.Event) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000281 logger.Debugw("UniPonAniConfigFsm start", log.Fields{"in state": e.FSM.Current(),
282 "device-id": oFsm.pAdaptFsm.deviceID})
283 // in case the used channel is not yet defined (can be re-used after restarts)
284 if oFsm.omciMIdsResponseReceived == nil {
285 oFsm.omciMIdsResponseReceived = make(chan bool)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530286 logger.Debug("uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000287 } else {
288 // as we may 're-use' this instance of FSM and the connected channel
289 // make sure there is no 'lingering' request in the already existing channel:
290 // (simple loop sufficient as we are the only receiver)
291 for len(oFsm.omciMIdsResponseReceived) > 0 {
292 <-oFsm.omciMIdsResponseReceived
293 }
294 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000295 //ensure internal slices are empty (which might be set from previous run) - release memory
296 oFsm.gemPortAttribsSlice = nil
297
mpagenko3dbcdd22020-07-22 07:38:45 +0000298 // start go routine for processing of LockState messages
mpagenkodff5dda2020-08-28 11:52:01 +0000299 go oFsm.processOmciAniMessages()
mpagenko3dbcdd22020-07-22 07:38:45 +0000300
301 //let the state machine run forward from here directly
302 pConfigAniStateAFsm := oFsm.pAdaptFsm
303 if pConfigAniStateAFsm != nil {
304 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530305 go oFsm.prepareAndEnterConfigState(pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000306
mpagenko3dbcdd22020-07-22 07:38:45 +0000307 }
308}
309
Himani Chawla6d2ae152020-09-02 13:11:20 +0530310func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(e *fsm.Event) {
311 logger.Debugw("uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000312 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
313 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
314 meInstance := oFsm.pOmciCC.sendCreateDot1PMapper(context.TODO(), ConstDefaultOmciTimeout, true,
315 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
316 //accept also nil as (error) return value for writing to LastTx
317 // - this avoids misinterpretation of new received OMCI messages
318 oFsm.pOmciCC.pLastTxMeInstance = meInstance
319}
320
Himani Chawla6d2ae152020-09-02 13:11:20 +0530321func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(e *fsm.Event) {
322 logger.Debugw("uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000323 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
324 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
325 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
326 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
327 meParams := me.ParamData{
328 EntityID: oFsm.macBPCD0ID,
329 Attributes: me.AttributeValueMap{
330 "BridgeIdPointer": bridgePtr,
331 "PortNum": 0xFF, //fixed unique ANI side indication
332 "TpType": 3, //for .1PMapper
333 "TpPointer": oFsm.mapperSP0ID,
334 },
335 }
336 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
337 oFsm.pAdaptFsm.commChan, meParams)
338 //accept also nil as (error) return value for writing to LastTx
339 // - this avoids misinterpretation of new received OMCI messages
340 oFsm.pOmciCC.pLastTxMeInstance = meInstance
341
342}
343
Himani Chawla6d2ae152020-09-02 13:11:20 +0530344func (oFsm *uniPonAniConfigFsm) enterSettingTconts(e *fsm.Event) {
345 logger.Debugw("uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000346 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
347 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
348 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
349 meParams := me.ParamData{
350 EntityID: oFsm.tcont0ID,
351 Attributes: me.AttributeValueMap{
352 "AllocId": oFsm.alloc0ID,
353 },
354 }
355 meInstance := oFsm.pOmciCC.sendSetTcontVar(context.TODO(), ConstDefaultOmciTimeout, true,
356 oFsm.pAdaptFsm.commChan, meParams)
357 //accept also nil as (error) return value for writing to LastTx
358 // - this avoids misinterpretation of new received OMCI messages
359 oFsm.pOmciCC.pLastTxMeInstance = meInstance
360}
361
Himani Chawla6d2ae152020-09-02 13:11:20 +0530362func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(e *fsm.Event) {
363 logger.Debugw("uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000364 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
365 go oFsm.performCreatingGemNCTPs()
366}
367
Himani Chawla6d2ae152020-09-02 13:11:20 +0530368func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(e *fsm.Event) {
369 logger.Debugw("uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000370 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
371 go oFsm.performCreatingGemIWs()
372}
373
Himani Chawla6d2ae152020-09-02 13:11:20 +0530374func (oFsm *uniPonAniConfigFsm) enterSettingPQs(e *fsm.Event) {
375 logger.Debugw("uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000376 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
377 go oFsm.performSettingPQs()
378}
379
Himani Chawla6d2ae152020-09-02 13:11:20 +0530380func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(e *fsm.Event) {
381 logger.Debugw("uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko3dbcdd22020-07-22 07:38:45 +0000382 "toGemIw": 1024 /* cmp above */, "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
383
Himani Chawla6d2ae152020-09-02 13:11:20 +0530384 logger.Debugw("uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000385 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
386 "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
387
mpagenko3dbcdd22020-07-22 07:38:45 +0000388 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000389 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530390 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000391 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000392
393 //assign the GemPorts according to the configured Prio
394 var loPrioGemPortArray [8]uint16
395 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
396 for i := 0; i < 8; i++ {
397 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
398 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
399 if prio == 1 { // Check this p-bit is set
400 if loPrioGemPortArray[i] == 0 {
401 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
402 } else {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530403 logger.Warnw("uniPonAniConfigFsm PrioString not unique", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000404 "device-id": oFsm.pAdaptFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
405 "SetGemPort": loPrioGemPortArray[i]})
406 }
407 }
408 } else {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530409 logger.Warnw("uniPonAniConfigFsm PrioString evaluation error", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000410 "device-id": oFsm.pAdaptFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
411 "prioString": gemPortAttribs.pbitString, "position": i})
412 }
413
414 }
415 }
416 var foundIwPtr bool = false
Himani Chawla4d908332020-08-31 12:30:20 +0530417 for index, value := range loPrioGemPortArray {
418 if value != 0 {
419 foundIwPtr = true
420 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
421 logger.Debugf("UniPonAniConfigFsm Set::1pMapper", log.Fields{
422 "IwPtr for Prio%d": strconv.FormatInt(int64(value), 16), "device-id": oFsm.pAdaptFsm.deviceID}, index)
423 meParams.Attributes[meAttribute] = value
424
425 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000426 }
Himani Chawla4d908332020-08-31 12:30:20 +0530427
428 if !foundIwPtr {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000429 logger.Errorw("UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
430 "device-id": oFsm.pAdaptFsm.deviceID})
431 //let's reset the state machine in order to release all resources now
432 pConfigAniStateAFsm := oFsm.pAdaptFsm
433 if pConfigAniStateAFsm != nil {
434 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530435 go func(aPAFsm *AdapterFsm) {
436 if aPAFsm != nil && aPAFsm.pFsm != nil {
437 _ = aPAFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000438 }
439 }(pConfigAniStateAFsm)
440 }
441 }
442
mpagenko3dbcdd22020-07-22 07:38:45 +0000443 meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
444 oFsm.pAdaptFsm.commChan, meParams)
445 //accept also nil as (error) return value for writing to LastTx
446 // - this avoids misinterpretation of new received OMCI messages
447 oFsm.pOmciCC.pLastTxMeInstance = meInstance
448}
449
Himani Chawla6d2ae152020-09-02 13:11:20 +0530450func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(e *fsm.Event) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000451
mpagenko1cc3cb42020-07-27 15:24:38 +0000452 oFsm.aniConfigCompleted = true
mpagenko3dbcdd22020-07-22 07:38:45 +0000453
454 //let's reset the state machine in order to release all resources now
455 pConfigAniStateAFsm := oFsm.pAdaptFsm
456 if pConfigAniStateAFsm != nil {
457 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530458 go func(aPAFsm *AdapterFsm) {
459 if aPAFsm != nil && aPAFsm.pFsm != nil {
460 _ = aPAFsm.pFsm.Event(aniEvReset)
mpagenko3dbcdd22020-07-22 07:38:45 +0000461 }
462 }(pConfigAniStateAFsm)
463 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000464}
465
Himani Chawla6d2ae152020-09-02 13:11:20 +0530466func (oFsm *uniPonAniConfigFsm) enterResettingState(e *fsm.Event) {
467 logger.Debugw("uniPonAniConfigFsm resetting", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000468
mpagenko3dbcdd22020-07-22 07:38:45 +0000469 pConfigAniStateAFsm := oFsm.pAdaptFsm
470 if pConfigAniStateAFsm != nil {
471 // abort running message processing
472 fsmAbortMsg := Message{
473 Type: TestMsg,
474 Data: TestMessage{
475 TestMessageVal: AbortMessageProcessing,
476 },
477 }
478 pConfigAniStateAFsm.commChan <- fsmAbortMsg
479
480 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 go func(aPAFsm *AdapterFsm) {
482 if aPAFsm != nil && aPAFsm.pFsm != nil {
483 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +0000484 }
485 }(pConfigAniStateAFsm)
486 }
487}
488
Himani Chawla6d2ae152020-09-02 13:11:20 +0530489func (oFsm *uniPonAniConfigFsm) enterDisabledState(e *fsm.Event) {
490 logger.Debugw("uniPonAniConfigFsm enters disabled state", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
mpagenko1cc3cb42020-07-27 15:24:38 +0000491
492 if oFsm.aniConfigCompleted {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530493 logger.Debugw("uniPonAniConfigFsm send dh event notification", log.Fields{
mpagenko1cc3cb42020-07-27 15:24:38 +0000494 "from_State": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
495 //use DeviceHandler event notification directly
Himani Chawla6d2ae152020-09-02 13:11:20 +0530496 oFsm.pOmciCC.pBaseDeviceHandler.deviceProcStatusUpdate(oFsm.requestEvent)
mpagenko1cc3cb42020-07-27 15:24:38 +0000497 oFsm.aniConfigCompleted = false
498 }
mpagenkodff5dda2020-08-28 11:52:01 +0000499 //store that the UNI related techProfile processing is done for the given Profile and Uni
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, true)
mpagenkodff5dda2020-08-28 11:52:01 +0000501 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
502 go oFsm.pOmciCC.pBaseDeviceHandler.verifyUniVlanConfigRequest(oFsm.pOnuUniPort)
mpagenko1cc3cb42020-07-27 15:24:38 +0000503
504 if oFsm.chanSet {
505 // indicate processing done to the caller
Himani Chawla6d2ae152020-09-02 13:11:20 +0530506 logger.Debugw("uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko1cc3cb42020-07-27 15:24:38 +0000507 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
508 oFsm.chSuccess <- oFsm.procStep
509 oFsm.chanSet = false //reset the internal channel state
510 }
511
512}
513
Himani Chawla6d2ae152020-09-02 13:11:20 +0530514func (oFsm *uniPonAniConfigFsm) processOmciAniMessages( /*ctx context.Context*/ ) {
515 logger.Debugw("Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000516loop:
517 for {
mpagenko3dbcdd22020-07-22 07:38:45 +0000518 // case <-ctx.Done():
519 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.pAdaptFsm.deviceID})
520 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +0530521 message, ok := <-oFsm.pAdaptFsm.commChan
522 if !ok {
523 logger.Info("UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
524 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
525 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
526 break loop
527 }
528 logger.Debugw("UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
529
530 switch message.Type {
531 case TestMsg:
532 msg, _ := message.Data.(TestMessage)
533 if msg.TestMessageVal == AbortMessageProcessing {
534 logger.Infow("UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000535 break loop
536 }
Himani Chawla4d908332020-08-31 12:30:20 +0530537 logger.Warnw("UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "MessageVal": msg.TestMessageVal})
538 case OMCI:
539 msg, _ := message.Data.(OmciMessage)
540 oFsm.handleOmciAniConfigMessage(msg)
541 default:
542 logger.Warn("UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
543 "message.Type": message.Type})
544 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000545
Himani Chawla4d908332020-08-31 12:30:20 +0530546 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530547 logger.Infow("End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530548}
549
Himani Chawla6d2ae152020-09-02 13:11:20 +0530550func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530551 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
552 if msgLayer == nil {
553 logger.Error("Omci Msg layer could not be detected for CreateResponse")
554 return
555 }
556 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
557 if !msgOk {
558 logger.Error("Omci Msg layer could not be assigned for CreateResponse")
559 return
560 }
561 logger.Debugw("CreateResponse Data", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
562 if msgObj.Result != me.Success {
563 logger.Errorw("Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
564 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
565 return
566 }
567 if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
568 msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
569 // maybe we can use just the same eventName for different state transitions like "forward"
570 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
571 switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
572 case "Ieee8021PMapperServiceProfile":
573 { // let the FSM proceed ...
574 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
575 }
576 case "MacBridgePortConfigurationData":
577 { // let the FSM proceed ...
578 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
579 }
580 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint":
581 { // let aniConfig Multi-Id processing proceed by stopping the wait function
582 oFsm.omciMIdsResponseReceived <- true
mpagenko3dbcdd22020-07-22 07:38:45 +0000583 }
584 }
585 }
Himani Chawla4d908332020-08-31 12:30:20 +0530586}
587
Himani Chawla6d2ae152020-09-02 13:11:20 +0530588func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +0530589 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
590 if msgLayer == nil {
591 logger.Error("UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse")
592 return
593 }
594 msgObj, msgOk := msgLayer.(*omci.SetResponse)
595 if !msgOk {
596 logger.Error("UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse")
597 return
598 }
599 logger.Debugw("UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
600 if msgObj.Result != me.Success {
601 logger.Errorw("UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
602 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
603 return
604 }
605 if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
606 msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
607 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
608 // if, then something like:
609 //oFsm.pOnuDB.StoreMe(msgObj)
610
611 switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
612 case "TCont":
613 { // let the FSM proceed ...
614 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
615 }
616 case "PriorityQueue":
617 { // let the PrioQueue init proceed by stopping the wait function
618 oFsm.omciMIdsResponseReceived <- true
619 }
620 case "Ieee8021PMapperServiceProfile":
621 { // let the FSM proceed ...
622 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
623 }
624 }
625 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000626}
627
Himani Chawla6d2ae152020-09-02 13:11:20 +0530628func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(msg OmciMessage) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000629 logger.Debugw("Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
630 "msgType": msg.OmciMsg.MessageType})
631
632 switch msg.OmciMsg.MessageType {
633 case omci.CreateResponseType:
634 {
Himani Chawla4d908332020-08-31 12:30:20 +0530635 oFsm.handleOmciAniConfigCreateResponseMessage(msg)
636
mpagenko3dbcdd22020-07-22 07:38:45 +0000637 } //CreateResponseType
638 case omci.SetResponseType:
639 {
Himani Chawla4d908332020-08-31 12:30:20 +0530640 oFsm.handleOmciAniConfigSetResponseMessage(msg)
mpagenko3dbcdd22020-07-22 07:38:45 +0000641
mpagenko3dbcdd22020-07-22 07:38:45 +0000642 } //SetResponseType
643 default:
644 {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530645 logger.Errorw("uniPonAniConfigFsm - Rx OMCI unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
mpagenko3dbcdd22020-07-22 07:38:45 +0000646 return
647 }
648 }
649}
650
Himani Chawla6d2ae152020-09-02 13:11:20 +0530651func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000652 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
653 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530654 logger.Debugw("uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000655 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
656 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
657 "device-id": oFsm.pAdaptFsm.deviceID})
658 meParams := me.ParamData{
659 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
660 Attributes: me.AttributeValueMap{
661 "PortId": gemPortAttribs.gemPortID,
662 "TContPointer": oFsm.tcont0ID,
663 "Direction": gemPortAttribs.direction,
664 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
665 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
666 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
667 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
668 },
669 }
670 meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
671 oFsm.pAdaptFsm.commChan, meParams)
672 //accept also nil as (error) return value for writing to LastTx
673 // - this avoids misinterpretation of new received OMCI messages
674 oFsm.pOmciCC.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000675
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000676 //verify response
677 err := oFsm.waitforOmciResponse()
678 if err != nil {
679 logger.Errorw("GemNWCtp create failed, aborting AniConfig FSM!",
divyadesai4d299552020-08-18 07:13:49 +0000680 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +0530681 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000682 return
683 }
684 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +0000685
686 // if Config has been done for all GemPort instances let the FSM proceed
divyadesai4d299552020-08-18 07:13:49 +0000687 logger.Debugw("GemNWCtp create loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530688 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000689}
690
Himani Chawla6d2ae152020-09-02 13:11:20 +0530691func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000692 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
693 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530694 logger.Debugw("uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000695 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
696 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
697 "device-id": oFsm.pAdaptFsm.deviceID})
698 meParams := me.ParamData{
699 EntityID: gemPortAttribs.gemPortID,
700 Attributes: me.AttributeValueMap{
701 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
702 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
703 "ServiceProfilePointer": oFsm.mapperSP0ID,
704 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
705 "GalProfilePointer": galEthernetEID,
706 },
707 }
708 meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
709 oFsm.pAdaptFsm.commChan, meParams)
710 //accept also nil as (error) return value for writing to LastTx
711 // - this avoids misinterpretation of new received OMCI messages
712 oFsm.pOmciCC.pLastTxMeInstance = meInstance
mpagenko3dbcdd22020-07-22 07:38:45 +0000713
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000714 //verify response
715 err := oFsm.waitforOmciResponse()
716 if err != nil {
717 logger.Errorw("GemIwTp create failed, aborting AniConfig FSM!",
divyadesai4d299552020-08-18 07:13:49 +0000718 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +0530719 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000720 return
721 }
722 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +0000723
724 // if Config has been done for all GemPort instances let the FSM proceed
divyadesai4d299552020-08-18 07:13:49 +0000725 logger.Debugw("GemIwTp create loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530726 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000727}
728
Himani Chawla6d2ae152020-09-02 13:11:20 +0530729func (oFsm *uniPonAniConfigFsm) performSettingPQs() {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000730 const cu16StrictPrioWeight uint16 = 0xFFFF
731 //find all upstream PrioQueues related to this T-Cont
732 loQueueMap := ordered_map.NewOrderedMap()
733 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
734 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +0530735 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000736 //key does not yet exist
737 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
738 }
739 } else {
740 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
741 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000742 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000743
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000744 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
745 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
746 // complete chain is not valid, then some error should be thrown and configuration can be aborted
747 // or even be finished without correct SP/WRR setting
748
749 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
750 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
751 // even though its T-Cont seems to be wrong ...
752 loTrafficSchedulerEID := 0x8000
753 //for all found queues
754 iter := loQueueMap.IterFunc()
755 for kv, ok := iter(); ok; kv, ok = iter() {
756 queueIndex := (kv.Key).(uint16)
757 meParams := me.ParamData{
758 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +0530759 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000760 }
761 if (kv.Value).(uint16) == cu16StrictPrioWeight {
762 //StrictPrio indication
Himani Chawla6d2ae152020-09-02 13:11:20 +0530763 logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000764 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
765 "device-id": oFsm.pAdaptFsm.deviceID})
766 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
767 } else {
768 //WRR indication
Himani Chawla6d2ae152020-09-02 13:11:20 +0530769 logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000770 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
771 "Weight": kv.Value,
772 "device-id": oFsm.pAdaptFsm.deviceID})
773 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
774 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
775 }
776 meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(context.TODO(), ConstDefaultOmciTimeout, true,
777 oFsm.pAdaptFsm.commChan, meParams)
778 //accept also nil as (error) return value for writing to LastTx
779 // - this avoids misinterpretation of new received OMCI messages
780 oFsm.pOmciCC.pLastTxMeInstance = meInstance
781
782 //verify response
783 err := oFsm.waitforOmciResponse()
784 if err != nil {
785 logger.Errorw("PrioQueue set failed, aborting AniConfig FSM!",
divyadesai4d299552020-08-18 07:13:49 +0000786 log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +0530787 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000788 return
789 }
790
791 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
792 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
793 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
794 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
795
796 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +0000797
798 // if Config has been done for all PrioQueue instances let the FSM proceed
divyadesai4d299552020-08-18 07:13:49 +0000799 logger.Debugw("PrioQueue set loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530800 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +0000801}
802
Himani Chawla6d2ae152020-09-02 13:11:20 +0530803func (oFsm *uniPonAniConfigFsm) waitforOmciResponse() error {
mpagenko3dbcdd22020-07-22 07:38:45 +0000804 select {
Himani Chawla4d908332020-08-31 12:30:20 +0530805 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +0000806 // case <-ctx.Done():
807 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
808 case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
809 logger.Warnw("UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530810 return errors.New("uniPonAniConfigFsm multi entity timeout")
mpagenko3dbcdd22020-07-22 07:38:45 +0000811 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +0530812 if success {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530813 logger.Debug("uniPonAniConfigFsm multi entity response received")
mpagenko3dbcdd22020-07-22 07:38:45 +0000814 return nil
815 }
816 // should not happen so far
Himani Chawla6d2ae152020-09-02 13:11:20 +0530817 logger.Warnw("uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530818 return errors.New("uniPonAniConfigFsm multi entity responseError")
mpagenko3dbcdd22020-07-22 07:38:45 +0000819 }
820}