blob: 64d4c0b3f450113256fe0bfa45d8035874c9e13d [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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package avcfg provides anig and vlan configuration functionality
18package avcfg
mpagenko3dbcdd22020-07-22 07:38:45 +000019
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
mpagenko7d6bb022021-03-11 15:07:55 +000026 "sync"
mpagenko3dbcdd22020-07-22 07:38:45 +000027 "time"
28
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000029 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000031 "github.com/opencord/omci-lib-go/v2"
32 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000034
khenaidoo7d3c5582021-08-11 18:09:44 -040035 //ic "github.com/opencord/voltha-protos/v5/go/inter_container"
36 //"github.com/opencord/voltha-protos/v5/go/openflow_13"
37 //"github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000038 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
39 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
mpagenko3dbcdd22020-07-22 07:38:45 +000040)
41
mpagenko1cc3cb42020-07-27 15:24:38 +000042const (
43 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000044 aniEvStart = "aniEvStart"
45 aniEvStartConfig = "aniEvStartConfig"
46 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
47 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
48 aniEvRxTcontsResp = "aniEvRxTcontsResp"
49 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
50 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
51 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
52 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
53 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080054 aniEvWaitFlowRem = "aniEvWaitFlowRem"
55 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000056 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
57 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030058 aniEvRxRemTdResp = "aniEvRxRemTdResp"
mpagenko8b07c1b2020-11-26 10:36:31 +000059 aniEvRemTcontPath = "aniEvRemTcontPath"
60 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
61 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
62 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
63 aniEvTimeoutSimple = "aniEvTimeoutSimple"
64 aniEvTimeoutMids = "aniEvTimeoutMids"
65 aniEvReset = "aniEvReset"
66 aniEvRestart = "aniEvRestart"
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +000067 aniEvSkipOmciConfig = "aniEvSkipOmciConfig"
Mahir Gunyel9545be22021-07-04 15:53:16 -070068 aniEvRemGemDone = "aniEvRemGemDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000069)
70const (
71 // states of config PON ANI port FSM
72 aniStDisabled = "aniStDisabled"
73 aniStStarting = "aniStStarting"
74 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
75 aniStCreatingMBPCD = "aniStCreatingMBPCD"
76 aniStSettingTconts = "aniStSettingTconts"
77 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
78 aniStCreatingGemIWs = "aniStCreatingGemIWs"
79 aniStSettingPQs = "aniStSettingPQs"
80 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
81 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000082 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080083 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000084 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030085 aniStRemovingTD = "aniStRemovingTD"
mpagenko8b07c1b2020-11-26 10:36:31 +000086 aniStResetTcont = "aniStResetTcont"
87 aniStRemDot1PMapper = "aniStRemDot1PMapper"
88 aniStRemAniBPCD = "aniStRemAniBPCD"
89 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000090 aniStResetting = "aniStResetting"
91)
92
Girish Gowdra09e5f212021-09-30 16:28:36 -070093const (
94 bitTrafficSchedulerPtrSetPermitted = 0x0002 // Refer section 9.1.2 ONU-2G, table for "Quality of service (QoS) configuration flexibility" IE
95)
96
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000097// CAniFsmIdleState - TODO: add comment
98const CAniFsmIdleState = aniStConfigDone
99
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000100type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +0300101 gemPortID uint16
102 upQueueID uint16
103 downQueueID uint16
104 direction uint8
105 qosPolicy string
106 weight uint8
107 pbitString string
108 isMulticast bool
109 multicastGemID uint16
110 staticACL string
111 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000112}
113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000114//UniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
115type UniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000116 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117 pDeviceHandler cmn.IdeviceHandler
118 pOnuDeviceEntry cmn.IonuDeviceEntry
119 pOmciCC *cmn.OmciCC
120 pOnuUniPort *cmn.OnuUniPort
121 pUniTechProf *OnuUniTechProf
122 pOnuDB *devdb.OnuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800123 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000124 uniTpKey uniTP
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125 requestEvent cmn.OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000126 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000127 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000128 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530129 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000130 PAdaptFsm *cmn.AdapterFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000131 chSuccess chan<- uint8
132 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000133 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000134 chanSet bool
135 mapperSP0ID uint16
136 macBPCD0ID uint16
137 tcont0ID uint16
138 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000139 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000140 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000141 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000142 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000143 isWaitingForFlowDelete bool
144 waitFlowDeleteChannel chan bool
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700145 tcontSetBefore bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000146}
147
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000148//NewUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
149func NewUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort, apUniTechProf *OnuUniTechProf,
150 apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8, aRequestEvent cmn.OnuDeviceEvent, aName string,
151 apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, aCommChannel chan cmn.Message) *UniPonAniConfigFsm {
152 instFsm := &UniPonAniConfigFsm{
153 pDeviceHandler: apDeviceHandler,
154 pOnuDeviceEntry: apOnuDeviceEntry,
155 deviceID: apDeviceHandler.GetDeviceID(),
156 pOmciCC: apDevOmciCC,
157 pOnuUniPort: apUniPort,
158 pUniTechProf: apUniTechProf,
159 pOnuDB: apOnuDB,
160 techProfileID: aTechProfileID,
161 requestEvent: aRequestEvent,
162 chanSet: false,
163 tcontSetBefore: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000164 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000165 instFsm.uniTpKey = uniTP{uniID: apUniPort.UniID, tpID: aTechProfileID}
mpagenkobb47bc22021-04-20 13:29:09 +0000166 instFsm.waitFlowDeleteChannel = make(chan bool)
mpagenko8b07c1b2020-11-26 10:36:31 +0000167
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000168 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
169 if instFsm.PAdaptFsm == nil {
170 logger.Errorw(ctx, "UniPonAniConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000171 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000172 return nil
173 }
174
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000175 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000176 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000177 fsm.Events{
178
mpagenko1cc3cb42020-07-27 15:24:38 +0000179 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000180
181 //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 +0000182 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000183 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000184 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
185 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000186 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000187 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000188 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000189 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000190 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000191 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000192 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000193
mpagenko8b07c1b2020-11-26 10:36:31 +0000194 //for removing Gem related resources
195 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800196 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
197 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000198 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300199 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700200 {Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStRemDot1PMapper},
201 {Name: aniEvRemGemDone, Src: []string{aniStRemDot1PMapper}, Dst: aniStConfigDone},
202 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
203 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000204
205 //for removing TCONT related resources
206 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700207 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStConfigDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000208
209 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300210 aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000211 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000212 {Name: aniEvTimeoutMids, Src: []string{
213 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000214
mpagenko1cc3cb42020-07-27 15:24:38 +0000215 // exceptional treatment for all states except aniStResetting
216 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
217 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300218 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000219 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000220 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000221 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000222 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000223 },
224
225 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000226 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
228 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
229 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
230 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
231 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
232 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
233 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
234 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
235 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
236 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000237 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000238 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300239 ("enter_" + aniStRemovingTD): func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000240 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
241 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
242 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
243 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
244 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
245 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000246 },
247 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 if instFsm.PAdaptFsm.PFsm == nil {
249 logger.Errorw(ctx, "UniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000250 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000251 return nil
252 }
253
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 logger.Debugw(ctx, "UniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000255 return instFsm
256}
257
Himani Chawla6d2ae152020-09-02 13:11:20 +0530258//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259func (oFsm *UniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000260 oFsm.chSuccess = aChSuccess
261 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000262 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000263}
264
mpagenko7d6bb022021-03-11 15:07:55 +0000265//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000266func (oFsm *UniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandt12609a12022-03-25 13:23:25 +0000267 logger.Debugw(ctx, "CancelProcessing entered", log.Fields{"device-id": oFsm.deviceID})
mpagenko73143992021-04-09 15:17:10 +0000268 //early indication about started reset processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000269 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000270 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000271 oFsm.mutexIsAwaitingResponse.Lock()
272 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000273 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000274 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
275 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
276 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000277 //use channel to indicate that the response waiting shall be aborted
278 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000279 } else {
280 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000281 }
mpagenkocf48e452021-04-23 09:23:00 +0000282
283 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000284 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000285 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000286 //use channel to indicate that the response waiting shall be aborted
287 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000288 } else {
289 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000290 }
mpagenkocf48e452021-04-23 09:23:00 +0000291
mpagenko7d6bb022021-03-11 15:07:55 +0000292 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000293 PAdaptFsm := oFsm.PAdaptFsm
294 if PAdaptFsm != nil {
mpagenko7d6bb022021-03-11 15:07:55 +0000295 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000296 go func(aPAFsm *cmn.AdapterFsm) {
297 if aPAFsm.PFsm != nil {
298 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
mpagenko7d6bb022021-03-11 15:07:55 +0000299 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000300 }(PAdaptFsm)
mpagenko7d6bb022021-03-11 15:07:55 +0000301 }
mpagenko73143992021-04-09 15:17:10 +0000302
mpagenko45cc6a32021-07-23 10:06:57 +0000303 // possible access conflicts on internal data by next needed data clearance
304 // are avoided by using mutexTPState also from within clearAniSideConfig
305 // do not try to lock TpProcMutex here as done in previous code version
306 // as it may result in deadlock situations (as observed at soft-reboot handling where
307 // TpProcMutex is already locked by some ongoing TechProfile config/removal processing
mpagenko73143992021-04-09 15:17:10 +0000308 //remove all TechProf related internal data to allow for new configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000309 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.UniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000310}
311
Mahir Gunyel6781f962021-05-16 23:30:08 -0700312//nolint: gocyclo
313//TODO:visit here for refactoring for gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000314func (oFsm *UniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *cmn.AdapterFsm) {
315 if aPAFsm != nil && aPAFsm.PFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700316 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000317 oFsm.mapperSP0ID, err = cmn.GenerateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.techProfileID))
Mahir Gunyel6781f962021-05-16 23:30:08 -0700318 if err != nil {
319 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
320 "techProfileID": oFsm.techProfileID, "error": err})
321 return
322 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000323 oFsm.macBPCD0ID, err = cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.techProfileID))
Mahir Gunyel6781f962021-05-16 23:30:08 -0700324 if err != nil {
325 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
326 "techProfileID": oFsm.techProfileID, "error": err})
327 return
328 }
329 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
330 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000331 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "techProfileID": oFsm.techProfileID})
332 if oFsm.pOnuDeviceEntry == nil {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700333 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800334 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530335 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000336 tcontInstID, tcontAlreadyExist, err := oFsm.pOnuDeviceEntry.AllocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700337 if err != nil {
338 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700339 //reset the state machine to enable usage on subsequent requests
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000340 _ = aPAFsm.PFsm.Event(aniEvReset)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700341 return
342 }
343 oFsm.tcont0ID = tcontInstID
344 oFsm.tcontSetBefore = tcontAlreadyExist
345 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
346 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
347 "tcontAlreadyExist": tcontAlreadyExist,
348 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800349
350 // Access critical state with lock
mpagenko3ce9fa02021-07-28 13:26:54 +0000351 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000352 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
353 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko3ce9fa02021-07-28 13:26:54 +0000354 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800355
Himani Chawla26e555c2020-08-31 12:30:20 +0530356 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800357 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300358 loGemPortAttribs := ponAniGemPortAttribs{}
359
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
361
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000362 if queueInstKeys := oFsm.pOnuDB.GetSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530363
364 loGemPortAttribs.gemPortID = gemEntry.gemPortID
365 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
366 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
367 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
368 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
369
370 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.UniID,
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
373 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
374 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.UniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
Himani Chawla26e555c2020-08-31 12:30:20 +0530376
377 usQueueFound := false
378 dsQueueFound := false
379 for _, mgmtEntityID := range queueInstKeys {
380 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000381 returnVal := meAttributes[me.PriorityQueue_RelatedPort]
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000383 if relatedPort, err := oFsm.pOnuDB.GetUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530384 if relatedPort == usQrelPortMask {
385 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000387 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 usQueueFound = true
389 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
390 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000392 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 dsQueueFound = true
394 }
395 if usQueueFound && dsQueueFound {
396 break
397 }
398 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000399 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 }
401 } else {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000402 logger.Warnw(ctx, "PrioQueue.RelatedPort not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530403 }
404 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000405 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000406 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530407 }
408 }
409 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000410 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530411 }
412 loGemPortAttribs.direction = gemEntry.direction
413 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
414 loGemPortAttribs.weight = gemEntry.queueWeight
415 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300416
ozgecanetsia4b232302020-11-11 10:58:10 +0300417 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300418 //TODO this might effectively ignore the for loop starting at line 316
419 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300420 loGemPortAttribs.isMulticast = true
421 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
422 loGemPortAttribs.staticACL = gemEntry.staticACL
423 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530424
dbainbri4d3a0dc2020-12-02 00:33:42 +0000425 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300426 "gemPortID": loGemPortAttribs.gemPortID,
427 "isMulticast": loGemPortAttribs.isMulticast,
428 "multicastGemID": loGemPortAttribs.multicastGemID,
429 "staticACL": loGemPortAttribs.staticACL,
430 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000431 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300432 })
433
434 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000435 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300436 "gemPortID": loGemPortAttribs.gemPortID,
437 "upQueueID": loGemPortAttribs.upQueueID,
438 "downQueueID": loGemPortAttribs.downQueueID,
439 "pbitString": loGemPortAttribs.pbitString,
440 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000441 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300442 })
443 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530444
445 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
446 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000447 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
448 _ = aPAFsm.PFsm.Event(aniEvStartConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000449 } else {
450 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000451 _ = aPAFsm.PFsm.Event(aniEvSkipOmciConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000452 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530453 }
454}
455
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456func (oFsm *UniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000457 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000458 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000459 // in case the used channel is not yet defined (can be re-used after restarts)
460 if oFsm.omciMIdsResponseReceived == nil {
461 oFsm.omciMIdsResponseReceived = make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000462 logger.Debug(ctx, "UniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000463 } else {
464 // as we may 're-use' this instance of FSM and the connected channel
465 // make sure there is no 'lingering' request in the already existing channel:
466 // (simple loop sufficient as we are the only receiver)
467 for len(oFsm.omciMIdsResponseReceived) > 0 {
468 <-oFsm.omciMIdsResponseReceived
469 }
470 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000471 //ensure internal slices are empty (which might be set from previous run) - release memory
472 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000473 oFsm.mutexIsAwaitingResponse.Lock()
474 //reset the canceled state possibly existing from previous reset
475 oFsm.isCanceled = false
476 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000477
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000478 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000480
481 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000483 if pConfigAniStateAFsm != nil {
484 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000485 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000486
mpagenko3dbcdd22020-07-22 07:38:45 +0000487 }
488}
489
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490func (oFsm *UniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
491 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000492 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000494 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000495 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 meInstance, err := oFsm.pOmciCC.SendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
497 oFsm.mapperSP0ID, oFsm.PAdaptFsm.CommChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300498 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000499 logger.Errorw(ctx, "Dot1PMapper create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300500 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000501 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300502 if pConfigAniStateAFsm != nil {
503 oFsm.mutexPLastTxMeInstance.Unlock()
504 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 go func(aPAFsm *cmn.AdapterFsm) {
506 if aPAFsm != nil && aPAFsm.PFsm != nil {
507 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300508 }
509 }(pConfigAniStateAFsm)
510 return
511 }
512 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000513 //accept also nil as (error) return value for writing to LastTx
514 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000515 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300516 oFsm.mutexPLastTxMeInstance.Unlock()
517
mpagenko3dbcdd22020-07-22 07:38:45 +0000518}
519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000520func (oFsm *UniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
521 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000522 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
523 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
525 bridgePtr := cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
mpagenko3dbcdd22020-07-22 07:38:45 +0000526 meParams := me.ParamData{
527 EntityID: oFsm.macBPCD0ID,
528 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000529 me.MacBridgePortConfigurationData_BridgeIdPointer: bridgePtr,
530 me.MacBridgePortConfigurationData_PortNum: 0xFF, //fixed unique ANI side indication
531 me.MacBridgePortConfigurationData_TpType: 3, //for .1PMapper
532 me.MacBridgePortConfigurationData_TpPointer: oFsm.mapperSP0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000533 },
534 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000535 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000536 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
537 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300538 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300540 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000541 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300542 if pConfigAniStateAFsm != nil {
543 oFsm.mutexPLastTxMeInstance.Unlock()
544 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000545 go func(aPAFsm *cmn.AdapterFsm) {
546 if aPAFsm != nil && aPAFsm.PFsm != nil {
547 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300548 }
549 }(pConfigAniStateAFsm)
550 return
551 }
552 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000553 //accept also nil as (error) return value for writing to LastTx
554 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000555 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300556 oFsm.mutexPLastTxMeInstance.Unlock()
557
mpagenko3dbcdd22020-07-22 07:38:45 +0000558}
559
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560func (oFsm *UniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
561 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000562 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
563 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700565 "tcontExist": oFsm.tcontSetBefore})
566 //If tcont was set before, then no need to set it again. Let state machine to proceed.
567 if oFsm.tcontSetBefore {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000568 go func(aPAFsm *cmn.AdapterFsm) {
569 if aPAFsm != nil && aPAFsm.PFsm != nil {
570 _ = aPAFsm.PFsm.Event(aniEvRxTcontsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700571 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700573 return
574 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000575 meParams := me.ParamData{
576 EntityID: oFsm.tcont0ID,
577 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000578 me.TCont_AllocId: oFsm.alloc0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000579 },
580 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000581 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000582 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
583 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300584 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000585 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300586 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000587 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300588 if pConfigAniStateAFsm != nil {
589 oFsm.mutexPLastTxMeInstance.Unlock()
590 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 go func(aPAFsm *cmn.AdapterFsm) {
592 if aPAFsm != nil && aPAFsm.PFsm != nil {
593 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300594 }
595 }(pConfigAniStateAFsm)
596 return
597 }
598 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000599 //accept also nil as (error) return value for writing to LastTx
600 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000601 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300602 oFsm.mutexPLastTxMeInstance.Unlock()
603
mpagenko3dbcdd22020-07-22 07:38:45 +0000604}
605
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606func (oFsm *UniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
607 logger.Debugw(ctx, "UniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
608 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000609 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000610}
611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000612func (oFsm *UniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
613 logger.Debugw(ctx, "UniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
614 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000616}
617
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618func (oFsm *UniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
619 logger.Debugw(ctx, "UniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000620 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000622}
623
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000624func (oFsm *UniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300625
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000626 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000627 "toGemIw": 1024, /* cmp above */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000628 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000629
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000630 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000631 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000632 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000633
mpagenko3dbcdd22020-07-22 07:38:45 +0000634 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000635 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530636 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000637 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000638
639 //assign the GemPorts according to the configured Prio
640 var loPrioGemPortArray [8]uint16
641 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300642 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000643 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300644 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
645 "prioString": gemPortAttribs.pbitString})
646 continue
647 }
648 if gemPortAttribs.pbitString == "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000649 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300650 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
651 "prioString": gemPortAttribs.pbitString})
652 continue
653 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000654 for i := 0; i < 8; i++ {
655 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
656 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
657 if prio == 1 { // Check this p-bit is set
658 if loPrioGemPortArray[i] == 0 {
659 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
660 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000662 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000663 "SetGemPort": loPrioGemPortArray[i]})
664 }
665 }
666 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000667 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000668 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000669 "prioString": gemPortAttribs.pbitString, "position": i})
670 }
671
672 }
673 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300674
ozgecanetsia4b232302020-11-11 10:58:10 +0300675 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530676 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300677 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530678 if value != 0 {
679 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530680 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000682 "for Prio": index,
683 "IwPtr": strconv.FormatInt(int64(value), 16),
684 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300685 } else {
686 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000687 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
688 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300689 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530690 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000691 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300692 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000693 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
694 // but except for processing effort does not really harm - left to keep changes low
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000695 meParams.Attributes[me.Ieee8021PMapperServiceProfile_TpPointer] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530696
697 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000699 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300700 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
701 // this reset needs to be performed only if the tech profile provides upstream gem ports but no priority is set
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000702 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000703 //pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300704 //if pConfigAniStateAFsm != nil {
705 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000706 // go func(aPAFsm *cmn.AdapterFsm) {
707 // if aPAFsm != nil && aPAFsm.PFsm != nil {
708 // _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300709 // }
710 // }(pConfigAniStateAFsm)
711 //}
712 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000713 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000714 if pConfigAniStateAFsm != nil {
715 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000716 go func(aPAFsm *cmn.AdapterFsm) {
717 if aPAFsm != nil && aPAFsm.PFsm != nil {
718 _ = aPAFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000719 }
720 }(pConfigAniStateAFsm)
721 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300722 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000723 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000724 meInstance, err := oFsm.pOmciCC.SendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
725 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300726 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000727 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300728 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300730 if pConfigAniStateAFsm != nil {
731 oFsm.mutexPLastTxMeInstance.Unlock()
732 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000733 go func(aPAFsm *cmn.AdapterFsm) {
734 if aPAFsm != nil && aPAFsm.PFsm != nil {
735 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300736 }
737 }(pConfigAniStateAFsm)
738 return
739 }
740 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300741 //accept also nil as (error) return value for writing to LastTx
742 // - this avoids misinterpretation of new received OMCI messages
743 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300744 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000745 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000746}
747
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000748func (oFsm *UniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
749 logger.Debugw(ctx, "UniPonAniConfigFsm ani config done", log.Fields{
750 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000751 //store that the UNI related techProfile processing is done for the given Profile and Uni
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000752 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
753 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000754 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000755 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000756 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
757 // but only in case the techProfile was configured (not deleted)
758 if oFsm.requestEventOffset == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000759 go oFsm.pDeviceHandler.VerifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000760 }
761 } else {
762 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000763 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000764 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000765 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000766 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000767 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
768 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000769 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000770 }
mpagenko01e726e2020-10-23 09:45:29 +0000771
772 //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 +0000773}
774
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000775func (oFsm *UniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000776 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
777 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000778 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
779 select {
780 case <-oFsm.waitFlowDeleteChannel:
781 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
782 default:
783 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000784
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785 uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.UniID)
786 if uniVlanConfigFsm != nil {
mpagenko3ce9fa02021-07-28 13:26:54 +0000787 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000788 if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000789 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000790 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000791 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000792 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000793 if pConfigAniStateAFsm != nil {
794 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000795 go func(aPAFsm *cmn.AdapterFsm) {
796 if aPAFsm != nil && aPAFsm.PFsm != nil {
797 _ = aPAFsm.PFsm.Event(aniEvWaitFlowRem)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000798 }
799 }(pConfigAniStateAFsm)
800 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000801 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000802 }
803 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800804 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000805 } else {
806 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
807 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800808 }
809
mpagenko3ce9fa02021-07-28 13:26:54 +0000810 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000811 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000812 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000813 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
815 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000816 "GemIwTp-entity-id": loGemPortID})
817 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
818
819 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000820 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821 meInstance, err := oFsm.pOmciCC.SendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
822 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300823 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 logger.Errorw(ctx, "GemIWTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300825 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300827 if pConfigAniStateAFsm != nil {
828 oFsm.mutexPLastTxMeInstance.Unlock()
829 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000830 go func(aPAFsm *cmn.AdapterFsm) {
831 if aPAFsm != nil && aPAFsm.PFsm != nil {
832 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300833 }
834 }(pConfigAniStateAFsm)
835 return
836 }
837 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000838 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300839 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000840}
841
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842func (oFsm *UniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
mpagenkobb47bc22021-04-20 13:29:09 +0000843 oFsm.mutexIsAwaitingResponse.Lock()
844 oFsm.isWaitingForFlowDelete = true
845 oFsm.mutexIsAwaitingResponse.Unlock()
846 select {
847 // maybe be also some outside cancel (but no context modeled for the moment ...)
848 // case <-ctx.Done():
849 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000850 case <-time.After(2 * oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //give flow processing enough time to finish (but try to be less than rwCore flow timeouts)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 logger.Warnw(ctx, "UniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
852 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000853 oFsm.mutexIsAwaitingResponse.Lock()
854 oFsm.isWaitingForFlowDelete = false
855 oFsm.mutexIsAwaitingResponse.Unlock()
856 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000858 if pConfigAniStateAFsm != nil {
859 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000860 go func(aPAFsm *cmn.AdapterFsm) {
861 if aPAFsm != nil && aPAFsm.PFsm != nil {
862 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000863 }
864 }(pConfigAniStateAFsm)
865 } else {
866 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000867 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000868 }
869 return
870
871 case success := <-oFsm.waitFlowDeleteChannel:
872 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 logger.Debugw(ctx, "UniPonAniConfigFsm flow removed info received", log.Fields{
874 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000875 oFsm.mutexIsAwaitingResponse.Lock()
876 oFsm.isWaitingForFlowDelete = false
877 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000879 if pConfigAniStateAFsm != nil {
880 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000881 go func(aPAFsm *cmn.AdapterFsm) {
882 if aPAFsm != nil && aPAFsm.PFsm != nil {
883 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000884 }
885 }(pConfigAniStateAFsm)
886 } else {
887 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000889 }
890 return
891 }
892 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 logger.Debugw(ctx, "UniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
894 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000895 oFsm.mutexIsAwaitingResponse.Lock()
896 oFsm.isWaitingForFlowDelete = false
897 oFsm.mutexIsAwaitingResponse.Unlock()
898 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000899 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000900 if pConfigAniStateAFsm != nil {
901 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000902 go func(aPAFsm *cmn.AdapterFsm) {
903 if aPAFsm != nil && aPAFsm.PFsm != nil {
904 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenkobb47bc22021-04-20 13:29:09 +0000905 }
906 }(pConfigAniStateAFsm)
907 }
908 return
909 }
910}
911
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912func (oFsm *UniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000913 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000914 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000915 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000916 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
917 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000918 "GemNCTP-entity-id": loGemPortID})
919 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000920 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000921 meInstance, err := oFsm.pOmciCC.SendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
922 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300923 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000924 logger.Errorw(ctx, "GemNCTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300925 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000926 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300927 if pConfigAniStateAFsm != nil {
928 oFsm.mutexPLastTxMeInstance.Unlock()
929 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 go func(aPAFsm *cmn.AdapterFsm) {
931 if aPAFsm != nil && aPAFsm.PFsm != nil {
932 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300933 }
934 }(pConfigAniStateAFsm)
935 return
936 }
937 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000938 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000939 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300940
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800941 // Mark the gem port to be removed for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000942 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
943 if OnuMetricsManager != nil {
944 OnuMetricsManager.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800945 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000946}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000947func (oFsm *UniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000948 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300949 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000950 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000951 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
952 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300953 "TD-entity-id": loGemPortID})
954
955 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 meInstance, err := oFsm.pOmciCC.SendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
957 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300958
959 if err != nil {
960 logger.Errorw(ctx, "TD delete failed - proceed fsm",
961 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000962 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300963 if pConfigAniStateAFsm != nil {
964 oFsm.mutexPLastTxMeInstance.Unlock()
965 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000966 go func(aPAFsm *cmn.AdapterFsm) {
967 if aPAFsm != nil && aPAFsm.PFsm != nil {
968 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300969 }
970 }(pConfigAniStateAFsm)
971 return
972 }
973 }
974 oFsm.pLastTxMeInstance = meInstance
975 oFsm.mutexPLastTxMeInstance.Unlock()
976}
mpagenko8b07c1b2020-11-26 10:36:31 +0000977
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978func (oFsm *UniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
979 logger.Debugw(ctx, "UniPonAniConfigFsm - start resetting the TCont", log.Fields{
980 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000981
982 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
983 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
984 meParams := me.ParamData{
985 EntityID: oFsm.tcont0ID,
986 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000987 me.TCont_AllocId: cmn.UnusedTcontAllocID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000988 },
989 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000990 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000991 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
992 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300993 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000994 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300995 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000996 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300997 if pConfigAniStateAFsm != nil {
998 oFsm.mutexPLastTxMeInstance.Unlock()
999 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001000 go func(aPAFsm *cmn.AdapterFsm) {
1001 if aPAFsm != nil && aPAFsm.PFsm != nil {
1002 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001003 }
1004 }(pConfigAniStateAFsm)
1005 return
1006 }
1007 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001008 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001009 oFsm.mutexPLastTxMeInstance.Unlock()
1010
mpagenko8b07c1b2020-11-26 10:36:31 +00001011}
1012
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001013func (oFsm *UniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
1014 logger.Debugw(ctx, "UniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
1015 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Mahir Gunyel9545be22021-07-04 15:53:16 -07001016 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1017 unicastGemCount := 0
1018 for _, gemEntry := range mapGemPortParams {
1019 if !gemEntry.isMulticast {
1020 unicastGemCount++
1021 }
1022 }
1023 if unicastGemCount > 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001024 logger.Debugw(ctx, "UniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1025 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1026 pConfigAniStateAFsm := oFsm.PAdaptFsm
Mahir Gunyel9545be22021-07-04 15:53:16 -07001027 if pConfigAniStateAFsm != nil {
1028 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 go func(aPAFsm *cmn.AdapterFsm) {
1030 if aPAFsm != nil && aPAFsm.PFsm != nil {
1031 _ = aPAFsm.PFsm.Event(aniEvRemGemDone)
Mahir Gunyel9545be22021-07-04 15:53:16 -07001032 }
1033 }(pConfigAniStateAFsm)
1034 return
1035 }
1036 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001037 logger.Debugw(ctx, "UniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1038 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001039
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001040 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 meInstance, err := oFsm.pOmciCC.SendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1042 oFsm.PAdaptFsm.CommChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001043 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001045 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001046 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001047 if pConfigAniStateAFsm != nil {
1048 oFsm.mutexPLastTxMeInstance.Unlock()
1049 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001050 go func(aPAFsm *cmn.AdapterFsm) {
1051 if aPAFsm != nil && aPAFsm.PFsm != nil {
1052 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001053 }
1054 }(pConfigAniStateAFsm)
1055 return
1056 }
1057 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001058 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001059 oFsm.mutexPLastTxMeInstance.Unlock()
1060
mpagenko8b07c1b2020-11-26 10:36:31 +00001061}
1062
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001063func (oFsm *UniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1064 logger.Debugw(ctx, "UniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
1065 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001066
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001067 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001068 meInstance, err := oFsm.pOmciCC.SendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1069 oFsm.PAdaptFsm.CommChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001070 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001071 logger.Errorw(ctx, "MBPConfigData delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001072 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001074 if pConfigAniStateAFsm != nil {
1075 oFsm.mutexPLastTxMeInstance.Unlock()
1076 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001077 go func(aPAFsm *cmn.AdapterFsm) {
1078 if aPAFsm != nil && aPAFsm.PFsm != nil {
1079 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001080 }
1081 }(pConfigAniStateAFsm)
1082 return
1083 }
1084 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001085 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001086 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001087}
1088
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001089func (oFsm *UniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1090 logger.Debugw(ctx, "UniPonAniConfigFsm ani removal done", log.Fields{
1091 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001092 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001093 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001094 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001095 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001096 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001097 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1098 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001099 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001100 }
1101
1102 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001103 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko8b07c1b2020-11-26 10:36:31 +00001104 if pConfigAniStateAFsm != nil {
1105 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001106 go func(aPAFsm *cmn.AdapterFsm) {
1107 if aPAFsm != nil && aPAFsm.PFsm != nil {
1108 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenko8b07c1b2020-11-26 10:36:31 +00001109 }
1110 }(pConfigAniStateAFsm)
1111 }
1112}
1113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001114func (oFsm *UniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1115 logger.Debugw(ctx, "UniPonAniConfigFsm resetting", log.Fields{
1116 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001117
mpagenko45cc6a32021-07-23 10:06:57 +00001118 if oFsm.isChanSet() {
1119 // indicate processing error to the caller (in case there was still some open request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120 logger.Debugw(ctx, "UniPonAniConfigFsm processingError on channel", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001121 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1122 //use non-blocking channel send to avoid blocking because of non-existing receiver
1123 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1124 select {
1125 case oFsm.chSuccess <- 0:
1126 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 logger.Debugw(ctx, "UniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001128 "device-id": oFsm.deviceID})
1129 }
1130 oFsm.setChanSet(false) //reset the internal channel state
1131 }
1132
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001133 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +00001134 if pConfigAniStateAFsm != nil {
1135 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001136 fsmAbortMsg := cmn.Message{
1137 Type: cmn.TestMsg,
1138 Data: cmn.TestMessage{
1139 TestMessageVal: cmn.AbortMessageProcessing,
mpagenko3dbcdd22020-07-22 07:38:45 +00001140 },
1141 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001142 pConfigAniStateAFsm.CommChan <- fsmAbortMsg
mpagenko3dbcdd22020-07-22 07:38:45 +00001143
1144 //try to restart the FSM to 'disabled', decouple event transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001145 go func(aPAFsm *cmn.AdapterFsm) {
1146 if aPAFsm != nil && aPAFsm.PFsm != nil {
1147 _ = aPAFsm.PFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001148 }
1149 }(pConfigAniStateAFsm)
1150 }
1151}
1152
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001153func (oFsm *UniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1154 logger.Debugw(ctx, "UniPonAniConfigFsm enters disabled state", log.Fields{
1155 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001156 oFsm.mutexPLastTxMeInstance.Lock()
1157 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001158 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001159}
1160
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001161func (oFsm *UniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1162 logger.Debugw(ctx, "Start UniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001163loop:
1164 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001165 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001166 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001167 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001168 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301169 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001170 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301171 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001172 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301173 break loop
1174 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301176
1177 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 case cmn.TestMsg:
1179 msg, _ := message.Data.(cmn.TestMessage)
1180 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001181 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001182 break loop
1183 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001184 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001185 case cmn.OMCI:
1186 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001187 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301188 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001189 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301190 "message.Type": message.Type})
1191 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001192
Himani Chawla4d908332020-08-31 12:30:20 +05301193 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001194 logger.Infow(ctx, "End UniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301195}
1196
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001197func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301198 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1199 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001200 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001201 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301202 return
1203 }
1204 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1205 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001207 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301208 return
1209 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001210 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001211 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1212 //if the result is ok or Instance already exists (latest needed at least as long as we do not clear the OMCI techProfile data)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001213 oFsm.mutexPLastTxMeInstance.RLock()
1214 if oFsm.pLastTxMeInstance != nil {
1215 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1216 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1217 // maybe we can use just the same eventName for different state transitions like "forward"
1218 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1219 switch oFsm.pLastTxMeInstance.GetName() {
1220 case "Ieee8021PMapperServiceProfile":
1221 { // let the FSM proceed ...
1222 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001223 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapCResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001224 }
1225 case "MacBridgePortConfigurationData":
1226 { // let the FSM proceed ...
1227 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxMbpcdResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001229 }
1230 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1231 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1232 oFsm.mutexPLastTxMeInstance.RUnlock()
1233 oFsm.omciMIdsResponseReceived <- true
1234 }
1235 default:
1236 {
1237 oFsm.mutexPLastTxMeInstance.RUnlock()
1238 logger.Warnw(ctx, "Unsupported ME name received!",
1239 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1240 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001241 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001242 } else {
1243 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001244 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001245 } else {
1246 oFsm.mutexPLastTxMeInstance.RUnlock()
1247 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001248 }
1249 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001250 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1251 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301252 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1253 return
1254 }
Himani Chawla4d908332020-08-31 12:30:20 +05301255}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001256func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
Mahir Gunyel01034b62021-06-29 11:25:09 -07001257 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1258 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1259 oFsm.mutexPLastTxMeInstance.RLock()
1260 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1261 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1262 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1263 switch oFsm.pLastTxMeInstance.GetName() {
1264 case "TCont":
1265 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1266 //We should revert DB
1267 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1268 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1269 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001270 if oFsm.pOnuDeviceEntry != nil {
1271 oFsm.pOnuDeviceEntry.FreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001272 } else {
1273 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1274 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1275 }
1276 }
1277 default:
1278 logger.Warnw(ctx, "Unsupported ME name received with error!",
1279 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1280 }
1281 }
1282}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301284 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1285 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001287 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301288 return
1289 }
1290 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1291 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001293 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301294 return
1295 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001296 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301297 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001298 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001299 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301300 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001301
Mahir Gunyel01034b62021-06-29 11:25:09 -07001302 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301303 return
1304 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001305 oFsm.mutexPLastTxMeInstance.RLock()
1306 if oFsm.pLastTxMeInstance != nil {
1307 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1308 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1309 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1310 // if, then something like:
1311 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301312
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001313 switch oFsm.pLastTxMeInstance.GetName() {
1314 case "TCont":
1315 { // let the FSM proceed ...
1316 oFsm.mutexPLastTxMeInstance.RUnlock()
1317 if oFsm.requestEventOffset == 0 { //from TCont config request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxTcontsResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001319 } else { // from T-Cont reset request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001320 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxResetTcontResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001321 }
1322 }
1323 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1324 { // let the PrioQueue init proceed by stopping the wait function
1325 oFsm.mutexPLastTxMeInstance.RUnlock()
1326 oFsm.omciMIdsResponseReceived <- true
1327 }
1328 case "Ieee8021PMapperServiceProfile":
1329 { // let the FSM proceed ...
1330 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001331 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001332 }
1333 default:
1334 {
1335 oFsm.mutexPLastTxMeInstance.RUnlock()
1336 logger.Warnw(ctx, "Unsupported ME name received!",
1337 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001338 }
Himani Chawla4d908332020-08-31 12:30:20 +05301339 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001340 } else {
1341 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301342 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001343 } else {
1344 oFsm.mutexPLastTxMeInstance.RUnlock()
1345 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301346 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001347}
1348
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001349func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001350 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1351 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001352 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001353 log.Fields{"device-id": oFsm.deviceID})
1354 return
1355 }
1356 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1357 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001358 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001359 log.Fields{"device-id": oFsm.deviceID})
1360 return
1361 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001363 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001364 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001365 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1366 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1367 // store error for mgmt display?
1368 return
1369 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001370 oFsm.mutexPLastTxMeInstance.RLock()
1371 if oFsm.pLastTxMeInstance != nil {
1372 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1373 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1374 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1375 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001376
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001377 switch oFsm.pLastTxMeInstance.GetName() {
1378 case "GemInterworkingTerminationPoint":
1379 { // let the FSM proceed ...
1380 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemiwResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001382 }
1383 case "GemPortNetworkCtp":
1384 { // let the FSM proceed ...
1385 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemntpResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001387 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001388 case "TrafficDescriptor":
1389 { // let the FSM proceed ...
1390 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemTdResp)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001392 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001393 case "Ieee8021PMapperServiceProfile":
1394 { // let the FSM proceed ...
1395 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001396 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRem1pMapperResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001397 }
1398 case "MacBridgePortConfigurationData":
1399 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1400 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001401 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemAniBPCDResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001402 }
1403 default:
1404 {
1405 oFsm.mutexPLastTxMeInstance.RUnlock()
1406 logger.Warnw(ctx, "Unsupported ME name received!",
1407 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1408 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001409 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001410 } else {
1411 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001412 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001413 } else {
1414 oFsm.mutexPLastTxMeInstance.RUnlock()
1415 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001416 }
1417}
1418
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001419func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001420 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001421 "msgType": msg.OmciMsg.MessageType})
1422
1423 switch msg.OmciMsg.MessageType {
1424 case omci.CreateResponseType:
1425 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301427
mpagenko3dbcdd22020-07-22 07:38:45 +00001428 } //CreateResponseType
1429 case omci.SetResponseType:
1430 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001432
mpagenko3dbcdd22020-07-22 07:38:45 +00001433 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001434 case omci.DeleteResponseType:
1435 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001437
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001438 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001439 default:
1440 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001441 logger.Errorw(ctx, "UniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001442 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001443 return
1444 }
1445 }
1446}
1447
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001448func (oFsm *UniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001449 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1450 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001451 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001452 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1453 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001454 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001455 meParams := me.ParamData{
1456 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1457 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001458 me.GemPortNetworkCtp_PortId: gemPortAttribs.gemPortID,
1459 me.GemPortNetworkCtp_TContPointer: oFsm.tcont0ID,
1460 me.GemPortNetworkCtp_Direction: gemPortAttribs.direction,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001461 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1462 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001463 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1464 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: gemPortAttribs.downQueueID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001465 },
1466 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001467 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468 meInstance, err := oFsm.pOmciCC.SendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1469 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001470 if err != nil {
1471 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001472 logger.Errorw(ctx, "GemNCTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001473 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001474 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001475 return
1476 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001477 //accept also nil as (error) return value for writing to LastTx
1478 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001479 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001480 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001481 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001482 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001483 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001485 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001487 return
1488 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001489 // Mark the gem port to be added for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001490 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
1491 if OnuMetricsManager != nil {
1492 OnuMetricsManager.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001493 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001494 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001495
1496 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001499}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500func (oFsm *UniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001501 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1502 if gemPortAttribs.isMulticast {
1503 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1504 return true
1505 }
1506 }
1507 return false
1508}
mpagenko3dbcdd22020-07-22 07:38:45 +00001509
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001510func (oFsm *UniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001511 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1512 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001513 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001514 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1515 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001516 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001517
ozgecanetsia4b232302020-11-11 10:58:10 +03001518 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1519 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001520
1521 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001522 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001523 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001524 me.MulticastGemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.multicastGemID,
1525 me.MulticastGemInterworkingTerminationPoint_InterworkingOption: 0, // Don't Care
1526 me.MulticastGemInterworkingTerminationPoint_ServiceProfilePointer: 0, // Don't Care
1527 me.MulticastGemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001528 },
1529 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001530 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1531 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1532 continue
1533 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001534 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001535 meInstance, err := oFsm.pOmciCC.SendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1536 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001537 if err != nil {
1538 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001539 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001540 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001541 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001542 return
1543
1544 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001545 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001546 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001547 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001548 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001549 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001550 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001551 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001552 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001553 return
1554 }
1555 ipv4MulticastTable := make([]uint8, 12)
1556 //Gem Port ID
1557 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1558 //Secondary Key
1559 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1560 // Multicast IP range start This is the 224.0.0.1 address
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001561 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], cmn.IPToInt32(net.IPv4(224, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001562 // MulticastIp range stop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001563 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001564
1565 meIPV4MCTableParams := me.ParamData{
1566 EntityID: gemPortAttribs.multicastGemID,
1567 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001568 me.MulticastGemInterworkingTerminationPoint_Ipv4MulticastAddressTable: ipv4MulticastTable,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001569 },
1570 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001571 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001572 meIPV4MCTableInstance, err := oFsm.pOmciCC.SendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1573 true, oFsm.PAdaptFsm.CommChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001574 if err != nil {
1575 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001576 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001577 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001578 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001579 return
1580 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001581 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001582 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001583
1584 } else {
1585 meParams := me.ParamData{
1586 EntityID: gemPortAttribs.gemPortID,
1587 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001588 me.GemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.gemPortID, //same as EntityID, see above
1589 me.GemInterworkingTerminationPoint_InterworkingOption: 5, //fixed model:: G.998 .1pMapper
1590 me.GemInterworkingTerminationPoint_ServiceProfilePointer: oFsm.mapperSP0ID,
1591 me.GemInterworkingTerminationPoint_InterworkingTerminationPointPointer: 0, //not used with .1PMapper Mac bridge
1592 me.GemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001593 },
1594 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001595 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001596 meInstance, err := oFsm.pOmciCC.SendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1597 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001598 if err != nil {
1599 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001600 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001601 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001602 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001603 return
1604 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001605 //accept also nil as (error) return value for writing to LastTx
1606 // - this avoids misinterpretation of new received OMCI messages
1607 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001608 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001609 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001610 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001612 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001614 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001615 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001616 return
1617 }
1618 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001619
1620 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001621 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001622 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001623}
1624
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001625func (oFsm *UniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001626 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1627 if oFsm.tcontSetBefore {
1628 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1629 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001630 "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001631 "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001632 go func(aPAFsm *cmn.AdapterFsm) {
1633 if aPAFsm != nil && aPAFsm.PFsm != nil {
1634 _ = aPAFsm.PFsm.Event(aniEvRxPrioqsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001635 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001636 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001637 return
1638 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001639 const cu16StrictPrioWeight uint16 = 0xFFFF
1640 //find all upstream PrioQueues related to this T-Cont
1641 loQueueMap := ordered_map.NewOrderedMap()
1642 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001643 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001644 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001645 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1646 "prioString": gemPortAttribs.pbitString})
1647 continue
1648 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001649 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301650 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001651 //key does not yet exist
1652 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1653 }
1654 } else {
1655 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1656 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001657 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001658
Girish Gowdra09e5f212021-09-30 16:28:36 -07001659 trafficSchedPtrSetSupported := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001660 loOnu2g := oFsm.pOnuDB.GetMe(me.Onu2GClassID, cmn.Onu2gMeID)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001661 if loOnu2g == nil {
1662 logger.Errorw(ctx, "onu2g is nil, cannot read qos configuration flexibility parameter",
1663 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001664 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001665 return
1666 }
1667 returnVal := loOnu2g["QualityOfServiceQosConfigurationFlexibility"]
1668 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001669 if qosCfgFlexParam, err := oFsm.pOnuDB.GetUint16Attrib(returnVal); err == nil {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001670 trafficSchedPtrSetSupported = qosCfgFlexParam&bitTrafficSchedulerPtrSetPermitted == bitTrafficSchedulerPtrSetPermitted
1671 logger.Debugw(ctx, "trafficSchedPtrSetSupported set",
1672 log.Fields{"qosCfgFlexParam": qosCfgFlexParam, "trafficSchedPtrSetSupported": trafficSchedPtrSetSupported})
1673 } else {
1674 logger.Errorw(ctx, "Cannot extract qos configuration flexibility parameter",
1675 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001676 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001677 return
1678 }
1679 } else {
1680 logger.Errorw(ctx, "Cannot read qos configuration flexibility parameter",
1681 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001682 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001683 return
1684 }
1685
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001686 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1687 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1688 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1689 // or even be finished without correct SP/WRR setting
1690
1691 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1692 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1693 // even though its T-Cont seems to be wrong ...
1694 loTrafficSchedulerEID := 0x8000
1695 //for all found queues
1696 iter := loQueueMap.IterFunc()
1697 for kv, ok := iter(); ok; kv, ok = iter() {
1698 queueIndex := (kv.Key).(uint16)
1699 meParams := me.ParamData{
1700 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301701 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001702 }
Girish Gowdra09e5f212021-09-30 16:28:36 -07001703 if trafficSchedPtrSetSupported {
1704 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1705 //StrictPrio indication
1706 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
1707 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1708 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001709 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = 0 //ensure T-Cont defined StrictPrio scheduling
Girish Gowdra09e5f212021-09-30 16:28:36 -07001710 } else {
1711 //WRR indication
1712 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
1713 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1714 "Weight": kv.Value,
1715 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001716 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1717 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Girish Gowdra09e5f212021-09-30 16:28:36 -07001718 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001719 } else {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001720 // setting Traffic Scheduler (TS) pointer is not supported unless we point to another TS that points to the same TCONT.
1721 // For now lets use TS that is hardwired in the ONU and just update the weight in case of WRR, which in fact is all we need at the moment.
1722 // The code could get unnecessarily convoluted if we provide the flexibility try to find and point to another TS that points to the same TCONT.
1723 if (kv.Value).(uint16) == cu16StrictPrioWeight { // SP case, nothing to be done. Proceed to the next queue
1724 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio, traffic sched ptr set unsupported", log.Fields{
1725 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1726 "device-id": oFsm.deviceID})
1727 continue
1728 }
1729 // WRR case, update weight.
1730 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR, traffic sched ptr set unsupported", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001731 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1732 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001733 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001734 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001735 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001736 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001737 meInstance, err := oFsm.pOmciCC.SendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1738 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001739 if err != nil {
1740 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001741 logger.Errorw(ctx, "PrioQueueVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001742 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001743 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001744 return
1745 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001746 //accept also nil as (error) return value for writing to LastTx
1747 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001748 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001749 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001750
1751 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001752 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001753 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001755 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001756 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001757 return
1758 }
1759
1760 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1761 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1762 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1763 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1764
1765 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001766
1767 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001769 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001770}
1771
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001772func (oFsm *UniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001773 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001774 if oFsm.isCanceled {
1775 // FSM already canceled before entering wait
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001776 logger.Debugw(ctx, "UniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
mpagenkocf48e452021-04-23 09:23:00 +00001777 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001778 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00001779 }
mpagenko7d6bb022021-03-11 15:07:55 +00001780 oFsm.isAwaitingResponse = true
1781 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001782 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301783 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001784 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001785 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001786 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001788 oFsm.mutexIsAwaitingResponse.Lock()
1789 oFsm.isAwaitingResponse = false
1790 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001791 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001792 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301793 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001794 logger.Debugw(ctx, "UniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001795 oFsm.mutexIsAwaitingResponse.Lock()
1796 oFsm.isAwaitingResponse = false
1797 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001798 return nil
1799 }
mpagenko7d6bb022021-03-11 15:07:55 +00001800 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001801 logger.Debugw(ctx, "UniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001802 oFsm.mutexIsAwaitingResponse.Lock()
1803 oFsm.isAwaitingResponse = false
1804 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001805 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001806 }
1807}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001808
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001809func (oFsm *UniPonAniConfigFsm) setChanSet(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001810 oFsm.mutexChanSet.Lock()
1811 oFsm.chanSet = flagValue
1812 oFsm.mutexChanSet.Unlock()
1813}
1814
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001815func (oFsm *UniPonAniConfigFsm) isChanSet() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001816 oFsm.mutexChanSet.RLock()
1817 flagValue := oFsm.chanSet
1818 oFsm.mutexChanSet.RUnlock()
1819 return flagValue
1820}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001821
1822// PrepareForGarbageCollection - remove references to prepare for garbage collection
1823func (oFsm *UniPonAniConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
1824 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": oFsm.deviceID})
1825 oFsm.pDeviceHandler = nil
1826 oFsm.pOnuDeviceEntry = nil
1827 oFsm.pOmciCC = nil
1828}