blob: bbcc41a73bd87e3ec9eebb16bc69c925d956efdc [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +053017// Package avcfg provides anig and vlan configuration functionality
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package 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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530128// UniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000129type 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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530163// NewUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000164func 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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530281// 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) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530283 logger.Info(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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530328// 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 }
bseenivaeba8eb12024-12-13 11:54:28 +0530352 // Access critical state with lock
353 oFsm.pUniTechProf.mutexTPState.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000354 tcontInstID, tcontAlreadyExist, err := oFsm.pOnuDeviceEntry.AllocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700355 if err != nil {
356 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700357 //reset the state machine to enable usage on subsequent requests
bseenivaeba8eb12024-12-13 11:54:28 +0530358 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000359 _ = aPAFsm.PFsm.Event(aniEvReset)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700360 return
361 }
362 oFsm.tcont0ID = tcontInstID
363 oFsm.tcontSetBefore = tcontAlreadyExist
364 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
365 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
366 "tcontAlreadyExist": tcontAlreadyExist,
367 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800368
mpagenko8b07c1b2020-11-26 10:36:31 +0000369 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
370 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko3ce9fa02021-07-28 13:26:54 +0000371 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800372
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800374 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300375 loGemPortAttribs := ponAniGemPortAttribs{}
376
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
378
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 if queueInstKeys := oFsm.pOnuDB.GetSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530380
381 loGemPortAttribs.gemPortID = gemEntry.gemPortID
382 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
383 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
384 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
385 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
386
387 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.UniID,
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000390 // Note: As we do not maintain any slot numbering, slot number will be excluded from search pattern.
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.UniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
Himani Chawla26e555c2020-08-31 12:30:20 +0530393
394 usQueueFound := false
395 dsQueueFound := false
396 for _, mgmtEntityID := range queueInstKeys {
397 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000398 returnVal := meAttributes[me.PriorityQueue_RelatedPort]
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000400 if relatedPort, err := oFsm.pOnuDB.GetUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 if relatedPort == usQrelPortMask {
402 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000403 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000404 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 usQueueFound = true
406 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
407 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000408 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000409 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 dsQueueFound = true
411 }
412 if usQueueFound && dsQueueFound {
413 break
414 }
415 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000416 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530417 }
418 } else {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000419 logger.Warnw(ctx, "PrioQueue.RelatedPort not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530420 }
421 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000422 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000423 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530424 }
425 }
426 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530428 }
429 loGemPortAttribs.direction = gemEntry.direction
430 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
431 loGemPortAttribs.weight = gemEntry.queueWeight
432 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300433
ozgecanetsia4b232302020-11-11 10:58:10 +0300434 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300435 //TODO this might effectively ignore the for loop starting at line 316
436 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300437 loGemPortAttribs.isMulticast = true
438 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
439 loGemPortAttribs.staticACL = gemEntry.staticACL
440 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530441
dbainbri4d3a0dc2020-12-02 00:33:42 +0000442 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300443 "gemPortID": loGemPortAttribs.gemPortID,
444 "isMulticast": loGemPortAttribs.isMulticast,
445 "multicastGemID": loGemPortAttribs.multicastGemID,
446 "staticACL": loGemPortAttribs.staticACL,
447 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000448 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300449 })
450
451 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000452 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300453 "gemPortID": loGemPortAttribs.gemPortID,
454 "upQueueID": loGemPortAttribs.upQueueID,
455 "downQueueID": loGemPortAttribs.downQueueID,
456 "pbitString": loGemPortAttribs.pbitString,
457 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000458 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300459 })
460 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530461
462 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530463 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
464 meParams := me.ParamData{
465 EntityID: loGemPortAttribs.gemPortID,
466 Attributes: me.AttributeValueMap{
467 me.GemPortNetworkCtp_PortId: loGemPortAttribs.gemPortID,
468 me.GemPortNetworkCtp_TContPointer: oFsm.tcont0ID,
469 me.GemPortNetworkCtp_Direction: loGemPortAttribs.direction,
470 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: loGemPortAttribs.upQueueID,
471 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: loGemPortAttribs.downQueueID,
472 },
473 }
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +0530474 oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemPortNetworkCtpClassID, loGemPortAttribs.gemPortID, meParams.Attributes)
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530475 var meAttributes me.AttributeValueMap //dummy , anyways we are not going to use the values.
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +0530476 oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID, loGemPortAttribs.gemPortID, meAttributes)
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530477
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +0530478 oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemInterworkingTerminationPointClassID, loGemPortAttribs.gemPortID, meAttributes)
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530479
480 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
483 _ = aPAFsm.PFsm.Event(aniEvStartConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000484 } else {
485 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000486 _ = aPAFsm.PFsm.Event(aniEvSkipOmciConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000487 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 }
489}
490
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000491func (oFsm *UniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530492 logger.Info(ctx, "UniPonAniConfigFsm start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000494 // in case the used channel is not yet defined (can be re-used after restarts)
495 if oFsm.omciMIdsResponseReceived == nil {
496 oFsm.omciMIdsResponseReceived = make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 logger.Debug(ctx, "UniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000498 } else {
499 // as we may 're-use' this instance of FSM and the connected channel
500 // make sure there is no 'lingering' request in the already existing channel:
501 // (simple loop sufficient as we are the only receiver)
502 for len(oFsm.omciMIdsResponseReceived) > 0 {
503 <-oFsm.omciMIdsResponseReceived
504 }
505 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000506 //ensure internal slices are empty (which might be set from previous run) - release memory
507 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000508 oFsm.mutexIsAwaitingResponse.Lock()
509 //reset the canceled state possibly existing from previous reset
510 oFsm.isCanceled = false
511 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000512
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000513 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000515
516 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000517 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000518 if pConfigAniStateAFsm != nil {
519 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000520 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000521
mpagenko3dbcdd22020-07-22 07:38:45 +0000522 }
523}
524
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000525func (oFsm *UniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
526 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000527 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000528 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000529 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000530 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 meInstance, err := oFsm.pOmciCC.SendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
532 oFsm.mapperSP0ID, oFsm.PAdaptFsm.CommChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300533 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000534 logger.Errorw(ctx, "Dot1PMapper create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300535 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000536 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300537 if pConfigAniStateAFsm != nil {
538 oFsm.mutexPLastTxMeInstance.Unlock()
539 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 go func(aPAFsm *cmn.AdapterFsm) {
541 if aPAFsm != nil && aPAFsm.PFsm != nil {
542 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300543 }
544 }(pConfigAniStateAFsm)
545 return
546 }
547 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000548 //accept also nil as (error) return value for writing to LastTx
549 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000550 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300551 oFsm.mutexPLastTxMeInstance.Unlock()
552
mpagenko3dbcdd22020-07-22 07:38:45 +0000553}
554
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000555func (oFsm *UniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530556 logger.Info(ctx, "Creating Tx MAC Bridge Port Config Data", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000557 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
558 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000559 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
560 bridgePtr := cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
mpagenko3dbcdd22020-07-22 07:38:45 +0000561 meParams := me.ParamData{
562 EntityID: oFsm.macBPCD0ID,
563 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000564 me.MacBridgePortConfigurationData_BridgeIdPointer: bridgePtr,
565 me.MacBridgePortConfigurationData_PortNum: 0xFF, //fixed unique ANI side indication
566 me.MacBridgePortConfigurationData_TpType: 3, //for .1PMapper
567 me.MacBridgePortConfigurationData_TpPointer: oFsm.mapperSP0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000568 },
569 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000570 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
572 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300573 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000574 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300575 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300577 if pConfigAniStateAFsm != nil {
578 oFsm.mutexPLastTxMeInstance.Unlock()
579 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 go func(aPAFsm *cmn.AdapterFsm) {
581 if aPAFsm != nil && aPAFsm.PFsm != nil {
582 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300583 }
584 }(pConfigAniStateAFsm)
585 return
586 }
587 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000588 //accept also nil as (error) return value for writing to LastTx
589 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000590 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300591 oFsm.mutexPLastTxMeInstance.Unlock()
592
mpagenko3dbcdd22020-07-22 07:38:45 +0000593}
594
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595func (oFsm *UniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530596 logger.Info(ctx, "Tx Setting Tcont ", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000597 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
598 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700600 "tcontExist": oFsm.tcontSetBefore})
601 //If tcont was set before, then no need to set it again. Let state machine to proceed.
602 if oFsm.tcontSetBefore {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000603 go func(aPAFsm *cmn.AdapterFsm) {
604 if aPAFsm != nil && aPAFsm.PFsm != nil {
605 _ = aPAFsm.PFsm.Event(aniEvRxTcontsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700606 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700608 return
609 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000610 meParams := me.ParamData{
611 EntityID: oFsm.tcont0ID,
612 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000613 me.TCont_AllocId: oFsm.alloc0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000614 },
615 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000616 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000617 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
618 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300619 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000620 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300621 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000622 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300623 if pConfigAniStateAFsm != nil {
624 oFsm.mutexPLastTxMeInstance.Unlock()
625 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000626 go func(aPAFsm *cmn.AdapterFsm) {
627 if aPAFsm != nil && aPAFsm.PFsm != nil {
628 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300629 }
630 }(pConfigAniStateAFsm)
631 return
632 }
633 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000634 //accept also nil as (error) return value for writing to LastTx
635 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000636 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300637 oFsm.mutexPLastTxMeInstance.Unlock()
638
mpagenko3dbcdd22020-07-22 07:38:45 +0000639}
640
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641func (oFsm *UniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530642 logger.Info(ctx, "UniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000643 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000644 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000645}
646
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000647func (oFsm *UniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530648 logger.Info(ctx, "UniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000649 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000651}
652
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000653func (oFsm *UniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530654 logger.Info(ctx, "UniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000655 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000657}
658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659func (oFsm *UniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300660
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530661 logger.Info(ctx, "UniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000662 "toGemIw": 1024, /* cmp above */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000663 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000664
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530665 logger.Info(ctx, "UniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000666 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000667 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000668
mpagenko3dbcdd22020-07-22 07:38:45 +0000669 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000670 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530671 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000672 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000673
674 //assign the GemPorts according to the configured Prio
675 var loPrioGemPortArray [8]uint16
676 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300677 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300679 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
680 "prioString": gemPortAttribs.pbitString})
681 continue
682 }
683 if gemPortAttribs.pbitString == "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000684 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300685 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
686 "prioString": gemPortAttribs.pbitString})
687 continue
688 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000689 for i := 0; i < 8; i++ {
690 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
691 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
692 if prio == 1 { // Check this p-bit is set
693 if loPrioGemPortArray[i] == 0 {
694 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
695 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000696 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000697 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000698 "SetGemPort": loPrioGemPortArray[i]})
699 }
700 }
701 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000702 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000703 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000704 "prioString": gemPortAttribs.pbitString, "position": i})
705 }
706
707 }
708 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300709
ozgecanetsia4b232302020-11-11 10:58:10 +0300710 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530711 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300712 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530713 if value != 0 {
714 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530715 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000717 "for Prio": index,
718 "IwPtr": strconv.FormatInt(int64(value), 16),
719 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300720 } else {
721 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000722 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
723 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300724 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530725 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000726 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300727 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000728 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
729 // but except for processing effort does not really harm - left to keep changes low
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000730 meParams.Attributes[me.Ieee8021PMapperServiceProfile_TpPointer] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530731
732 if !foundIwPtr {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530733 logger.Warn(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000734 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300735 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
736 // 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 +0000737 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000738 //pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300739 //if pConfigAniStateAFsm != nil {
740 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000741 // go func(aPAFsm *cmn.AdapterFsm) {
742 // if aPAFsm != nil && aPAFsm.PFsm != nil {
743 // _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300744 // }
745 // }(pConfigAniStateAFsm)
746 //}
747 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000748 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000749 if pConfigAniStateAFsm != nil {
750 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000751 go func(aPAFsm *cmn.AdapterFsm) {
752 if aPAFsm != nil && aPAFsm.PFsm != nil {
753 _ = aPAFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000754 }
755 }(pConfigAniStateAFsm)
756 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300757 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000758 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000759 meInstance, err := oFsm.pOmciCC.SendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
760 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300761 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000762 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300763 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000764 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300765 if pConfigAniStateAFsm != nil {
766 oFsm.mutexPLastTxMeInstance.Unlock()
767 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000768 go func(aPAFsm *cmn.AdapterFsm) {
769 if aPAFsm != nil && aPAFsm.PFsm != nil {
770 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300771 }
772 }(pConfigAniStateAFsm)
773 return
774 }
775 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300776 //accept also nil as (error) return value for writing to LastTx
777 // - this avoids misinterpretation of new received OMCI messages
778 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300779 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000780 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000781}
782
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000783func (oFsm *UniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530784 logger.Info(ctx, "UniPonAniConfigFsm ani config done", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000786 //store that the UNI related techProfile processing is done for the given Profile and Uni
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000787 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
788 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000789 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000790 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000791 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
792 // but only in case the techProfile was configured (not deleted)
793 if oFsm.requestEventOffset == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000794 go oFsm.pDeviceHandler.VerifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000795 }
796 } else {
797 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000798 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000799 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000800 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000801 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000802 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
803 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000804 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000805 }
mpagenko01e726e2020-10-23 09:45:29 +0000806
807 //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 +0000808}
809
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000810func (oFsm *UniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000811 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
812 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000813 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
814 select {
815 case <-oFsm.waitFlowDeleteChannel:
816 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
817 default:
818 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000819
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820 uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.UniID)
821 if uniVlanConfigFsm != nil {
mpagenko3ce9fa02021-07-28 13:26:54 +0000822 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000823 if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000824 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000825 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000826 // 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 +0000827 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000828 if pConfigAniStateAFsm != nil {
829 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000830 go func(aPAFsm *cmn.AdapterFsm) {
831 if aPAFsm != nil && aPAFsm.PFsm != nil {
832 _ = aPAFsm.PFsm.Event(aniEvWaitFlowRem)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000833 }
834 }(pConfigAniStateAFsm)
835 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836 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 +0000837 }
838 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800839 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000840 } else {
841 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
842 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800843 }
844
mpagenko3ce9fa02021-07-28 13:26:54 +0000845 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000846 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000847 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000848 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000849 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
850 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000851 "GemIwTp-entity-id": loGemPortID})
852 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
853
854 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000855 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 meInstance, err := oFsm.pOmciCC.SendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
857 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300858 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 logger.Errorw(ctx, "GemIWTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300860 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300862 if pConfigAniStateAFsm != nil {
863 oFsm.mutexPLastTxMeInstance.Unlock()
864 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000865 go func(aPAFsm *cmn.AdapterFsm) {
866 if aPAFsm != nil && aPAFsm.PFsm != nil {
867 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300868 }
869 }(pConfigAniStateAFsm)
870 return
871 }
872 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000873 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300874 oFsm.mutexPLastTxMeInstance.Unlock()
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530875 logger.Infow(ctx, "Deleting GemIWTP at the ONU DB ", log.Fields{"device-id": oFsm.deviceID, "GEMID": loGemPortID})
876 oFsm.pOnuDB.DeleteMe(me.GemInterworkingTerminationPointClassID, loGemPortID)
mpagenko8b07c1b2020-11-26 10:36:31 +0000877}
878
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000879func (oFsm *UniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
mpagenkobb47bc22021-04-20 13:29:09 +0000880 oFsm.mutexIsAwaitingResponse.Lock()
881 oFsm.isWaitingForFlowDelete = true
882 oFsm.mutexIsAwaitingResponse.Unlock()
883 select {
884 // maybe be also some outside cancel (but no context modeled for the moment ...)
885 // case <-ctx.Done():
886 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000887 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 +0000888 logger.Warnw(ctx, "UniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
889 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000890 oFsm.mutexIsAwaitingResponse.Lock()
891 oFsm.isWaitingForFlowDelete = false
892 oFsm.mutexIsAwaitingResponse.Unlock()
893 //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 +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 case success := <-oFsm.waitFlowDeleteChannel:
909 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000910 logger.Debugw(ctx, "UniPonAniConfigFsm flow removed info received", log.Fields{
911 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000912 oFsm.mutexIsAwaitingResponse.Lock()
913 oFsm.isWaitingForFlowDelete = false
914 oFsm.mutexIsAwaitingResponse.Unlock()
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(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000921 }
922 }(pConfigAniStateAFsm)
923 } else {
924 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000925 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000926 }
927 return
928 }
929 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 logger.Debugw(ctx, "UniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
931 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000932 oFsm.mutexIsAwaitingResponse.Lock()
933 oFsm.isWaitingForFlowDelete = false
934 oFsm.mutexIsAwaitingResponse.Unlock()
935 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000936 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000937 if pConfigAniStateAFsm != nil {
938 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000939 go func(aPAFsm *cmn.AdapterFsm) {
940 if aPAFsm != nil && aPAFsm.PFsm != nil {
941 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenkobb47bc22021-04-20 13:29:09 +0000942 }
943 }(pConfigAniStateAFsm)
944 }
945 return
946 }
947}
948
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000949func (oFsm *UniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000950 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000951 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000952 oFsm.pUniTechProf.mutexTPState.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530953 logger.Info(ctx, "UniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000955 "GemNCTP-entity-id": loGemPortID})
956 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000957 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 meInstance, err := oFsm.pOmciCC.SendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
959 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300960 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000961 logger.Errorw(ctx, "GemNCTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300962 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000963 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300964 if pConfigAniStateAFsm != nil {
965 oFsm.mutexPLastTxMeInstance.Unlock()
966 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 go func(aPAFsm *cmn.AdapterFsm) {
968 if aPAFsm != nil && aPAFsm.PFsm != nil {
969 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300970 }
971 }(pConfigAniStateAFsm)
972 return
973 }
974 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000975 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000976 oFsm.mutexPLastTxMeInstance.Unlock()
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530977 oFsm.pOnuDB.DeleteMe(me.GemPortNetworkCtpClassID, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800978 // Mark the gem port to be removed for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
980 if OnuMetricsManager != nil {
981 OnuMetricsManager.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800982 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000983}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984func (oFsm *UniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000985 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300986 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000987 oFsm.pUniTechProf.mutexTPState.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530988 logger.Info(ctx, "UniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000989 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300990 "TD-entity-id": loGemPortID})
991
992 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 meInstance, err := oFsm.pOmciCC.SendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
994 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300995
996 if err != nil {
997 logger.Errorw(ctx, "TD delete failed - proceed fsm",
998 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001000 if pConfigAniStateAFsm != nil {
1001 oFsm.mutexPLastTxMeInstance.Unlock()
1002 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001003 go func(aPAFsm *cmn.AdapterFsm) {
1004 if aPAFsm != nil && aPAFsm.PFsm != nil {
1005 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001006 }
1007 }(pConfigAniStateAFsm)
1008 return
1009 }
1010 }
1011 oFsm.pLastTxMeInstance = meInstance
1012 oFsm.mutexPLastTxMeInstance.Unlock()
1013}
mpagenko8b07c1b2020-11-26 10:36:31 +00001014
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015func (oFsm *UniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301016 logger.Info(ctx, "UniPonAniConfigFsm - start resetting the TCont", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001018
1019 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
1020 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
1021 meParams := me.ParamData{
1022 EntityID: oFsm.tcont0ID,
1023 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001024 me.TCont_AllocId: cmn.UnusedTcontAllocID,
mpagenko8b07c1b2020-11-26 10:36:31 +00001025 },
1026 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001027 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1029 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001030 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001032 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001033 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001034 if pConfigAniStateAFsm != nil {
1035 oFsm.mutexPLastTxMeInstance.Unlock()
1036 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001037 go func(aPAFsm *cmn.AdapterFsm) {
1038 if aPAFsm != nil && aPAFsm.PFsm != nil {
1039 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001040 }
1041 }(pConfigAniStateAFsm)
1042 return
1043 }
1044 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001045 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001046 oFsm.mutexPLastTxMeInstance.Unlock()
1047
mpagenko8b07c1b2020-11-26 10:36:31 +00001048}
1049
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001050func (oFsm *UniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301051 logger.Info(ctx, "UniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
bseenivaeba8eb12024-12-13 11:54:28 +05301053 var mapGemPortParams map[uint16]*gemPortParamStruct
Mahir Gunyel9545be22021-07-04 15:53:16 -07001054 unicastGemCount := 0
bseenivaeba8eb12024-12-13 11:54:28 +05301055 oFsm.pUniTechProf.mutexTPState.RLock()
1056 if _, ok := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey]; ok {
1057 mapGemPortParams = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1058 } else {
1059 logger.Warnw(ctx, "GemPortParams not found in mapPonAniConfig", log.Fields{"device-id": oFsm.deviceID,
1060 "uni-id": oFsm.pOnuUniPort.UniID})
1061 }
1062 oFsm.pUniTechProf.mutexTPState.RUnlock()
Mahir Gunyel9545be22021-07-04 15:53:16 -07001063 for _, gemEntry := range mapGemPortParams {
1064 if !gemEntry.isMulticast {
1065 unicastGemCount++
1066 }
1067 }
1068 if unicastGemCount > 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001069 logger.Debugw(ctx, "UniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1070 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1071 pConfigAniStateAFsm := oFsm.PAdaptFsm
Mahir Gunyel9545be22021-07-04 15:53:16 -07001072 if pConfigAniStateAFsm != nil {
1073 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 go func(aPAFsm *cmn.AdapterFsm) {
1075 if aPAFsm != nil && aPAFsm.PFsm != nil {
1076 _ = aPAFsm.PFsm.Event(aniEvRemGemDone)
Mahir Gunyel9545be22021-07-04 15:53:16 -07001077 }
1078 }(pConfigAniStateAFsm)
1079 return
1080 }
1081 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 logger.Debugw(ctx, "UniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1083 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001084
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001085 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001086 meInstance, err := oFsm.pOmciCC.SendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1087 oFsm.PAdaptFsm.CommChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001088 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001089 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001090 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001091 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001092 if pConfigAniStateAFsm != nil {
1093 oFsm.mutexPLastTxMeInstance.Unlock()
1094 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001095 go func(aPAFsm *cmn.AdapterFsm) {
1096 if aPAFsm != nil && aPAFsm.PFsm != nil {
1097 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001098 }
1099 }(pConfigAniStateAFsm)
1100 return
1101 }
1102 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001103 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001104 oFsm.mutexPLastTxMeInstance.Unlock()
1105
mpagenko8b07c1b2020-11-26 10:36:31 +00001106}
1107
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001108func (oFsm *UniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301109 logger.Info(ctx, "UniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001110 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001111
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001112 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113 meInstance, err := oFsm.pOmciCC.SendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1114 oFsm.PAdaptFsm.CommChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001115 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001116 logger.Errorw(ctx, "MBPConfigData delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001117 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001118 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001119 if pConfigAniStateAFsm != nil {
1120 oFsm.mutexPLastTxMeInstance.Unlock()
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)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001125 }
1126 }(pConfigAniStateAFsm)
1127 return
1128 }
1129 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001130 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001131 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001132}
1133
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001134func (oFsm *UniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301135 logger.Info(ctx, "UniPonAniConfigFsm ani removal done", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001136 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001137 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001138 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001139 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001140 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001141 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001142 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1143 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001144 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001145 }
1146
1147 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001148 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko8b07c1b2020-11-26 10:36:31 +00001149 if pConfigAniStateAFsm != nil {
1150 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001151 go func(aPAFsm *cmn.AdapterFsm) {
1152 if aPAFsm != nil && aPAFsm.PFsm != nil {
1153 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenko8b07c1b2020-11-26 10:36:31 +00001154 }
1155 }(pConfigAniStateAFsm)
1156 }
1157}
1158
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001159func (oFsm *UniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1160 logger.Debugw(ctx, "UniPonAniConfigFsm resetting", log.Fields{
1161 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001162
mpagenko45cc6a32021-07-23 10:06:57 +00001163 if oFsm.isChanSet() {
1164 // indicate processing error to the caller (in case there was still some open request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001165 logger.Debugw(ctx, "UniPonAniConfigFsm processingError on channel", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001166 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1167 //use non-blocking channel send to avoid blocking because of non-existing receiver
1168 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1169 select {
1170 case oFsm.chSuccess <- 0:
1171 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001172 logger.Debugw(ctx, "UniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001173 "device-id": oFsm.deviceID})
1174 }
1175 oFsm.setChanSet(false) //reset the internal channel state
1176 }
1177
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +00001179 if pConfigAniStateAFsm != nil {
1180 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001181 fsmAbortMsg := cmn.Message{
1182 Type: cmn.TestMsg,
1183 Data: cmn.TestMessage{
1184 TestMessageVal: cmn.AbortMessageProcessing,
mpagenko3dbcdd22020-07-22 07:38:45 +00001185 },
1186 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001187 pConfigAniStateAFsm.CommChan <- fsmAbortMsg
mpagenko3dbcdd22020-07-22 07:38:45 +00001188
1189 //try to restart the FSM to 'disabled', decouple event transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001190 go func(aPAFsm *cmn.AdapterFsm) {
1191 if aPAFsm != nil && aPAFsm.PFsm != nil {
1192 _ = aPAFsm.PFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001193 }
1194 }(pConfigAniStateAFsm)
1195 }
1196}
1197
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001198func (oFsm *UniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1199 logger.Debugw(ctx, "UniPonAniConfigFsm enters disabled state", log.Fields{
1200 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001201 oFsm.mutexPLastTxMeInstance.Lock()
1202 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001203 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001204}
1205
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001206func (oFsm *UniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301207 logger.Info(ctx, "Start UniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001208loop:
1209 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001210 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001211 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001212 // break loop
bseenivaeba8eb12024-12-13 11:54:28 +05301213 select {
1214 case message, ok := <-oFsm.PAdaptFsm.CommChan:
1215 if !ok {
1216 logger.Warn(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
1217 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1218 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
mpagenko3dbcdd22020-07-22 07:38:45 +00001219 break loop
1220 }
bseenivaeba8eb12024-12-13 11:54:28 +05301221 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
1222
1223 switch message.Type {
1224 case cmn.TestMsg:
1225 msg, _ := message.Data.(cmn.TestMessage)
1226 if msg.TestMessageVal == cmn.AbortMessageProcessing {
1227 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
1228 break loop
1229 }
1230 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
1231 case cmn.OMCI:
1232 msg, _ := message.Data.(cmn.OmciMessage)
1233 oFsm.handleOmciAniConfigMessage(ctx, msg)
1234 default:
1235 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
1236 "message.Type": message.Type})
1237 }
1238 case _, ok := <-oFsm.pDeviceHandler.GetDeviceDeleteCommChan(ctx):
1239 if !ok {
1240 logger.Warnw(ctx, "Device deletion channel closed", log.Fields{"device-id": oFsm.deviceID})
1241 }
1242 break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301243 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001244
Himani Chawla4d908332020-08-31 12:30:20 +05301245 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001246 logger.Infow(ctx, "End UniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301247}
1248
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301250 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1251 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001253 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301254 return
1255 }
1256 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1257 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001258 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001259 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301260 return
1261 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001262 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001263 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1264 //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 +00001265 oFsm.mutexPLastTxMeInstance.RLock()
1266 if oFsm.pLastTxMeInstance != nil {
1267 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1268 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1269 // maybe we can use just the same eventName for different state transitions like "forward"
1270 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1271 switch oFsm.pLastTxMeInstance.GetName() {
1272 case "Ieee8021PMapperServiceProfile":
1273 { // let the FSM proceed ...
1274 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapCResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001276 }
1277 case "MacBridgePortConfigurationData":
1278 { // let the FSM proceed ...
1279 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxMbpcdResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001281 }
1282 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1283 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1284 oFsm.mutexPLastTxMeInstance.RUnlock()
1285 oFsm.omciMIdsResponseReceived <- true
1286 }
1287 default:
1288 {
1289 oFsm.mutexPLastTxMeInstance.RUnlock()
1290 logger.Warnw(ctx, "Unsupported ME name received!",
1291 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1292 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001293 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001294 } else {
1295 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001296 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001297 } else {
1298 oFsm.mutexPLastTxMeInstance.RUnlock()
1299 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001300 }
1301 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001302 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1303 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001304 // possibly force FSM into abort or ignore some errors for some messages?
1305 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1306 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
Himani Chawla4d908332020-08-31 12:30:20 +05301307 return
1308 }
Himani Chawla4d908332020-08-31 12:30:20 +05301309}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
Mahir Gunyel01034b62021-06-29 11:25:09 -07001311 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1312 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1313 oFsm.mutexPLastTxMeInstance.RLock()
1314 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1315 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1316 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1317 switch oFsm.pLastTxMeInstance.GetName() {
1318 case "TCont":
1319 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1320 //We should revert DB
bseenivaeba8eb12024-12-13 11:54:28 +05301321 oFsm.pUniTechProf.mutexTPState.RLock()
Mahir Gunyel01034b62021-06-29 11:25:09 -07001322 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1323 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1324 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001325 if oFsm.pOnuDeviceEntry != nil {
1326 oFsm.pOnuDeviceEntry.FreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001327 } else {
1328 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1329 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1330 }
1331 }
bseenivaeba8eb12024-12-13 11:54:28 +05301332 oFsm.pUniTechProf.mutexTPState.RUnlock()
Mahir Gunyel01034b62021-06-29 11:25:09 -07001333 default:
1334 logger.Warnw(ctx, "Unsupported ME name received with error!",
1335 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1336 }
1337 }
1338}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301340 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1341 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001342 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001343 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301344 return
1345 }
1346 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1347 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001348 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001349 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301350 return
1351 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001352 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301353 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001354 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001355 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001356 // possibly force FSM into abort or ignore some errors for some messages?
1357 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1358 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001359 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301360 return
1361 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001362 oFsm.mutexPLastTxMeInstance.RLock()
1363 if oFsm.pLastTxMeInstance != nil {
1364 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1365 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1366 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1367 // if, then something like:
1368 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301369
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001370 switch oFsm.pLastTxMeInstance.GetName() {
1371 case "TCont":
1372 { // let the FSM proceed ...
1373 oFsm.mutexPLastTxMeInstance.RUnlock()
1374 if oFsm.requestEventOffset == 0 { //from TCont config request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001375 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxTcontsResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001376 } else { // from T-Cont reset request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001377 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxResetTcontResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001378 }
1379 }
1380 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1381 { // let the PrioQueue init proceed by stopping the wait function
1382 oFsm.mutexPLastTxMeInstance.RUnlock()
1383 oFsm.omciMIdsResponseReceived <- true
1384 }
1385 case "Ieee8021PMapperServiceProfile":
1386 { // let the FSM proceed ...
1387 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001388 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001389 }
1390 default:
1391 {
1392 oFsm.mutexPLastTxMeInstance.RUnlock()
1393 logger.Warnw(ctx, "Unsupported ME name received!",
1394 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001395 }
Himani Chawla4d908332020-08-31 12:30:20 +05301396 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001397 } else {
1398 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301399 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001400 } else {
1401 oFsm.mutexPLastTxMeInstance.RUnlock()
1402 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301403 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001404}
1405
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001406func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001407 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1408 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001409 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001410 log.Fields{"device-id": oFsm.deviceID})
1411 return
1412 }
1413 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1414 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001415 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001416 log.Fields{"device-id": oFsm.deviceID})
1417 return
1418 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Akash Soni8eff4632024-12-11 13:41:46 +05301420 if msgObj.Result == me.UnknownInstance {
1421 logger.Warnw(ctx, "UniPonAniConfigFsm - Unknow Instance",
1422 log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj, "Error": msgObj.Result})
1423 } else if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001424 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001425 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1426 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001427 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1428 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko8b07c1b2020-11-26 10:36:31 +00001429 return
1430 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001431 oFsm.mutexPLastTxMeInstance.RLock()
1432 if oFsm.pLastTxMeInstance != nil {
1433 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1434 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1435 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1436 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001437
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001438 switch oFsm.pLastTxMeInstance.GetName() {
1439 case "GemInterworkingTerminationPoint":
1440 { // let the FSM proceed ...
1441 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001442 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemiwResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001443 }
1444 case "GemPortNetworkCtp":
1445 { // let the FSM proceed ...
1446 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemntpResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001448 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001449 case "TrafficDescriptor":
1450 { // let the FSM proceed ...
1451 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001452 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemTdResp)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001453 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001454 case "Ieee8021PMapperServiceProfile":
1455 { // let the FSM proceed ...
1456 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRem1pMapperResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001458 }
1459 case "MacBridgePortConfigurationData":
1460 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1461 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001462 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemAniBPCDResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001463 }
1464 default:
1465 {
1466 oFsm.mutexPLastTxMeInstance.RUnlock()
1467 logger.Warnw(ctx, "Unsupported ME name received!",
1468 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1469 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001470 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001471 } else {
1472 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001473 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001474 } else {
1475 oFsm.mutexPLastTxMeInstance.RUnlock()
1476 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001477 }
1478}
1479
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001480func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001482 "msgType": msg.OmciMsg.MessageType})
1483
1484 switch msg.OmciMsg.MessageType {
1485 case omci.CreateResponseType:
1486 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301488
mpagenko3dbcdd22020-07-22 07:38:45 +00001489 } //CreateResponseType
1490 case omci.SetResponseType:
1491 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001492 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001493
mpagenko3dbcdd22020-07-22 07:38:45 +00001494 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001495 case omci.DeleteResponseType:
1496 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001498
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001499 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001500 default:
1501 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001502 logger.Errorw(ctx, "UniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001503 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001504 return
1505 }
1506 }
1507}
1508
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001509func (oFsm *UniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001510 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1511 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301512 logger.Info(ctx, "UniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001513 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1514 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001515 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001516 meParams := me.ParamData{
1517 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1518 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001519 me.GemPortNetworkCtp_PortId: gemPortAttribs.gemPortID,
1520 me.GemPortNetworkCtp_TContPointer: oFsm.tcont0ID,
1521 me.GemPortNetworkCtp_Direction: gemPortAttribs.direction,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001522 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1523 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001524 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1525 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: gemPortAttribs.downQueueID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001526 },
1527 }
Holger Hildebrandtc408f492022-07-14 08:39:24 +00001528 if oFsm.techProfileType == cTechProfileTypeXgsPon {
1529 meParams.Attributes[me.GemPortNetworkCtp_EncryptionKeyRing] = GemEncryptKeyRingUnicastDownstreamOnly
1530 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001531 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 meInstance, err := oFsm.pOmciCC.SendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1533 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001534 if err != nil {
1535 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001536 logger.Errorw(ctx, "GemNCTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001537 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001538 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001539 return
1540 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001541 //accept also nil as (error) return value for writing to LastTx
1542 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001543 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001544 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001545 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001546 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001547 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001549 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001550 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001551 return
1552 }
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05301553 oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemPortNetworkCtpClassID, gemPortAttribs.gemPortID, meParams.Attributes)
Girish Gowdra50e56422021-06-01 16:46:04 -07001554 // Mark the gem port to be added for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001555 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
1556 if OnuMetricsManager != nil {
1557 OnuMetricsManager.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001558 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001559 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001560
1561 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001562 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001563 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001564}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001565func (oFsm *UniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001566 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1567 if gemPortAttribs.isMulticast {
1568 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1569 return true
1570 }
1571 }
1572 return false
1573}
mpagenko3dbcdd22020-07-22 07:38:45 +00001574
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575func (oFsm *UniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001576 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1577 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301578 logger.Info(ctx, "UniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001579 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1580 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001581 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001582
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301583 var meParams me.ParamData
ozgecanetsia4b232302020-11-11 10:58:10 +03001584 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1585 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001586
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301587 meParams = me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001588 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001589 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001590 me.MulticastGemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.multicastGemID,
1591 me.MulticastGemInterworkingTerminationPoint_InterworkingOption: 0, // Don't Care
1592 me.MulticastGemInterworkingTerminationPoint_ServiceProfilePointer: 0, // Don't Care
1593 me.MulticastGemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001594 },
1595 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001596 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1597 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1598 continue
1599 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001600 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 meInstance, err := oFsm.pOmciCC.SendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1602 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001603 if err != nil {
1604 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001605 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001606 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001607 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001608 return
1609
1610 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001611 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001612 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001613 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001614 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001615 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001616 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001617 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001618 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001619 return
1620 }
1621 ipv4MulticastTable := make([]uint8, 12)
1622 //Gem Port ID
1623 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1624 //Secondary Key
1625 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1626 // Multicast IP range start This is the 224.0.0.1 address
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001627 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], cmn.IPToInt32(net.IPv4(224, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001628 // MulticastIp range stop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001629 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001630
1631 meIPV4MCTableParams := me.ParamData{
1632 EntityID: gemPortAttribs.multicastGemID,
1633 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001634 me.MulticastGemInterworkingTerminationPoint_Ipv4MulticastAddressTable: ipv4MulticastTable,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001635 },
1636 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001637 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001638 meIPV4MCTableInstance, err := oFsm.pOmciCC.SendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1639 true, oFsm.PAdaptFsm.CommChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001640 if err != nil {
1641 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001642 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001643 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001644 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001645 return
1646 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001647 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001648 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001649
1650 } else {
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301651 meParams = me.ParamData{
ozgecanetsia4b232302020-11-11 10:58:10 +03001652 EntityID: gemPortAttribs.gemPortID,
1653 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001654 me.GemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.gemPortID, //same as EntityID, see above
1655 me.GemInterworkingTerminationPoint_InterworkingOption: 5, //fixed model:: G.998 .1pMapper
1656 me.GemInterworkingTerminationPoint_ServiceProfilePointer: oFsm.mapperSP0ID,
1657 me.GemInterworkingTerminationPoint_InterworkingTerminationPointPointer: 0, //not used with .1PMapper Mac bridge
1658 me.GemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001659 },
1660 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001661 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 meInstance, err := oFsm.pOmciCC.SendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1663 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001664 if err != nil {
1665 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001667 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001668 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001669 return
1670 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001671 //accept also nil as (error) return value for writing to LastTx
1672 // - this avoids misinterpretation of new received OMCI messages
1673 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001674 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001675 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001676 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001678 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001680 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001681 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001682 return
1683 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301684 logger.Infow(ctx, "Adding GemIWTP to the ONU DB ", log.Fields{"device-id": oFsm.deviceID, "GEMID": gemPortAttribs.gemPortID})
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05301685 oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemInterworkingTerminationPointClassID, gemPortAttribs.gemPortID, meParams.Attributes)
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301686
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001687 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001688
1689 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001691 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001692}
1693
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001694func (oFsm *UniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001695 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1696 if oFsm.tcontSetBefore {
1697 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1698 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001700 "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001701 go func(aPAFsm *cmn.AdapterFsm) {
1702 if aPAFsm != nil && aPAFsm.PFsm != nil {
1703 _ = aPAFsm.PFsm.Event(aniEvRxPrioqsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001704 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001705 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001706 return
1707 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001708 const cu16StrictPrioWeight uint16 = 0xFFFF
1709 //find all upstream PrioQueues related to this T-Cont
1710 loQueueMap := ordered_map.NewOrderedMap()
1711 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001712 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001713 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001714 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1715 "prioString": gemPortAttribs.pbitString})
1716 continue
1717 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001718 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301719 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001720 //key does not yet exist
1721 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1722 }
1723 } else {
1724 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1725 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001726 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001727
Girish Gowdra09e5f212021-09-30 16:28:36 -07001728 trafficSchedPtrSetSupported := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001729 loOnu2g := oFsm.pOnuDB.GetMe(me.Onu2GClassID, cmn.Onu2gMeID)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001730 if loOnu2g == nil {
1731 logger.Errorw(ctx, "onu2g is nil, cannot read qos configuration flexibility parameter",
1732 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001733 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001734 return
1735 }
1736 returnVal := loOnu2g["QualityOfServiceQosConfigurationFlexibility"]
1737 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001738 if qosCfgFlexParam, err := oFsm.pOnuDB.GetUint16Attrib(returnVal); err == nil {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001739 trafficSchedPtrSetSupported = qosCfgFlexParam&bitTrafficSchedulerPtrSetPermitted == bitTrafficSchedulerPtrSetPermitted
1740 logger.Debugw(ctx, "trafficSchedPtrSetSupported set",
1741 log.Fields{"qosCfgFlexParam": qosCfgFlexParam, "trafficSchedPtrSetSupported": trafficSchedPtrSetSupported})
1742 } else {
1743 logger.Errorw(ctx, "Cannot extract qos configuration flexibility parameter",
1744 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001745 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001746 return
1747 }
1748 } else {
1749 logger.Errorw(ctx, "Cannot read qos configuration flexibility parameter",
1750 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001751 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001752 return
1753 }
1754
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001755 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1756 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1757 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1758 // or even be finished without correct SP/WRR setting
1759
1760 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1761 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1762 // even though its T-Cont seems to be wrong ...
1763 loTrafficSchedulerEID := 0x8000
1764 //for all found queues
1765 iter := loQueueMap.IterFunc()
1766 for kv, ok := iter(); ok; kv, ok = iter() {
1767 queueIndex := (kv.Key).(uint16)
1768 meParams := me.ParamData{
1769 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301770 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001771 }
Girish Gowdra09e5f212021-09-30 16:28:36 -07001772 if trafficSchedPtrSetSupported {
1773 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1774 //StrictPrio indication
1775 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
1776 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1777 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001778 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = 0 //ensure T-Cont defined StrictPrio scheduling
Girish Gowdra09e5f212021-09-30 16:28:36 -07001779 } else {
1780 //WRR indication
1781 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
1782 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1783 "Weight": kv.Value,
1784 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001785 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1786 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Girish Gowdra09e5f212021-09-30 16:28:36 -07001787 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001788 } else {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001789 // setting Traffic Scheduler (TS) pointer is not supported unless we point to another TS that points to the same TCONT.
1790 // 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.
1791 // 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.
1792 if (kv.Value).(uint16) == cu16StrictPrioWeight { // SP case, nothing to be done. Proceed to the next queue
1793 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio, traffic sched ptr set unsupported", log.Fields{
1794 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1795 "device-id": oFsm.deviceID})
1796 continue
1797 }
1798 // WRR case, update weight.
1799 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR, traffic sched ptr set unsupported", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001800 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1801 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001802 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001803 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001804 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001805 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001806 meInstance, err := oFsm.pOmciCC.SendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1807 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001808 if err != nil {
1809 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001810 logger.Errorw(ctx, "PrioQueueVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001811 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001812 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001813 return
1814 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001815 //accept also nil as (error) return value for writing to LastTx
1816 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001817 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001818 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001819
1820 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001821 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001822 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001824 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001825 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001826 return
1827 }
1828
1829 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1830 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1831 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1832 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1833
1834 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001835
1836 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001837 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001839}
1840
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001841func (oFsm *UniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001842 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001843 if oFsm.isCanceled {
1844 // FSM already canceled before entering wait
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001845 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 +00001846 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001847 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00001848 }
mpagenko7d6bb022021-03-11 15:07:55 +00001849 oFsm.isAwaitingResponse = true
1850 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001851 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301852 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001853 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001854 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001855 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 +00001856 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001857 oFsm.mutexIsAwaitingResponse.Lock()
1858 oFsm.isAwaitingResponse = false
1859 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001860 oFsm.mutexPLastTxMeInstance.RLock()
1861 if oFsm.pLastTxMeInstance != nil {
1862 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
1863 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
1864 }
1865 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001866 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001867 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301868 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001869 logger.Debugw(ctx, "UniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001870 oFsm.mutexIsAwaitingResponse.Lock()
1871 oFsm.isAwaitingResponse = false
1872 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001873 return nil
1874 }
mpagenko7d6bb022021-03-11 15:07:55 +00001875 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001876 logger.Debugw(ctx, "UniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001877 oFsm.mutexIsAwaitingResponse.Lock()
1878 oFsm.isAwaitingResponse = false
1879 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001880 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001881 }
1882}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001883
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001884func (oFsm *UniPonAniConfigFsm) setChanSet(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001885 oFsm.mutexChanSet.Lock()
1886 oFsm.chanSet = flagValue
1887 oFsm.mutexChanSet.Unlock()
1888}
1889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001890func (oFsm *UniPonAniConfigFsm) isChanSet() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001891 oFsm.mutexChanSet.RLock()
1892 flagValue := oFsm.chanSet
1893 oFsm.mutexChanSet.RUnlock()
1894 return flagValue
1895}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001896
1897// PrepareForGarbageCollection - remove references to prepare for garbage collection
1898func (oFsm *UniPonAniConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301899 logger.Info(ctx, "prepare for garbage collection", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001900 oFsm.pDeviceHandler = nil
1901 oFsm.pOnuDeviceEntry = nil
1902 oFsm.pOmciCC = nil
1903}