blob: ca5e60543110c668bfad68afd65b203e8453380c [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)
Holger Hildebrandtc408f492022-07-14 08:39:24 +000096const cTechProfileTypeXgsPon = "XGS-PON"
97
98// definitions as per G.988
99// Gem Encryption Key Ring
100const (
101 // No encryption. The downstream key index is ignored, and upstream traffic is transmitted with key index 0.
102 GemEncryptKeyRingNoEncrypt = 0
103 // Unicast payload encryption in both directions. Keys are generated by the ONU and transmitted to the OLT via the PLOAM channel.
104 GemEncryptKeyRingUnicastPayload = 1
105 // Broadcast (multicast) encryption. Keys are generated by the OLT and distributed via the OMCI.
106 GemEncryptKeyRingBroadcastMulticast = 2
107 // Unicast encryption, downstream only. Keys are generated by the ONU and transmitted to the OLT via the PLOAM channel.
108 GemEncryptKeyRingUnicastDownstreamOnly = 3
109)
Girish Gowdra09e5f212021-09-30 16:28:36 -0700110
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000111// CAniFsmIdleState - TODO: add comment
112const CAniFsmIdleState = aniStConfigDone
113
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000114type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +0300115 gemPortID uint16
116 upQueueID uint16
117 downQueueID uint16
118 direction uint8
119 qosPolicy string
120 weight uint8
121 pbitString string
122 isMulticast bool
123 multicastGemID uint16
124 staticACL string
125 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000126}
127
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000128//UniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
129type UniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000130 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000131 pDeviceHandler cmn.IdeviceHandler
132 pOnuDeviceEntry cmn.IonuDeviceEntry
133 pOmciCC *cmn.OmciCC
134 pOnuUniPort *cmn.OnuUniPort
135 pUniTechProf *OnuUniTechProf
136 pOnuDB *devdb.OnuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800137 techProfileID uint8
Holger Hildebrandtc408f492022-07-14 08:39:24 +0000138 techProfileType string
mpagenko8b07c1b2020-11-26 10:36:31 +0000139 uniTpKey uniTP
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000140 requestEvent cmn.OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000141 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000142 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000143 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530144 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000145 PAdaptFsm *cmn.AdapterFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000146 chSuccess chan<- uint8
147 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000148 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000149 chanSet bool
150 mapperSP0ID uint16
151 macBPCD0ID uint16
152 tcont0ID uint16
153 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000154 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000155 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000156 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000157 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000158 isWaitingForFlowDelete bool
159 waitFlowDeleteChannel chan bool
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700160 tcontSetBefore bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000161}
162
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000163//NewUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
164func NewUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort, apUniTechProf *OnuUniTechProf,
Holger Hildebrandtc408f492022-07-14 08:39:24 +0000165 apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8, aTechProfileType string, aRequestEvent cmn.OnuDeviceEvent, aName string,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000166 apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, aCommChannel chan cmn.Message) *UniPonAniConfigFsm {
167 instFsm := &UniPonAniConfigFsm{
168 pDeviceHandler: apDeviceHandler,
169 pOnuDeviceEntry: apOnuDeviceEntry,
170 deviceID: apDeviceHandler.GetDeviceID(),
171 pOmciCC: apDevOmciCC,
172 pOnuUniPort: apUniPort,
173 pUniTechProf: apUniTechProf,
174 pOnuDB: apOnuDB,
175 techProfileID: aTechProfileID,
Holger Hildebrandtc408f492022-07-14 08:39:24 +0000176 techProfileType: aTechProfileType,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000177 requestEvent: aRequestEvent,
178 chanSet: false,
179 tcontSetBefore: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000180 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000181 instFsm.uniTpKey = uniTP{uniID: apUniPort.UniID, tpID: aTechProfileID}
mpagenkobb47bc22021-04-20 13:29:09 +0000182 instFsm.waitFlowDeleteChannel = make(chan bool)
mpagenko8b07c1b2020-11-26 10:36:31 +0000183
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000184 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
185 if instFsm.PAdaptFsm == nil {
186 logger.Errorw(ctx, "UniPonAniConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000187 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000188 return nil
189 }
190
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000191 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000192 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000193 fsm.Events{
194
mpagenko1cc3cb42020-07-27 15:24:38 +0000195 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000196
197 //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 +0000198 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000199 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000200 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
201 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000202 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000203 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000204 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000205 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000206 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000207 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000208 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000209
mpagenko8b07c1b2020-11-26 10:36:31 +0000210 //for removing Gem related resources
211 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800212 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
213 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000214 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300215 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700216 {Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStRemDot1PMapper},
217 {Name: aniEvRemGemDone, Src: []string{aniStRemDot1PMapper}, Dst: aniStConfigDone},
218 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
219 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000220
221 //for removing TCONT related resources
222 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700223 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStConfigDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000224
225 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300226 aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000227 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000228 {Name: aniEvTimeoutMids, Src: []string{
229 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000230
mpagenko1cc3cb42020-07-27 15:24:38 +0000231 // exceptional treatment for all states except aniStResetting
232 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
233 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300234 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000235 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000236 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000237 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000238 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000239 },
240
241 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000242 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000243 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
244 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
245 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
246 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
247 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
248 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
249 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
250 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
251 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
252 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000253 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000254 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300255 ("enter_" + aniStRemovingTD): func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000256 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
257 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
258 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
259 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
260 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
261 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000262 },
263 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000264 if instFsm.PAdaptFsm.PFsm == nil {
265 logger.Errorw(ctx, "UniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000266 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000267 return nil
268 }
269
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000270 logger.Debugw(ctx, "UniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000271 return instFsm
272}
273
Himani Chawla6d2ae152020-09-02 13:11:20 +0530274//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000275func (oFsm *UniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000276 oFsm.chSuccess = aChSuccess
277 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000278 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000279}
280
mpagenko7d6bb022021-03-11 15:07:55 +0000281//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000282func (oFsm *UniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandt12609a12022-03-25 13:23:25 +0000283 logger.Debugw(ctx, "CancelProcessing entered", log.Fields{"device-id": oFsm.deviceID})
mpagenko73143992021-04-09 15:17:10 +0000284 //early indication about started reset processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000285 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000286 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000287 oFsm.mutexIsAwaitingResponse.Lock()
288 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000289 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000290 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
291 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
292 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000293 //use channel to indicate that the response waiting shall be aborted
294 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000295 } else {
296 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000297 }
mpagenkocf48e452021-04-23 09:23:00 +0000298
299 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000300 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000301 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000302 //use channel to indicate that the response waiting shall be aborted
303 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000304 } else {
305 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000306 }
mpagenkocf48e452021-04-23 09:23:00 +0000307
mpagenko7d6bb022021-03-11 15:07:55 +0000308 // 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 +0000309 PAdaptFsm := oFsm.PAdaptFsm
310 if PAdaptFsm != nil {
mpagenko7d6bb022021-03-11 15:07:55 +0000311 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000312 go func(aPAFsm *cmn.AdapterFsm) {
313 if aPAFsm.PFsm != nil {
314 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
mpagenko7d6bb022021-03-11 15:07:55 +0000315 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000316 }(PAdaptFsm)
mpagenko7d6bb022021-03-11 15:07:55 +0000317 }
mpagenko73143992021-04-09 15:17:10 +0000318
mpagenko45cc6a32021-07-23 10:06:57 +0000319 // possible access conflicts on internal data by next needed data clearance
320 // are avoided by using mutexTPState also from within clearAniSideConfig
321 // do not try to lock TpProcMutex here as done in previous code version
322 // as it may result in deadlock situations (as observed at soft-reboot handling where
323 // TpProcMutex is already locked by some ongoing TechProfile config/removal processing
mpagenko73143992021-04-09 15:17:10 +0000324 //remove all TechProf related internal data to allow for new configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000325 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.UniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000326}
327
Mahir Gunyel6781f962021-05-16 23:30:08 -0700328//nolint: gocyclo
329//TODO:visit here for refactoring for gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000330func (oFsm *UniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *cmn.AdapterFsm) {
331 if aPAFsm != nil && aPAFsm.PFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700332 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000333 oFsm.mapperSP0ID, err = cmn.GenerateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.techProfileID))
Mahir Gunyel6781f962021-05-16 23:30:08 -0700334 if err != nil {
335 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
336 "techProfileID": oFsm.techProfileID, "error": err})
337 return
338 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000339 oFsm.macBPCD0ID, err = cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.techProfileID))
Mahir Gunyel6781f962021-05-16 23:30:08 -0700340 if err != nil {
341 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
342 "techProfileID": oFsm.techProfileID, "error": err})
343 return
344 }
345 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
346 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000347 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "techProfileID": oFsm.techProfileID})
348 if oFsm.pOnuDeviceEntry == nil {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700349 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800350 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 tcontInstID, tcontAlreadyExist, err := oFsm.pOnuDeviceEntry.AllocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700353 if err != nil {
354 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700355 //reset the state machine to enable usage on subsequent requests
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 _ = aPAFsm.PFsm.Event(aniEvReset)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700357 return
358 }
359 oFsm.tcont0ID = tcontInstID
360 oFsm.tcontSetBefore = tcontAlreadyExist
361 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
362 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
363 "tcontAlreadyExist": tcontAlreadyExist,
364 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800365
366 // Access critical state with lock
mpagenko3ce9fa02021-07-28 13:26:54 +0000367 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000368 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
369 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko3ce9fa02021-07-28 13:26:54 +0000370 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800371
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800373 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300374 loGemPortAttribs := ponAniGemPortAttribs{}
375
Himani Chawla26e555c2020-08-31 12:30:20 +0530376 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
377
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 if queueInstKeys := oFsm.pOnuDB.GetSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530379
380 loGemPortAttribs.gemPortID = gemEntry.gemPortID
381 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
382 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
383 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
384 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
385
386 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.UniID,
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
389 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
390 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000391 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.UniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
Himani Chawla26e555c2020-08-31 12:30:20 +0530392
393 usQueueFound := false
394 dsQueueFound := false
395 for _, mgmtEntityID := range queueInstKeys {
396 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000397 returnVal := meAttributes[me.PriorityQueue_RelatedPort]
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 if relatedPort, err := oFsm.pOnuDB.GetUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 if relatedPort == usQrelPortMask {
401 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000402 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000403 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 usQueueFound = true
405 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
406 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000407 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000408 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530409 dsQueueFound = true
410 }
411 if usQueueFound && dsQueueFound {
412 break
413 }
414 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000415 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530416 }
417 } else {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000418 logger.Warnw(ctx, "PrioQueue.RelatedPort not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 }
420 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000422 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530423 }
424 }
425 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000426 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530427 }
428 loGemPortAttribs.direction = gemEntry.direction
429 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
430 loGemPortAttribs.weight = gemEntry.queueWeight
431 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300432
ozgecanetsia4b232302020-11-11 10:58:10 +0300433 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300434 //TODO this might effectively ignore the for loop starting at line 316
435 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300436 loGemPortAttribs.isMulticast = true
437 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
438 loGemPortAttribs.staticACL = gemEntry.staticACL
439 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530440
dbainbri4d3a0dc2020-12-02 00:33:42 +0000441 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300442 "gemPortID": loGemPortAttribs.gemPortID,
443 "isMulticast": loGemPortAttribs.isMulticast,
444 "multicastGemID": loGemPortAttribs.multicastGemID,
445 "staticACL": loGemPortAttribs.staticACL,
446 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000447 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300448 })
449
450 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000451 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300452 "gemPortID": loGemPortAttribs.gemPortID,
453 "upQueueID": loGemPortAttribs.upQueueID,
454 "downQueueID": loGemPortAttribs.downQueueID,
455 "pbitString": loGemPortAttribs.pbitString,
456 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000457 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300458 })
459 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530460
461 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
462 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
464 _ = aPAFsm.PFsm.Event(aniEvStartConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000465 } else {
466 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000467 _ = aPAFsm.PFsm.Event(aniEvSkipOmciConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000468 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 }
470}
471
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000472func (oFsm *UniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000474 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000475 // in case the used channel is not yet defined (can be re-used after restarts)
476 if oFsm.omciMIdsResponseReceived == nil {
477 oFsm.omciMIdsResponseReceived = make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000478 logger.Debug(ctx, "UniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000479 } else {
480 // as we may 're-use' this instance of FSM and the connected channel
481 // make sure there is no 'lingering' request in the already existing channel:
482 // (simple loop sufficient as we are the only receiver)
483 for len(oFsm.omciMIdsResponseReceived) > 0 {
484 <-oFsm.omciMIdsResponseReceived
485 }
486 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000487 //ensure internal slices are empty (which might be set from previous run) - release memory
488 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000489 oFsm.mutexIsAwaitingResponse.Lock()
490 //reset the canceled state possibly existing from previous reset
491 oFsm.isCanceled = false
492 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000493
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000494 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000495 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000496
497 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000499 if pConfigAniStateAFsm != nil {
500 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000501 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000502
mpagenko3dbcdd22020-07-22 07:38:45 +0000503 }
504}
505
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000506func (oFsm *UniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
507 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000508 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000509 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000510 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000511 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 meInstance, err := oFsm.pOmciCC.SendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
513 oFsm.mapperSP0ID, oFsm.PAdaptFsm.CommChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300514 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000515 logger.Errorw(ctx, "Dot1PMapper create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300516 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000517 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300518 if pConfigAniStateAFsm != nil {
519 oFsm.mutexPLastTxMeInstance.Unlock()
520 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000521 go func(aPAFsm *cmn.AdapterFsm) {
522 if aPAFsm != nil && aPAFsm.PFsm != nil {
523 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300524 }
525 }(pConfigAniStateAFsm)
526 return
527 }
528 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000529 //accept also nil as (error) return value for writing to LastTx
530 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000531 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300532 oFsm.mutexPLastTxMeInstance.Unlock()
533
mpagenko3dbcdd22020-07-22 07:38:45 +0000534}
535
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000536func (oFsm *UniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
537 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000538 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
539 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
541 bridgePtr := cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
mpagenko3dbcdd22020-07-22 07:38:45 +0000542 meParams := me.ParamData{
543 EntityID: oFsm.macBPCD0ID,
544 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000545 me.MacBridgePortConfigurationData_BridgeIdPointer: bridgePtr,
546 me.MacBridgePortConfigurationData_PortNum: 0xFF, //fixed unique ANI side indication
547 me.MacBridgePortConfigurationData_TpType: 3, //for .1PMapper
548 me.MacBridgePortConfigurationData_TpPointer: oFsm.mapperSP0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000549 },
550 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000551 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
553 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300554 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000555 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300556 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300558 if pConfigAniStateAFsm != nil {
559 oFsm.mutexPLastTxMeInstance.Unlock()
560 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000561 go func(aPAFsm *cmn.AdapterFsm) {
562 if aPAFsm != nil && aPAFsm.PFsm != nil {
563 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300564 }
565 }(pConfigAniStateAFsm)
566 return
567 }
568 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000569 //accept also nil as (error) return value for writing to LastTx
570 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000571 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300572 oFsm.mutexPLastTxMeInstance.Unlock()
573
mpagenko3dbcdd22020-07-22 07:38:45 +0000574}
575
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576func (oFsm *UniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
577 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000578 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
579 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700581 "tcontExist": oFsm.tcontSetBefore})
582 //If tcont was set before, then no need to set it again. Let state machine to proceed.
583 if oFsm.tcontSetBefore {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 go func(aPAFsm *cmn.AdapterFsm) {
585 if aPAFsm != nil && aPAFsm.PFsm != nil {
586 _ = aPAFsm.PFsm.Event(aniEvRxTcontsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700587 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000588 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700589 return
590 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000591 meParams := me.ParamData{
592 EntityID: oFsm.tcont0ID,
593 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000594 me.TCont_AllocId: oFsm.alloc0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000595 },
596 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000597 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
599 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300600 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000601 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300602 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000603 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300604 if pConfigAniStateAFsm != nil {
605 oFsm.mutexPLastTxMeInstance.Unlock()
606 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 go func(aPAFsm *cmn.AdapterFsm) {
608 if aPAFsm != nil && aPAFsm.PFsm != nil {
609 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300610 }
611 }(pConfigAniStateAFsm)
612 return
613 }
614 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000615 //accept also nil as (error) return value for writing to LastTx
616 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000617 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300618 oFsm.mutexPLastTxMeInstance.Unlock()
619
mpagenko3dbcdd22020-07-22 07:38:45 +0000620}
621
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000622func (oFsm *UniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
623 logger.Debugw(ctx, "UniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
624 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000626}
627
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000628func (oFsm *UniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
629 logger.Debugw(ctx, "UniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
630 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000632}
633
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000634func (oFsm *UniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
635 logger.Debugw(ctx, "UniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000636 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000638}
639
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640func (oFsm *UniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300641
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000643 "toGemIw": 1024, /* cmp above */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000645
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000647 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000648 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000649
mpagenko3dbcdd22020-07-22 07:38:45 +0000650 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000651 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530652 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000653 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000654
655 //assign the GemPorts according to the configured Prio
656 var loPrioGemPortArray [8]uint16
657 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300658 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300660 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
661 "prioString": gemPortAttribs.pbitString})
662 continue
663 }
664 if gemPortAttribs.pbitString == "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000665 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300666 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
667 "prioString": gemPortAttribs.pbitString})
668 continue
669 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000670 for i := 0; i < 8; i++ {
671 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
672 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
673 if prio == 1 { // Check this p-bit is set
674 if loPrioGemPortArray[i] == 0 {
675 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
676 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000677 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000678 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000679 "SetGemPort": loPrioGemPortArray[i]})
680 }
681 }
682 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000683 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000684 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000685 "prioString": gemPortAttribs.pbitString, "position": i})
686 }
687
688 }
689 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300690
ozgecanetsia4b232302020-11-11 10:58:10 +0300691 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530692 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300693 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530694 if value != 0 {
695 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530696 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000698 "for Prio": index,
699 "IwPtr": strconv.FormatInt(int64(value), 16),
700 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300701 } else {
702 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000703 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
704 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300705 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530706 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000707 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300708 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000709 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
710 // but except for processing effort does not really harm - left to keep changes low
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000711 meParams.Attributes[me.Ieee8021PMapperServiceProfile_TpPointer] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530712
713 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000714 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000715 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300716 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
717 // 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 +0000718 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000719 //pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300720 //if pConfigAniStateAFsm != nil {
721 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000722 // go func(aPAFsm *cmn.AdapterFsm) {
723 // if aPAFsm != nil && aPAFsm.PFsm != nil {
724 // _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300725 // }
726 // }(pConfigAniStateAFsm)
727 //}
728 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000730 if pConfigAniStateAFsm != nil {
731 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000732 go func(aPAFsm *cmn.AdapterFsm) {
733 if aPAFsm != nil && aPAFsm.PFsm != nil {
734 _ = aPAFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000735 }
736 }(pConfigAniStateAFsm)
737 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300738 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000739 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000740 meInstance, err := oFsm.pOmciCC.SendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
741 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300742 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000743 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300744 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000745 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300746 if pConfigAniStateAFsm != nil {
747 oFsm.mutexPLastTxMeInstance.Unlock()
748 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000749 go func(aPAFsm *cmn.AdapterFsm) {
750 if aPAFsm != nil && aPAFsm.PFsm != nil {
751 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300752 }
753 }(pConfigAniStateAFsm)
754 return
755 }
756 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300757 //accept also nil as (error) return value for writing to LastTx
758 // - this avoids misinterpretation of new received OMCI messages
759 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300760 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000761 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000762}
763
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000764func (oFsm *UniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
765 logger.Debugw(ctx, "UniPonAniConfigFsm ani config done", log.Fields{
766 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000767 //store that the UNI related techProfile processing is done for the given Profile and Uni
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000768 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
769 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000770 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000771 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000772 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
773 // but only in case the techProfile was configured (not deleted)
774 if oFsm.requestEventOffset == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000775 go oFsm.pDeviceHandler.VerifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000776 }
777 } else {
778 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000779 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000780 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000781 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000782 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000783 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
784 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000785 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000786 }
mpagenko01e726e2020-10-23 09:45:29 +0000787
788 //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 +0000789}
790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000791func (oFsm *UniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000792 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
793 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000794 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
795 select {
796 case <-oFsm.waitFlowDeleteChannel:
797 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
798 default:
799 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000800
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000801 uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.UniID)
802 if uniVlanConfigFsm != nil {
mpagenko3ce9fa02021-07-28 13:26:54 +0000803 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000804 if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000805 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000807 // 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 +0000808 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000809 if pConfigAniStateAFsm != nil {
810 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811 go func(aPAFsm *cmn.AdapterFsm) {
812 if aPAFsm != nil && aPAFsm.PFsm != nil {
813 _ = aPAFsm.PFsm.Event(aniEvWaitFlowRem)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000814 }
815 }(pConfigAniStateAFsm)
816 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000817 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 +0000818 }
819 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800820 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000821 } else {
822 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
823 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800824 }
825
mpagenko3ce9fa02021-07-28 13:26:54 +0000826 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000827 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000828 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000829 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000830 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
831 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000832 "GemIwTp-entity-id": loGemPortID})
833 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
834
835 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000836 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000837 meInstance, err := oFsm.pOmciCC.SendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
838 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300839 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000840 logger.Errorw(ctx, "GemIWTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300841 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300843 if pConfigAniStateAFsm != nil {
844 oFsm.mutexPLastTxMeInstance.Unlock()
845 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000846 go func(aPAFsm *cmn.AdapterFsm) {
847 if aPAFsm != nil && aPAFsm.PFsm != nil {
848 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300849 }
850 }(pConfigAniStateAFsm)
851 return
852 }
853 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000854 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300855 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000856}
857
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858func (oFsm *UniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
mpagenkobb47bc22021-04-20 13:29:09 +0000859 oFsm.mutexIsAwaitingResponse.Lock()
860 oFsm.isWaitingForFlowDelete = true
861 oFsm.mutexIsAwaitingResponse.Unlock()
862 select {
863 // maybe be also some outside cancel (but no context modeled for the moment ...)
864 // case <-ctx.Done():
865 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000866 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 +0000867 logger.Warnw(ctx, "UniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
868 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000869 oFsm.mutexIsAwaitingResponse.Lock()
870 oFsm.isWaitingForFlowDelete = false
871 oFsm.mutexIsAwaitingResponse.Unlock()
872 //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 +0000873 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000874 if pConfigAniStateAFsm != nil {
875 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 go func(aPAFsm *cmn.AdapterFsm) {
877 if aPAFsm != nil && aPAFsm.PFsm != nil {
878 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000879 }
880 }(pConfigAniStateAFsm)
881 } else {
882 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000884 }
885 return
886
887 case success := <-oFsm.waitFlowDeleteChannel:
888 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 logger.Debugw(ctx, "UniPonAniConfigFsm flow removed info received", log.Fields{
890 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000891 oFsm.mutexIsAwaitingResponse.Lock()
892 oFsm.isWaitingForFlowDelete = false
893 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000894 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000895 if pConfigAniStateAFsm != nil {
896 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000897 go func(aPAFsm *cmn.AdapterFsm) {
898 if aPAFsm != nil && aPAFsm.PFsm != nil {
899 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000900 }
901 }(pConfigAniStateAFsm)
902 } else {
903 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000904 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000905 }
906 return
907 }
908 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 logger.Debugw(ctx, "UniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
910 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000911 oFsm.mutexIsAwaitingResponse.Lock()
912 oFsm.isWaitingForFlowDelete = false
913 oFsm.mutexIsAwaitingResponse.Unlock()
914 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000915 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000916 if pConfigAniStateAFsm != nil {
917 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000918 go func(aPAFsm *cmn.AdapterFsm) {
919 if aPAFsm != nil && aPAFsm.PFsm != nil {
920 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenkobb47bc22021-04-20 13:29:09 +0000921 }
922 }(pConfigAniStateAFsm)
923 }
924 return
925 }
926}
927
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000928func (oFsm *UniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000929 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000930 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000931 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000932 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
933 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000934 "GemNCTP-entity-id": loGemPortID})
935 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000936 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000937 meInstance, err := oFsm.pOmciCC.SendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
938 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300939 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000940 logger.Errorw(ctx, "GemNCTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300941 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000942 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300943 if pConfigAniStateAFsm != nil {
944 oFsm.mutexPLastTxMeInstance.Unlock()
945 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000946 go func(aPAFsm *cmn.AdapterFsm) {
947 if aPAFsm != nil && aPAFsm.PFsm != nil {
948 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300949 }
950 }(pConfigAniStateAFsm)
951 return
952 }
953 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000954 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000955 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300956
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800957 // Mark the gem port to be removed for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
959 if OnuMetricsManager != nil {
960 OnuMetricsManager.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800961 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000962}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000963func (oFsm *UniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000964 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300965 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000966 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
968 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300969 "TD-entity-id": loGemPortID})
970
971 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000972 meInstance, err := oFsm.pOmciCC.SendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
973 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300974
975 if err != nil {
976 logger.Errorw(ctx, "TD delete failed - proceed fsm",
977 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300979 if pConfigAniStateAFsm != nil {
980 oFsm.mutexPLastTxMeInstance.Unlock()
981 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 go func(aPAFsm *cmn.AdapterFsm) {
983 if aPAFsm != nil && aPAFsm.PFsm != nil {
984 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300985 }
986 }(pConfigAniStateAFsm)
987 return
988 }
989 }
990 oFsm.pLastTxMeInstance = meInstance
991 oFsm.mutexPLastTxMeInstance.Unlock()
992}
mpagenko8b07c1b2020-11-26 10:36:31 +0000993
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000994func (oFsm *UniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
995 logger.Debugw(ctx, "UniPonAniConfigFsm - start resetting the TCont", log.Fields{
996 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000997
998 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
999 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
1000 meParams := me.ParamData{
1001 EntityID: oFsm.tcont0ID,
1002 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001003 me.TCont_AllocId: cmn.UnusedTcontAllocID,
mpagenko8b07c1b2020-11-26 10:36:31 +00001004 },
1005 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001006 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001007 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1008 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001009 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001011 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001013 if pConfigAniStateAFsm != nil {
1014 oFsm.mutexPLastTxMeInstance.Unlock()
1015 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 go func(aPAFsm *cmn.AdapterFsm) {
1017 if aPAFsm != nil && aPAFsm.PFsm != nil {
1018 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001019 }
1020 }(pConfigAniStateAFsm)
1021 return
1022 }
1023 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001024 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001025 oFsm.mutexPLastTxMeInstance.Unlock()
1026
mpagenko8b07c1b2020-11-26 10:36:31 +00001027}
1028
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029func (oFsm *UniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
1030 logger.Debugw(ctx, "UniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
1031 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Mahir Gunyel9545be22021-07-04 15:53:16 -07001032 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1033 unicastGemCount := 0
1034 for _, gemEntry := range mapGemPortParams {
1035 if !gemEntry.isMulticast {
1036 unicastGemCount++
1037 }
1038 }
1039 if unicastGemCount > 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 logger.Debugw(ctx, "UniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1041 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1042 pConfigAniStateAFsm := oFsm.PAdaptFsm
Mahir Gunyel9545be22021-07-04 15:53:16 -07001043 if pConfigAniStateAFsm != nil {
1044 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001045 go func(aPAFsm *cmn.AdapterFsm) {
1046 if aPAFsm != nil && aPAFsm.PFsm != nil {
1047 _ = aPAFsm.PFsm.Event(aniEvRemGemDone)
Mahir Gunyel9545be22021-07-04 15:53:16 -07001048 }
1049 }(pConfigAniStateAFsm)
1050 return
1051 }
1052 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 logger.Debugw(ctx, "UniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1054 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001055
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001056 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 meInstance, err := oFsm.pOmciCC.SendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1058 oFsm.PAdaptFsm.CommChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001059 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001060 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001061 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001062 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001063 if pConfigAniStateAFsm != nil {
1064 oFsm.mutexPLastTxMeInstance.Unlock()
1065 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001066 go func(aPAFsm *cmn.AdapterFsm) {
1067 if aPAFsm != nil && aPAFsm.PFsm != nil {
1068 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001069 }
1070 }(pConfigAniStateAFsm)
1071 return
1072 }
1073 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001074 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001075 oFsm.mutexPLastTxMeInstance.Unlock()
1076
mpagenko8b07c1b2020-11-26 10:36:31 +00001077}
1078
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079func (oFsm *UniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1080 logger.Debugw(ctx, "UniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
1081 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001082
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001083 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001084 meInstance, err := oFsm.pOmciCC.SendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1085 oFsm.PAdaptFsm.CommChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001086 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001087 logger.Errorw(ctx, "MBPConfigData delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001088 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001089 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001090 if pConfigAniStateAFsm != nil {
1091 oFsm.mutexPLastTxMeInstance.Unlock()
1092 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001093 go func(aPAFsm *cmn.AdapterFsm) {
1094 if aPAFsm != nil && aPAFsm.PFsm != nil {
1095 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001096 }
1097 }(pConfigAniStateAFsm)
1098 return
1099 }
1100 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001101 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001102 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001103}
1104
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001105func (oFsm *UniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1106 logger.Debugw(ctx, "UniPonAniConfigFsm ani removal done", log.Fields{
1107 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001108 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001109 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001110 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001111 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001112 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001113 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1114 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001115 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001116 }
1117
1118 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001119 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko8b07c1b2020-11-26 10:36:31 +00001120 if pConfigAniStateAFsm != nil {
1121 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001122 go func(aPAFsm *cmn.AdapterFsm) {
1123 if aPAFsm != nil && aPAFsm.PFsm != nil {
1124 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenko8b07c1b2020-11-26 10:36:31 +00001125 }
1126 }(pConfigAniStateAFsm)
1127 }
1128}
1129
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001130func (oFsm *UniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1131 logger.Debugw(ctx, "UniPonAniConfigFsm resetting", log.Fields{
1132 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001133
mpagenko45cc6a32021-07-23 10:06:57 +00001134 if oFsm.isChanSet() {
1135 // indicate processing error to the caller (in case there was still some open request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001136 logger.Debugw(ctx, "UniPonAniConfigFsm processingError on channel", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001137 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1138 //use non-blocking channel send to avoid blocking because of non-existing receiver
1139 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1140 select {
1141 case oFsm.chSuccess <- 0:
1142 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001143 logger.Debugw(ctx, "UniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001144 "device-id": oFsm.deviceID})
1145 }
1146 oFsm.setChanSet(false) //reset the internal channel state
1147 }
1148
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001149 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +00001150 if pConfigAniStateAFsm != nil {
1151 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001152 fsmAbortMsg := cmn.Message{
1153 Type: cmn.TestMsg,
1154 Data: cmn.TestMessage{
1155 TestMessageVal: cmn.AbortMessageProcessing,
mpagenko3dbcdd22020-07-22 07:38:45 +00001156 },
1157 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001158 pConfigAniStateAFsm.CommChan <- fsmAbortMsg
mpagenko3dbcdd22020-07-22 07:38:45 +00001159
1160 //try to restart the FSM to 'disabled', decouple event transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001161 go func(aPAFsm *cmn.AdapterFsm) {
1162 if aPAFsm != nil && aPAFsm.PFsm != nil {
1163 _ = aPAFsm.PFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001164 }
1165 }(pConfigAniStateAFsm)
1166 }
1167}
1168
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001169func (oFsm *UniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1170 logger.Debugw(ctx, "UniPonAniConfigFsm enters disabled state", log.Fields{
1171 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001172 oFsm.mutexPLastTxMeInstance.Lock()
1173 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001174 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001175}
1176
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001177func (oFsm *UniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1178 logger.Debugw(ctx, "Start UniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001179loop:
1180 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001181 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001182 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001183 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001184 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301185 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001186 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301187 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001188 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301189 break loop
1190 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001191 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301192
1193 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001194 case cmn.TestMsg:
1195 msg, _ := message.Data.(cmn.TestMessage)
1196 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001197 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001198 break loop
1199 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001200 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001201 case cmn.OMCI:
1202 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001203 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301204 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301206 "message.Type": message.Type})
1207 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001208
Himani Chawla4d908332020-08-31 12:30:20 +05301209 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001210 logger.Infow(ctx, "End UniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301211}
1212
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001213func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301214 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1215 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001216 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001217 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301218 return
1219 }
1220 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1221 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001223 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301224 return
1225 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001227 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1228 //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 +00001229 oFsm.mutexPLastTxMeInstance.RLock()
1230 if oFsm.pLastTxMeInstance != nil {
1231 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1232 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1233 // maybe we can use just the same eventName for different state transitions like "forward"
1234 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1235 switch oFsm.pLastTxMeInstance.GetName() {
1236 case "Ieee8021PMapperServiceProfile":
1237 { // let the FSM proceed ...
1238 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapCResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001240 }
1241 case "MacBridgePortConfigurationData":
1242 { // let the FSM proceed ...
1243 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxMbpcdResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001245 }
1246 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1247 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1248 oFsm.mutexPLastTxMeInstance.RUnlock()
1249 oFsm.omciMIdsResponseReceived <- true
1250 }
1251 default:
1252 {
1253 oFsm.mutexPLastTxMeInstance.RUnlock()
1254 logger.Warnw(ctx, "Unsupported ME name received!",
1255 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1256 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001257 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001258 } else {
1259 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001260 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001261 } else {
1262 oFsm.mutexPLastTxMeInstance.RUnlock()
1263 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001264 }
1265 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001266 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1267 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301268 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1269 return
1270 }
Himani Chawla4d908332020-08-31 12:30:20 +05301271}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
Mahir Gunyel01034b62021-06-29 11:25:09 -07001273 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1274 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1275 oFsm.mutexPLastTxMeInstance.RLock()
1276 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1277 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1278 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1279 switch oFsm.pLastTxMeInstance.GetName() {
1280 case "TCont":
1281 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1282 //We should revert DB
1283 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1284 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1285 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 if oFsm.pOnuDeviceEntry != nil {
1287 oFsm.pOnuDeviceEntry.FreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001288 } else {
1289 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1290 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1291 }
1292 }
1293 default:
1294 logger.Warnw(ctx, "Unsupported ME name received with error!",
1295 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1296 }
1297 }
1298}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301300 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1301 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001302 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001303 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301304 return
1305 }
1306 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1307 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001308 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001309 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301310 return
1311 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001312 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301313 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001315 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301316 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001317
Mahir Gunyel01034b62021-06-29 11:25:09 -07001318 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301319 return
1320 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001321 oFsm.mutexPLastTxMeInstance.RLock()
1322 if oFsm.pLastTxMeInstance != nil {
1323 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1324 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1325 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1326 // if, then something like:
1327 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301328
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001329 switch oFsm.pLastTxMeInstance.GetName() {
1330 case "TCont":
1331 { // let the FSM proceed ...
1332 oFsm.mutexPLastTxMeInstance.RUnlock()
1333 if oFsm.requestEventOffset == 0 { //from TCont config request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxTcontsResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001335 } else { // from T-Cont reset request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxResetTcontResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001337 }
1338 }
1339 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1340 { // let the PrioQueue init proceed by stopping the wait function
1341 oFsm.mutexPLastTxMeInstance.RUnlock()
1342 oFsm.omciMIdsResponseReceived <- true
1343 }
1344 case "Ieee8021PMapperServiceProfile":
1345 { // let the FSM proceed ...
1346 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001348 }
1349 default:
1350 {
1351 oFsm.mutexPLastTxMeInstance.RUnlock()
1352 logger.Warnw(ctx, "Unsupported ME name received!",
1353 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001354 }
Himani Chawla4d908332020-08-31 12:30:20 +05301355 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001356 } else {
1357 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301358 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001359 } else {
1360 oFsm.mutexPLastTxMeInstance.RUnlock()
1361 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301362 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001363}
1364
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001365func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001366 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1367 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001369 log.Fields{"device-id": oFsm.deviceID})
1370 return
1371 }
1372 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1373 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001374 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001375 log.Fields{"device-id": oFsm.deviceID})
1376 return
1377 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001378 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001379 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001380 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001381 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1382 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1383 // store error for mgmt display?
1384 return
1385 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001386 oFsm.mutexPLastTxMeInstance.RLock()
1387 if oFsm.pLastTxMeInstance != nil {
1388 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1389 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1390 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1391 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001392
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001393 switch oFsm.pLastTxMeInstance.GetName() {
1394 case "GemInterworkingTerminationPoint":
1395 { // let the FSM proceed ...
1396 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001397 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemiwResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001398 }
1399 case "GemPortNetworkCtp":
1400 { // let the FSM proceed ...
1401 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001402 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemntpResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001403 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001404 case "TrafficDescriptor":
1405 { // let the FSM proceed ...
1406 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001407 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemTdResp)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001408 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001409 case "Ieee8021PMapperServiceProfile":
1410 { // let the FSM proceed ...
1411 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001412 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRem1pMapperResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001413 }
1414 case "MacBridgePortConfigurationData":
1415 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1416 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001417 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemAniBPCDResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001418 }
1419 default:
1420 {
1421 oFsm.mutexPLastTxMeInstance.RUnlock()
1422 logger.Warnw(ctx, "Unsupported ME name received!",
1423 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1424 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001425 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001426 } else {
1427 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001428 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001429 } else {
1430 oFsm.mutexPLastTxMeInstance.RUnlock()
1431 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001432 }
1433}
1434
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001435func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001437 "msgType": msg.OmciMsg.MessageType})
1438
1439 switch msg.OmciMsg.MessageType {
1440 case omci.CreateResponseType:
1441 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301443
mpagenko3dbcdd22020-07-22 07:38:45 +00001444 } //CreateResponseType
1445 case omci.SetResponseType:
1446 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001448
mpagenko3dbcdd22020-07-22 07:38:45 +00001449 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001450 case omci.DeleteResponseType:
1451 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001452 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001453
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001454 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001455 default:
1456 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 logger.Errorw(ctx, "UniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001458 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001459 return
1460 }
1461 }
1462}
1463
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001464func (oFsm *UniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001465 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1466 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001467 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001468 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1469 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001470 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001471 meParams := me.ParamData{
1472 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1473 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001474 me.GemPortNetworkCtp_PortId: gemPortAttribs.gemPortID,
1475 me.GemPortNetworkCtp_TContPointer: oFsm.tcont0ID,
1476 me.GemPortNetworkCtp_Direction: gemPortAttribs.direction,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001477 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1478 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001479 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1480 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: gemPortAttribs.downQueueID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001481 },
1482 }
Holger Hildebrandtc408f492022-07-14 08:39:24 +00001483 if oFsm.techProfileType == cTechProfileTypeXgsPon {
1484 meParams.Attributes[me.GemPortNetworkCtp_EncryptionKeyRing] = GemEncryptKeyRingUnicastDownstreamOnly
1485 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001486 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001487 meInstance, err := oFsm.pOmciCC.SendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1488 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001489 if err != nil {
1490 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 logger.Errorw(ctx, "GemNCTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001492 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001493 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001494 return
1495 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001496 //accept also nil as (error) return value for writing to LastTx
1497 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001498 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001499 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001500 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001501 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001502 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001504 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001505 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001506 return
1507 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001508 // Mark the gem port to be added for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001509 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
1510 if OnuMetricsManager != nil {
1511 OnuMetricsManager.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001512 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001513 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001514
1515 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001518}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001519func (oFsm *UniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001520 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1521 if gemPortAttribs.isMulticast {
1522 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1523 return true
1524 }
1525 }
1526 return false
1527}
mpagenko3dbcdd22020-07-22 07:38:45 +00001528
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529func (oFsm *UniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001530 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1531 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001533 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1534 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001535 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001536
ozgecanetsia4b232302020-11-11 10:58:10 +03001537 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1538 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001539
1540 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001541 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001542 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001543 me.MulticastGemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.multicastGemID,
1544 me.MulticastGemInterworkingTerminationPoint_InterworkingOption: 0, // Don't Care
1545 me.MulticastGemInterworkingTerminationPoint_ServiceProfilePointer: 0, // Don't Care
1546 me.MulticastGemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001547 },
1548 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001549 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1550 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1551 continue
1552 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001553 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001554 meInstance, err := oFsm.pOmciCC.SendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1555 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001556 if err != nil {
1557 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001558 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001559 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001560 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001561 return
1562
1563 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001564 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001565 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001566 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001567 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001568 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001569 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001570 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001571 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001572 return
1573 }
1574 ipv4MulticastTable := make([]uint8, 12)
1575 //Gem Port ID
1576 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1577 //Secondary Key
1578 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1579 // Multicast IP range start This is the 224.0.0.1 address
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001580 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], cmn.IPToInt32(net.IPv4(224, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001581 // MulticastIp range stop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001582 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001583
1584 meIPV4MCTableParams := me.ParamData{
1585 EntityID: gemPortAttribs.multicastGemID,
1586 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001587 me.MulticastGemInterworkingTerminationPoint_Ipv4MulticastAddressTable: ipv4MulticastTable,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001588 },
1589 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001590 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001591 meIPV4MCTableInstance, err := oFsm.pOmciCC.SendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1592 true, oFsm.PAdaptFsm.CommChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001593 if err != nil {
1594 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001595 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001596 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001597 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001598 return
1599 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001600 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001601 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001602
1603 } else {
1604 meParams := me.ParamData{
1605 EntityID: gemPortAttribs.gemPortID,
1606 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001607 me.GemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.gemPortID, //same as EntityID, see above
1608 me.GemInterworkingTerminationPoint_InterworkingOption: 5, //fixed model:: G.998 .1pMapper
1609 me.GemInterworkingTerminationPoint_ServiceProfilePointer: oFsm.mapperSP0ID,
1610 me.GemInterworkingTerminationPoint_InterworkingTerminationPointPointer: 0, //not used with .1PMapper Mac bridge
1611 me.GemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001612 },
1613 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001614 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001615 meInstance, err := oFsm.pOmciCC.SendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1616 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001617 if err != nil {
1618 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001619 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001620 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001622 return
1623 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001624 //accept also nil as (error) return value for writing to LastTx
1625 // - this avoids misinterpretation of new received OMCI messages
1626 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001627 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001628 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001629 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001631 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001632 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001633 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001634 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001635 return
1636 }
1637 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001638
1639 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001641 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001642}
1643
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001644func (oFsm *UniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001645 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1646 if oFsm.tcontSetBefore {
1647 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1648 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001649 "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001650 "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 go func(aPAFsm *cmn.AdapterFsm) {
1652 if aPAFsm != nil && aPAFsm.PFsm != nil {
1653 _ = aPAFsm.PFsm.Event(aniEvRxPrioqsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001654 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001656 return
1657 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001658 const cu16StrictPrioWeight uint16 = 0xFFFF
1659 //find all upstream PrioQueues related to this T-Cont
1660 loQueueMap := ordered_map.NewOrderedMap()
1661 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001662 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001663 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001664 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1665 "prioString": gemPortAttribs.pbitString})
1666 continue
1667 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001668 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301669 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001670 //key does not yet exist
1671 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1672 }
1673 } else {
1674 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1675 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001676 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001677
Girish Gowdra09e5f212021-09-30 16:28:36 -07001678 trafficSchedPtrSetSupported := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001679 loOnu2g := oFsm.pOnuDB.GetMe(me.Onu2GClassID, cmn.Onu2gMeID)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001680 if loOnu2g == nil {
1681 logger.Errorw(ctx, "onu2g is nil, cannot read qos configuration flexibility parameter",
1682 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001684 return
1685 }
1686 returnVal := loOnu2g["QualityOfServiceQosConfigurationFlexibility"]
1687 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001688 if qosCfgFlexParam, err := oFsm.pOnuDB.GetUint16Attrib(returnVal); err == nil {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001689 trafficSchedPtrSetSupported = qosCfgFlexParam&bitTrafficSchedulerPtrSetPermitted == bitTrafficSchedulerPtrSetPermitted
1690 logger.Debugw(ctx, "trafficSchedPtrSetSupported set",
1691 log.Fields{"qosCfgFlexParam": qosCfgFlexParam, "trafficSchedPtrSetSupported": trafficSchedPtrSetSupported})
1692 } else {
1693 logger.Errorw(ctx, "Cannot extract qos configuration flexibility parameter",
1694 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001695 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001696 return
1697 }
1698 } else {
1699 logger.Errorw(ctx, "Cannot read qos configuration flexibility parameter",
1700 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001701 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001702 return
1703 }
1704
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001705 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1706 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1707 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1708 // or even be finished without correct SP/WRR setting
1709
1710 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1711 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1712 // even though its T-Cont seems to be wrong ...
1713 loTrafficSchedulerEID := 0x8000
1714 //for all found queues
1715 iter := loQueueMap.IterFunc()
1716 for kv, ok := iter(); ok; kv, ok = iter() {
1717 queueIndex := (kv.Key).(uint16)
1718 meParams := me.ParamData{
1719 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301720 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001721 }
Girish Gowdra09e5f212021-09-30 16:28:36 -07001722 if trafficSchedPtrSetSupported {
1723 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1724 //StrictPrio indication
1725 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
1726 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1727 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001728 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = 0 //ensure T-Cont defined StrictPrio scheduling
Girish Gowdra09e5f212021-09-30 16:28:36 -07001729 } else {
1730 //WRR indication
1731 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
1732 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1733 "Weight": kv.Value,
1734 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001735 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1736 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Girish Gowdra09e5f212021-09-30 16:28:36 -07001737 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001738 } else {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001739 // setting Traffic Scheduler (TS) pointer is not supported unless we point to another TS that points to the same TCONT.
1740 // 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.
1741 // 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.
1742 if (kv.Value).(uint16) == cu16StrictPrioWeight { // SP case, nothing to be done. Proceed to the next queue
1743 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio, traffic sched ptr set unsupported", log.Fields{
1744 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1745 "device-id": oFsm.deviceID})
1746 continue
1747 }
1748 // WRR case, update weight.
1749 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR, traffic sched ptr set unsupported", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001750 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1751 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001752 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001753 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001754 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001755 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001756 meInstance, err := oFsm.pOmciCC.SendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1757 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001758 if err != nil {
1759 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001760 logger.Errorw(ctx, "PrioQueueVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001761 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001762 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001763 return
1764 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001765 //accept also nil as (error) return value for writing to LastTx
1766 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001767 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001768 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001769
1770 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001771 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001772 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001774 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001775 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001776 return
1777 }
1778
1779 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1780 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1781 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1782 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1783
1784 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001785
1786 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001788 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001789}
1790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001791func (oFsm *UniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001792 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001793 if oFsm.isCanceled {
1794 // FSM already canceled before entering wait
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001795 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 +00001796 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001797 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00001798 }
mpagenko7d6bb022021-03-11 15:07:55 +00001799 oFsm.isAwaitingResponse = true
1800 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001801 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301802 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001803 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001804 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001805 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 +00001806 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001807 oFsm.mutexIsAwaitingResponse.Lock()
1808 oFsm.isAwaitingResponse = false
1809 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001810 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001811 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301812 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001813 logger.Debugw(ctx, "UniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001814 oFsm.mutexIsAwaitingResponse.Lock()
1815 oFsm.isAwaitingResponse = false
1816 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001817 return nil
1818 }
mpagenko7d6bb022021-03-11 15:07:55 +00001819 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001820 logger.Debugw(ctx, "UniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001821 oFsm.mutexIsAwaitingResponse.Lock()
1822 oFsm.isAwaitingResponse = false
1823 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001824 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001825 }
1826}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001827
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001828func (oFsm *UniPonAniConfigFsm) setChanSet(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001829 oFsm.mutexChanSet.Lock()
1830 oFsm.chanSet = flagValue
1831 oFsm.mutexChanSet.Unlock()
1832}
1833
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001834func (oFsm *UniPonAniConfigFsm) isChanSet() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001835 oFsm.mutexChanSet.RLock()
1836 flagValue := oFsm.chanSet
1837 oFsm.mutexChanSet.RUnlock()
1838 return flagValue
1839}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001840
1841// PrepareForGarbageCollection - remove references to prepare for garbage collection
1842func (oFsm *UniPonAniConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
1843 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": oFsm.deviceID})
1844 oFsm.pDeviceHandler = nil
1845 oFsm.pOnuDeviceEntry = nil
1846 oFsm.pOmciCC = nil
1847}