blob: 3e7be639239b87e36fb841f1a64bc3ecaa37f375 [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2020-2023 Open Networking Foundation (ONF) and the ONF Contributors
mpagenko3dbcdd22020-07-22 07:38:45 +00003 *
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)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000389 // Note: As we do not maintain any slot numbering, slot number will be excluded from search pattern.
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 // 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})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001268 // possibly force FSM into abort or ignore some errors for some messages?
1269 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1270 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
Himani Chawla4d908332020-08-31 12:30:20 +05301271 return
1272 }
Himani Chawla4d908332020-08-31 12:30:20 +05301273}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
Mahir Gunyel01034b62021-06-29 11:25:09 -07001275 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1276 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1277 oFsm.mutexPLastTxMeInstance.RLock()
1278 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1279 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1280 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1281 switch oFsm.pLastTxMeInstance.GetName() {
1282 case "TCont":
1283 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1284 //We should revert DB
1285 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1286 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1287 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 if oFsm.pOnuDeviceEntry != nil {
1289 oFsm.pOnuDeviceEntry.FreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001290 } else {
1291 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1292 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1293 }
1294 }
1295 default:
1296 logger.Warnw(ctx, "Unsupported ME name received with error!",
1297 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1298 }
1299 }
1300}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001301func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301302 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1303 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001304 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001305 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301306 return
1307 }
1308 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1309 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001310 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001311 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301312 return
1313 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301315 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001316 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001317 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001318 // possibly force FSM into abort or ignore some errors for some messages?
1319 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1320 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001321 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301322 return
1323 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001324 oFsm.mutexPLastTxMeInstance.RLock()
1325 if oFsm.pLastTxMeInstance != nil {
1326 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1327 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1328 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1329 // if, then something like:
1330 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301331
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001332 switch oFsm.pLastTxMeInstance.GetName() {
1333 case "TCont":
1334 { // let the FSM proceed ...
1335 oFsm.mutexPLastTxMeInstance.RUnlock()
1336 if oFsm.requestEventOffset == 0 { //from TCont config request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxTcontsResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001338 } else { // from T-Cont reset request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxResetTcontResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001340 }
1341 }
1342 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1343 { // let the PrioQueue init proceed by stopping the wait function
1344 oFsm.mutexPLastTxMeInstance.RUnlock()
1345 oFsm.omciMIdsResponseReceived <- true
1346 }
1347 case "Ieee8021PMapperServiceProfile":
1348 { // let the FSM proceed ...
1349 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001351 }
1352 default:
1353 {
1354 oFsm.mutexPLastTxMeInstance.RUnlock()
1355 logger.Warnw(ctx, "Unsupported ME name received!",
1356 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001357 }
Himani Chawla4d908332020-08-31 12:30:20 +05301358 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001359 } else {
1360 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301361 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001362 } else {
1363 oFsm.mutexPLastTxMeInstance.RUnlock()
1364 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301365 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001366}
1367
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001369 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1370 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001371 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001372 log.Fields{"device-id": oFsm.deviceID})
1373 return
1374 }
1375 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1376 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001377 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001378 log.Fields{"device-id": oFsm.deviceID})
1379 return
1380 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001382 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001383 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001384 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1385 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001386 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1387 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko8b07c1b2020-11-26 10:36:31 +00001388 return
1389 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001390 oFsm.mutexPLastTxMeInstance.RLock()
1391 if oFsm.pLastTxMeInstance != nil {
1392 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1393 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1394 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1395 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001396
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001397 switch oFsm.pLastTxMeInstance.GetName() {
1398 case "GemInterworkingTerminationPoint":
1399 { // let the FSM proceed ...
1400 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001401 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemiwResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001402 }
1403 case "GemPortNetworkCtp":
1404 { // let the FSM proceed ...
1405 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001406 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemntpResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001407 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001408 case "TrafficDescriptor":
1409 { // let the FSM proceed ...
1410 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemTdResp)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001412 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001413 case "Ieee8021PMapperServiceProfile":
1414 { // let the FSM proceed ...
1415 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001416 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRem1pMapperResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001417 }
1418 case "MacBridgePortConfigurationData":
1419 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1420 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001421 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemAniBPCDResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001422 }
1423 default:
1424 {
1425 oFsm.mutexPLastTxMeInstance.RUnlock()
1426 logger.Warnw(ctx, "Unsupported ME name received!",
1427 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1428 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001429 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001430 } else {
1431 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001432 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001433 } else {
1434 oFsm.mutexPLastTxMeInstance.RUnlock()
1435 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001436 }
1437}
1438
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001439func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001440 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001441 "msgType": msg.OmciMsg.MessageType})
1442
1443 switch msg.OmciMsg.MessageType {
1444 case omci.CreateResponseType:
1445 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301447
mpagenko3dbcdd22020-07-22 07:38:45 +00001448 } //CreateResponseType
1449 case omci.SetResponseType:
1450 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001452
mpagenko3dbcdd22020-07-22 07:38:45 +00001453 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001454 case omci.DeleteResponseType:
1455 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001457
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001458 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001459 default:
1460 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001461 logger.Errorw(ctx, "UniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001462 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001463 return
1464 }
1465 }
1466}
1467
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468func (oFsm *UniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001469 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1470 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001471 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001472 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1473 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001474 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001475 meParams := me.ParamData{
1476 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1477 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001478 me.GemPortNetworkCtp_PortId: gemPortAttribs.gemPortID,
1479 me.GemPortNetworkCtp_TContPointer: oFsm.tcont0ID,
1480 me.GemPortNetworkCtp_Direction: gemPortAttribs.direction,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001481 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1482 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001483 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1484 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: gemPortAttribs.downQueueID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001485 },
1486 }
Holger Hildebrandtc408f492022-07-14 08:39:24 +00001487 if oFsm.techProfileType == cTechProfileTypeXgsPon {
1488 meParams.Attributes[me.GemPortNetworkCtp_EncryptionKeyRing] = GemEncryptKeyRingUnicastDownstreamOnly
1489 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001490 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 meInstance, err := oFsm.pOmciCC.SendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1492 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001493 if err != nil {
1494 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001495 logger.Errorw(ctx, "GemNCTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001496 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001497 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001498 return
1499 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001500 //accept also nil as (error) return value for writing to LastTx
1501 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001502 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001503 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001504 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001505 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001506 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001508 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001509 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001510 return
1511 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001512 // Mark the gem port to be added for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001513 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
1514 if OnuMetricsManager != nil {
1515 OnuMetricsManager.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001516 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001517 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001518
1519 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001520 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001521 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001522}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001523func (oFsm *UniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001524 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1525 if gemPortAttribs.isMulticast {
1526 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1527 return true
1528 }
1529 }
1530 return false
1531}
mpagenko3dbcdd22020-07-22 07:38:45 +00001532
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001533func (oFsm *UniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001534 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1535 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001536 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001537 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1538 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001539 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001540
ozgecanetsia4b232302020-11-11 10:58:10 +03001541 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1542 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001543
1544 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001545 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001546 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001547 me.MulticastGemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.multicastGemID,
1548 me.MulticastGemInterworkingTerminationPoint_InterworkingOption: 0, // Don't Care
1549 me.MulticastGemInterworkingTerminationPoint_ServiceProfilePointer: 0, // Don't Care
1550 me.MulticastGemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001551 },
1552 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001553 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1554 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1555 continue
1556 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001557 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001558 meInstance, err := oFsm.pOmciCC.SendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1559 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001560 if err != nil {
1561 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001562 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001563 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001564 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001565 return
1566
1567 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001568 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001569 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001570 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001571 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001572 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001573 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001574 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001576 return
1577 }
1578 ipv4MulticastTable := make([]uint8, 12)
1579 //Gem Port ID
1580 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1581 //Secondary Key
1582 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1583 // Multicast IP range start This is the 224.0.0.1 address
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001584 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], cmn.IPToInt32(net.IPv4(224, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001585 // MulticastIp range stop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001586 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001587
1588 meIPV4MCTableParams := me.ParamData{
1589 EntityID: gemPortAttribs.multicastGemID,
1590 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001591 me.MulticastGemInterworkingTerminationPoint_Ipv4MulticastAddressTable: ipv4MulticastTable,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001592 },
1593 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001594 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001595 meIPV4MCTableInstance, err := oFsm.pOmciCC.SendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1596 true, oFsm.PAdaptFsm.CommChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001597 if err != nil {
1598 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001599 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001600 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001602 return
1603 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001604 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001605 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001606
1607 } else {
1608 meParams := me.ParamData{
1609 EntityID: gemPortAttribs.gemPortID,
1610 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001611 me.GemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.gemPortID, //same as EntityID, see above
1612 me.GemInterworkingTerminationPoint_InterworkingOption: 5, //fixed model:: G.998 .1pMapper
1613 me.GemInterworkingTerminationPoint_ServiceProfilePointer: oFsm.mapperSP0ID,
1614 me.GemInterworkingTerminationPoint_InterworkingTerminationPointPointer: 0, //not used with .1PMapper Mac bridge
1615 me.GemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001616 },
1617 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001618 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001619 meInstance, err := oFsm.pOmciCC.SendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1620 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001621 if err != nil {
1622 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001624 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001625 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001626 return
1627 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001628 //accept also nil as (error) return value for writing to LastTx
1629 // - this avoids misinterpretation of new received OMCI messages
1630 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001631 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001632 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001633 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001635 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001637 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001638 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001639 return
1640 }
1641 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001642
1643 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001645 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001646}
1647
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001648func (oFsm *UniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001649 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1650 if oFsm.tcontSetBefore {
1651 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1652 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001653 "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001654 "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 go func(aPAFsm *cmn.AdapterFsm) {
1656 if aPAFsm != nil && aPAFsm.PFsm != nil {
1657 _ = aPAFsm.PFsm.Event(aniEvRxPrioqsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001658 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001659 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001660 return
1661 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001662 const cu16StrictPrioWeight uint16 = 0xFFFF
1663 //find all upstream PrioQueues related to this T-Cont
1664 loQueueMap := ordered_map.NewOrderedMap()
1665 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001666 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001667 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001668 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1669 "prioString": gemPortAttribs.pbitString})
1670 continue
1671 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001672 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301673 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001674 //key does not yet exist
1675 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1676 }
1677 } else {
1678 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1679 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001680 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001681
Girish Gowdra09e5f212021-09-30 16:28:36 -07001682 trafficSchedPtrSetSupported := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 loOnu2g := oFsm.pOnuDB.GetMe(me.Onu2GClassID, cmn.Onu2gMeID)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001684 if loOnu2g == nil {
1685 logger.Errorw(ctx, "onu2g is nil, cannot read qos configuration flexibility parameter",
1686 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001688 return
1689 }
1690 returnVal := loOnu2g["QualityOfServiceQosConfigurationFlexibility"]
1691 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001692 if qosCfgFlexParam, err := oFsm.pOnuDB.GetUint16Attrib(returnVal); err == nil {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001693 trafficSchedPtrSetSupported = qosCfgFlexParam&bitTrafficSchedulerPtrSetPermitted == bitTrafficSchedulerPtrSetPermitted
1694 logger.Debugw(ctx, "trafficSchedPtrSetSupported set",
1695 log.Fields{"qosCfgFlexParam": qosCfgFlexParam, "trafficSchedPtrSetSupported": trafficSchedPtrSetSupported})
1696 } else {
1697 logger.Errorw(ctx, "Cannot extract qos configuration flexibility parameter",
1698 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001700 return
1701 }
1702 } else {
1703 logger.Errorw(ctx, "Cannot read qos configuration flexibility parameter",
1704 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001705 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001706 return
1707 }
1708
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001709 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1710 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1711 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1712 // or even be finished without correct SP/WRR setting
1713
1714 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1715 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1716 // even though its T-Cont seems to be wrong ...
1717 loTrafficSchedulerEID := 0x8000
1718 //for all found queues
1719 iter := loQueueMap.IterFunc()
1720 for kv, ok := iter(); ok; kv, ok = iter() {
1721 queueIndex := (kv.Key).(uint16)
1722 meParams := me.ParamData{
1723 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301724 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001725 }
Girish Gowdra09e5f212021-09-30 16:28:36 -07001726 if trafficSchedPtrSetSupported {
1727 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1728 //StrictPrio indication
1729 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
1730 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1731 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001732 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = 0 //ensure T-Cont defined StrictPrio scheduling
Girish Gowdra09e5f212021-09-30 16:28:36 -07001733 } else {
1734 //WRR indication
1735 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
1736 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1737 "Weight": kv.Value,
1738 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001739 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1740 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Girish Gowdra09e5f212021-09-30 16:28:36 -07001741 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001742 } else {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001743 // setting Traffic Scheduler (TS) pointer is not supported unless we point to another TS that points to the same TCONT.
1744 // 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.
1745 // 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.
1746 if (kv.Value).(uint16) == cu16StrictPrioWeight { // SP case, nothing to be done. Proceed to the next queue
1747 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio, traffic sched ptr set unsupported", log.Fields{
1748 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1749 "device-id": oFsm.deviceID})
1750 continue
1751 }
1752 // WRR case, update weight.
1753 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR, traffic sched ptr set unsupported", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001754 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1755 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001756 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001757 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001758 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001759 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001760 meInstance, err := oFsm.pOmciCC.SendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1761 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001762 if err != nil {
1763 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001764 logger.Errorw(ctx, "PrioQueueVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001765 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001766 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001767 return
1768 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001769 //accept also nil as (error) return value for writing to LastTx
1770 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001771 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001772 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001773
1774 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001775 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001776 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001778 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001779 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001780 return
1781 }
1782
1783 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1784 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1785 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1786 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1787
1788 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001789
1790 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001792 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001793}
1794
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001795func (oFsm *UniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001796 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001797 if oFsm.isCanceled {
1798 // FSM already canceled before entering wait
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001799 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 +00001800 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001801 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00001802 }
mpagenko7d6bb022021-03-11 15:07:55 +00001803 oFsm.isAwaitingResponse = true
1804 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001805 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301806 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001807 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001808 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001809 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 +00001810 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001811 oFsm.mutexIsAwaitingResponse.Lock()
1812 oFsm.isAwaitingResponse = false
1813 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001814 oFsm.mutexPLastTxMeInstance.RLock()
1815 if oFsm.pLastTxMeInstance != nil {
1816 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
1817 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
1818 }
1819 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001820 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001821 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301822 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001823 logger.Debugw(ctx, "UniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001824 oFsm.mutexIsAwaitingResponse.Lock()
1825 oFsm.isAwaitingResponse = false
1826 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001827 return nil
1828 }
mpagenko7d6bb022021-03-11 15:07:55 +00001829 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001830 logger.Debugw(ctx, "UniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001831 oFsm.mutexIsAwaitingResponse.Lock()
1832 oFsm.isAwaitingResponse = false
1833 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001834 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001835 }
1836}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001837
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838func (oFsm *UniPonAniConfigFsm) setChanSet(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001839 oFsm.mutexChanSet.Lock()
1840 oFsm.chanSet = flagValue
1841 oFsm.mutexChanSet.Unlock()
1842}
1843
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001844func (oFsm *UniPonAniConfigFsm) isChanSet() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001845 oFsm.mutexChanSet.RLock()
1846 flagValue := oFsm.chanSet
1847 oFsm.mutexChanSet.RUnlock()
1848 return flagValue
1849}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001850
1851// PrepareForGarbageCollection - remove references to prepare for garbage collection
1852func (oFsm *UniPonAniConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
1853 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": oFsm.deviceID})
1854 oFsm.pDeviceHandler = nil
1855 oFsm.pOnuDeviceEntry = nil
1856 oFsm.pOmciCC = nil
1857}