blob: 8539c71e24d42e9a7ffbd6b9a6b284dc58992c1c [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2020-2023 Open Networking Foundation (ONF) and the ONF Contributors
mpagenko3dbcdd22020-07-22 07:38:45 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
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 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 tcontInstID, tcontAlreadyExist, err := oFsm.pOnuDeviceEntry.AllocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700353 if err != nil {
354 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700355 //reset the state machine to enable usage on subsequent requests
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 _ = aPAFsm.PFsm.Event(aniEvReset)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700357 return
358 }
359 oFsm.tcont0ID = tcontInstID
360 oFsm.tcontSetBefore = tcontAlreadyExist
361 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
362 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
363 "tcontAlreadyExist": tcontAlreadyExist,
364 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800365
366 // Access critical state with lock
mpagenko3ce9fa02021-07-28 13:26:54 +0000367 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000368 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
369 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko3ce9fa02021-07-28 13:26:54 +0000370 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800371
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800373 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300374 loGemPortAttribs := ponAniGemPortAttribs{}
375
Himani Chawla26e555c2020-08-31 12:30:20 +0530376 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
377
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 if queueInstKeys := oFsm.pOnuDB.GetSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530379
380 loGemPortAttribs.gemPortID = gemEntry.gemPortID
381 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
382 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
383 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
384 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
385
386 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.UniID,
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000389 // Note: As we do not maintain any slot numbering, slot number will be excluded from search pattern.
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000391 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.UniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
Himani Chawla26e555c2020-08-31 12:30:20 +0530392
393 usQueueFound := false
394 dsQueueFound := false
395 for _, mgmtEntityID := range queueInstKeys {
396 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000397 returnVal := meAttributes[me.PriorityQueue_RelatedPort]
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 if relatedPort, err := oFsm.pOnuDB.GetUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 if relatedPort == usQrelPortMask {
401 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000402 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000403 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 usQueueFound = true
405 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
406 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000407 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000408 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530409 dsQueueFound = true
410 }
411 if usQueueFound && dsQueueFound {
412 break
413 }
414 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000415 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530416 }
417 } else {
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000418 logger.Warnw(ctx, "PrioQueue.RelatedPort not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 }
420 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000422 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530423 }
424 }
425 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000426 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530427 }
428 loGemPortAttribs.direction = gemEntry.direction
429 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
430 loGemPortAttribs.weight = gemEntry.queueWeight
431 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300432
ozgecanetsia4b232302020-11-11 10:58:10 +0300433 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300434 //TODO this might effectively ignore the for loop starting at line 316
435 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300436 loGemPortAttribs.isMulticast = true
437 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
438 loGemPortAttribs.staticACL = gemEntry.staticACL
439 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530440
dbainbri4d3a0dc2020-12-02 00:33:42 +0000441 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300442 "gemPortID": loGemPortAttribs.gemPortID,
443 "isMulticast": loGemPortAttribs.isMulticast,
444 "multicastGemID": loGemPortAttribs.multicastGemID,
445 "staticACL": loGemPortAttribs.staticACL,
446 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000447 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300448 })
449
450 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000451 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300452 "gemPortID": loGemPortAttribs.gemPortID,
453 "upQueueID": loGemPortAttribs.upQueueID,
454 "downQueueID": loGemPortAttribs.downQueueID,
455 "pbitString": loGemPortAttribs.pbitString,
456 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000457 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300458 })
459 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530460
461 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530462 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
463 meParams := me.ParamData{
464 EntityID: loGemPortAttribs.gemPortID,
465 Attributes: me.AttributeValueMap{
466 me.GemPortNetworkCtp_PortId: loGemPortAttribs.gemPortID,
467 me.GemPortNetworkCtp_TContPointer: oFsm.tcont0ID,
468 me.GemPortNetworkCtp_Direction: loGemPortAttribs.direction,
469 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: loGemPortAttribs.upQueueID,
470 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: loGemPortAttribs.downQueueID,
471 },
472 }
473 oFsm.pOnuDB.PutMe(ctx, me.GemPortNetworkCtpClassID, loGemPortAttribs.gemPortID, meParams.Attributes)
474 var meAttributes me.AttributeValueMap //dummy , anyways we are not going to use the values.
475 oFsm.pOnuDB.PutMe(ctx, me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID, loGemPortAttribs.gemPortID, meAttributes)
476
477 oFsm.pOnuDB.PutMe(ctx, me.GemInterworkingTerminationPointClassID, loGemPortAttribs.gemPortID, meAttributes)
478
479 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000481 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
482 _ = aPAFsm.PFsm.Event(aniEvStartConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000483 } else {
484 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000485 _ = aPAFsm.PFsm.Event(aniEvSkipOmciConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000486 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530487 }
488}
489
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490func (oFsm *UniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530491 logger.Info(ctx, "UniPonAniConfigFsm start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000493 // in case the used channel is not yet defined (can be re-used after restarts)
494 if oFsm.omciMIdsResponseReceived == nil {
495 oFsm.omciMIdsResponseReceived = make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 logger.Debug(ctx, "UniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000497 } else {
498 // as we may 're-use' this instance of FSM and the connected channel
499 // make sure there is no 'lingering' request in the already existing channel:
500 // (simple loop sufficient as we are the only receiver)
501 for len(oFsm.omciMIdsResponseReceived) > 0 {
502 <-oFsm.omciMIdsResponseReceived
503 }
504 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000505 //ensure internal slices are empty (which might be set from previous run) - release memory
506 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000507 oFsm.mutexIsAwaitingResponse.Lock()
508 //reset the canceled state possibly existing from previous reset
509 oFsm.isCanceled = false
510 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000511
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000512 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000514
515 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000517 if pConfigAniStateAFsm != nil {
518 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000520
mpagenko3dbcdd22020-07-22 07:38:45 +0000521 }
522}
523
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524func (oFsm *UniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
525 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000526 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000528 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000529 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000530 meInstance, err := oFsm.pOmciCC.SendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
531 oFsm.mapperSP0ID, oFsm.PAdaptFsm.CommChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300532 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 logger.Errorw(ctx, "Dot1PMapper create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300534 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300536 if pConfigAniStateAFsm != nil {
537 oFsm.mutexPLastTxMeInstance.Unlock()
538 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 go func(aPAFsm *cmn.AdapterFsm) {
540 if aPAFsm != nil && aPAFsm.PFsm != nil {
541 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300542 }
543 }(pConfigAniStateAFsm)
544 return
545 }
546 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000547 //accept also nil as (error) return value for writing to LastTx
548 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000549 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300550 oFsm.mutexPLastTxMeInstance.Unlock()
551
mpagenko3dbcdd22020-07-22 07:38:45 +0000552}
553
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000554func (oFsm *UniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530555 logger.Info(ctx, "Creating Tx MAC Bridge Port Config Data", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000556 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
557 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000558 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
559 bridgePtr := cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
mpagenko3dbcdd22020-07-22 07:38:45 +0000560 meParams := me.ParamData{
561 EntityID: oFsm.macBPCD0ID,
562 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000563 me.MacBridgePortConfigurationData_BridgeIdPointer: bridgePtr,
564 me.MacBridgePortConfigurationData_PortNum: 0xFF, //fixed unique ANI side indication
565 me.MacBridgePortConfigurationData_TpType: 3, //for .1PMapper
566 me.MacBridgePortConfigurationData_TpPointer: oFsm.mapperSP0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000567 },
568 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000569 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000570 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
571 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300572 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300574 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300576 if pConfigAniStateAFsm != nil {
577 oFsm.mutexPLastTxMeInstance.Unlock()
578 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 go func(aPAFsm *cmn.AdapterFsm) {
580 if aPAFsm != nil && aPAFsm.PFsm != nil {
581 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300582 }
583 }(pConfigAniStateAFsm)
584 return
585 }
586 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000587 //accept also nil as (error) return value for writing to LastTx
588 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000589 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300590 oFsm.mutexPLastTxMeInstance.Unlock()
591
mpagenko3dbcdd22020-07-22 07:38:45 +0000592}
593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000594func (oFsm *UniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530595 logger.Info(ctx, "Tx Setting Tcont ", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000596 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
597 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700599 "tcontExist": oFsm.tcontSetBefore})
600 //If tcont was set before, then no need to set it again. Let state machine to proceed.
601 if oFsm.tcontSetBefore {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 go func(aPAFsm *cmn.AdapterFsm) {
603 if aPAFsm != nil && aPAFsm.PFsm != nil {
604 _ = aPAFsm.PFsm.Event(aniEvRxTcontsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700605 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700607 return
608 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000609 meParams := me.ParamData{
610 EntityID: oFsm.tcont0ID,
611 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000612 me.TCont_AllocId: oFsm.alloc0ID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000613 },
614 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000615 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
617 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300618 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000619 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300620 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000621 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300622 if pConfigAniStateAFsm != nil {
623 oFsm.mutexPLastTxMeInstance.Unlock()
624 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000625 go func(aPAFsm *cmn.AdapterFsm) {
626 if aPAFsm != nil && aPAFsm.PFsm != nil {
627 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300628 }
629 }(pConfigAniStateAFsm)
630 return
631 }
632 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000633 //accept also nil as (error) return value for writing to LastTx
634 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000635 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300636 oFsm.mutexPLastTxMeInstance.Unlock()
637
mpagenko3dbcdd22020-07-22 07:38:45 +0000638}
639
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640func (oFsm *UniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530641 logger.Info(ctx, "UniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000644}
645
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646func (oFsm *UniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530647 logger.Info(ctx, "UniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000650}
651
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652func (oFsm *UniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530653 logger.Info(ctx, "UniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000654 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000656}
657
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000658func (oFsm *UniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300659
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530660 logger.Info(ctx, "UniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000661 "toGemIw": 1024, /* cmp above */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000662 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000663
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530664 logger.Info(ctx, "UniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000665 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000666 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000667
mpagenko3dbcdd22020-07-22 07:38:45 +0000668 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000669 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530670 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000671 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000672
673 //assign the GemPorts according to the configured Prio
674 var loPrioGemPortArray [8]uint16
675 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300676 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000677 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300678 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
679 "prioString": gemPortAttribs.pbitString})
680 continue
681 }
682 if gemPortAttribs.pbitString == "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000683 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300684 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
685 "prioString": gemPortAttribs.pbitString})
686 continue
687 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000688 for i := 0; i < 8; i++ {
689 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
690 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
691 if prio == 1 { // Check this p-bit is set
692 if loPrioGemPortArray[i] == 0 {
693 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
694 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000695 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000696 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000697 "SetGemPort": loPrioGemPortArray[i]})
698 }
699 }
700 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000701 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000702 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000703 "prioString": gemPortAttribs.pbitString, "position": i})
704 }
705
706 }
707 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300708
ozgecanetsia4b232302020-11-11 10:58:10 +0300709 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530710 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300711 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530712 if value != 0 {
713 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530714 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000716 "for Prio": index,
717 "IwPtr": strconv.FormatInt(int64(value), 16),
718 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300719 } else {
720 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000721 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
722 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300723 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530724 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000725 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300726 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000727 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
728 // but except for processing effort does not really harm - left to keep changes low
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +0000729 meParams.Attributes[me.Ieee8021PMapperServiceProfile_TpPointer] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530730
731 if !foundIwPtr {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530732 logger.Warn(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000733 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300734 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
735 // 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 +0000736 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000737 //pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300738 //if pConfigAniStateAFsm != nil {
739 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000740 // go func(aPAFsm *cmn.AdapterFsm) {
741 // if aPAFsm != nil && aPAFsm.PFsm != nil {
742 // _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300743 // }
744 // }(pConfigAniStateAFsm)
745 //}
746 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000747 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000748 if pConfigAniStateAFsm != nil {
749 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000750 go func(aPAFsm *cmn.AdapterFsm) {
751 if aPAFsm != nil && aPAFsm.PFsm != nil {
752 _ = aPAFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000753 }
754 }(pConfigAniStateAFsm)
755 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300756 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000757 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000758 meInstance, err := oFsm.pOmciCC.SendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
759 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300760 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000761 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300762 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000763 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300764 if pConfigAniStateAFsm != nil {
765 oFsm.mutexPLastTxMeInstance.Unlock()
766 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000767 go func(aPAFsm *cmn.AdapterFsm) {
768 if aPAFsm != nil && aPAFsm.PFsm != nil {
769 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300770 }
771 }(pConfigAniStateAFsm)
772 return
773 }
774 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300775 //accept also nil as (error) return value for writing to LastTx
776 // - this avoids misinterpretation of new received OMCI messages
777 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300778 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000779 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000780}
781
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000782func (oFsm *UniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530783 logger.Info(ctx, "UniPonAniConfigFsm ani config done", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000784 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000785 //store that the UNI related techProfile processing is done for the given Profile and Uni
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000786 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
787 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000788 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000789 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000790 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
791 // but only in case the techProfile was configured (not deleted)
792 if oFsm.requestEventOffset == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000793 go oFsm.pDeviceHandler.VerifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000794 }
795 } else {
796 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000797 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000798 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000799 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000801 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
802 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000803 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000804 }
mpagenko01e726e2020-10-23 09:45:29 +0000805
806 //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 +0000807}
808
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000809func (oFsm *UniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000810 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
811 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000812 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
813 select {
814 case <-oFsm.waitFlowDeleteChannel:
815 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
816 default:
817 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000818
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000819 uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.UniID)
820 if uniVlanConfigFsm != nil {
mpagenko3ce9fa02021-07-28 13:26:54 +0000821 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000822 if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000823 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000825 // 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 +0000826 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000827 if pConfigAniStateAFsm != nil {
828 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 go func(aPAFsm *cmn.AdapterFsm) {
830 if aPAFsm != nil && aPAFsm.PFsm != nil {
831 _ = aPAFsm.PFsm.Event(aniEvWaitFlowRem)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000832 }
833 }(pConfigAniStateAFsm)
834 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000835 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 +0000836 }
837 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800838 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000839 } else {
840 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
841 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800842 }
843
mpagenko3ce9fa02021-07-28 13:26:54 +0000844 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000845 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000846 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000847 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000848 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
849 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000850 "GemIwTp-entity-id": loGemPortID})
851 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
852
853 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000854 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855 meInstance, err := oFsm.pOmciCC.SendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
856 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300857 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 logger.Errorw(ctx, "GemIWTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300859 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000860 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300861 if pConfigAniStateAFsm != nil {
862 oFsm.mutexPLastTxMeInstance.Unlock()
863 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000864 go func(aPAFsm *cmn.AdapterFsm) {
865 if aPAFsm != nil && aPAFsm.PFsm != nil {
866 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300867 }
868 }(pConfigAniStateAFsm)
869 return
870 }
871 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000872 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300873 oFsm.mutexPLastTxMeInstance.Unlock()
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530874 logger.Infow(ctx, "Deleting GemIWTP at the ONU DB ", log.Fields{"device-id": oFsm.deviceID, "GEMID": loGemPortID})
875 oFsm.pOnuDB.DeleteMe(me.GemInterworkingTerminationPointClassID, loGemPortID)
mpagenko8b07c1b2020-11-26 10:36:31 +0000876}
877
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878func (oFsm *UniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
mpagenkobb47bc22021-04-20 13:29:09 +0000879 oFsm.mutexIsAwaitingResponse.Lock()
880 oFsm.isWaitingForFlowDelete = true
881 oFsm.mutexIsAwaitingResponse.Unlock()
882 select {
883 // maybe be also some outside cancel (but no context modeled for the moment ...)
884 // case <-ctx.Done():
885 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000886 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 +0000887 logger.Warnw(ctx, "UniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
888 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000889 oFsm.mutexIsAwaitingResponse.Lock()
890 oFsm.isWaitingForFlowDelete = false
891 oFsm.mutexIsAwaitingResponse.Unlock()
892 //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 +0000893 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000894 if pConfigAniStateAFsm != nil {
895 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000896 go func(aPAFsm *cmn.AdapterFsm) {
897 if aPAFsm != nil && aPAFsm.PFsm != nil {
898 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000899 }
900 }(pConfigAniStateAFsm)
901 } else {
902 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000904 }
905 return
906
907 case success := <-oFsm.waitFlowDeleteChannel:
908 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 logger.Debugw(ctx, "UniPonAniConfigFsm flow removed info received", log.Fields{
910 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000911 oFsm.mutexIsAwaitingResponse.Lock()
912 oFsm.isWaitingForFlowDelete = false
913 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000915 if pConfigAniStateAFsm != nil {
916 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000917 go func(aPAFsm *cmn.AdapterFsm) {
918 if aPAFsm != nil && aPAFsm.PFsm != nil {
919 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000920 }
921 }(pConfigAniStateAFsm)
922 } else {
923 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000924 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000925 }
926 return
927 }
928 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000929 logger.Debugw(ctx, "UniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
930 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000931 oFsm.mutexIsAwaitingResponse.Lock()
932 oFsm.isWaitingForFlowDelete = false
933 oFsm.mutexIsAwaitingResponse.Unlock()
934 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000935 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000936 if pConfigAniStateAFsm != nil {
937 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000938 go func(aPAFsm *cmn.AdapterFsm) {
939 if aPAFsm != nil && aPAFsm.PFsm != nil {
940 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenkobb47bc22021-04-20 13:29:09 +0000941 }
942 }(pConfigAniStateAFsm)
943 }
944 return
945 }
946}
947
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000948func (oFsm *UniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000949 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000950 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000951 oFsm.pUniTechProf.mutexTPState.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530952 logger.Info(ctx, "UniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000954 "GemNCTP-entity-id": loGemPortID})
955 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000956 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000957 meInstance, err := oFsm.pOmciCC.SendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
958 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300959 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 logger.Errorw(ctx, "GemNCTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300961 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000962 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300963 if pConfigAniStateAFsm != nil {
964 oFsm.mutexPLastTxMeInstance.Unlock()
965 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000966 go func(aPAFsm *cmn.AdapterFsm) {
967 if aPAFsm != nil && aPAFsm.PFsm != nil {
968 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300969 }
970 }(pConfigAniStateAFsm)
971 return
972 }
973 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000974 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000975 oFsm.mutexPLastTxMeInstance.Unlock()
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530976 oFsm.pOnuDB.DeleteMe(me.GemPortNetworkCtpClassID, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800977 // Mark the gem port to be removed for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
979 if OnuMetricsManager != nil {
980 OnuMetricsManager.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800981 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000982}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000983func (oFsm *UniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000984 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300985 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000986 oFsm.pUniTechProf.mutexTPState.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530987 logger.Info(ctx, "UniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000988 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300989 "TD-entity-id": loGemPortID})
990
991 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000992 meInstance, err := oFsm.pOmciCC.SendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
993 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300994
995 if err != nil {
996 logger.Errorw(ctx, "TD delete failed - proceed fsm",
997 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300999 if pConfigAniStateAFsm != nil {
1000 oFsm.mutexPLastTxMeInstance.Unlock()
1001 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 go func(aPAFsm *cmn.AdapterFsm) {
1003 if aPAFsm != nil && aPAFsm.PFsm != nil {
1004 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001005 }
1006 }(pConfigAniStateAFsm)
1007 return
1008 }
1009 }
1010 oFsm.pLastTxMeInstance = meInstance
1011 oFsm.mutexPLastTxMeInstance.Unlock()
1012}
mpagenko8b07c1b2020-11-26 10:36:31 +00001013
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014func (oFsm *UniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301015 logger.Info(ctx, "UniPonAniConfigFsm - start resetting the TCont", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001017
1018 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
1019 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
1020 meParams := me.ParamData{
1021 EntityID: oFsm.tcont0ID,
1022 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001023 me.TCont_AllocId: cmn.UnusedTcontAllocID,
mpagenko8b07c1b2020-11-26 10:36:31 +00001024 },
1025 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001026 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001027 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1028 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001029 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001030 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001031 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001032 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001033 if pConfigAniStateAFsm != nil {
1034 oFsm.mutexPLastTxMeInstance.Unlock()
1035 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 go func(aPAFsm *cmn.AdapterFsm) {
1037 if aPAFsm != nil && aPAFsm.PFsm != nil {
1038 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001039 }
1040 }(pConfigAniStateAFsm)
1041 return
1042 }
1043 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001044 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001045 oFsm.mutexPLastTxMeInstance.Unlock()
1046
mpagenko8b07c1b2020-11-26 10:36:31 +00001047}
1048
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049func (oFsm *UniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301050 logger.Info(ctx, "UniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001051 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Mahir Gunyel9545be22021-07-04 15:53:16 -07001052 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1053 unicastGemCount := 0
1054 for _, gemEntry := range mapGemPortParams {
1055 if !gemEntry.isMulticast {
1056 unicastGemCount++
1057 }
1058 }
1059 if unicastGemCount > 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001060 logger.Debugw(ctx, "UniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1061 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1062 pConfigAniStateAFsm := oFsm.PAdaptFsm
Mahir Gunyel9545be22021-07-04 15:53:16 -07001063 if pConfigAniStateAFsm != nil {
1064 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001065 go func(aPAFsm *cmn.AdapterFsm) {
1066 if aPAFsm != nil && aPAFsm.PFsm != nil {
1067 _ = aPAFsm.PFsm.Event(aniEvRemGemDone)
Mahir Gunyel9545be22021-07-04 15:53:16 -07001068 }
1069 }(pConfigAniStateAFsm)
1070 return
1071 }
1072 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 logger.Debugw(ctx, "UniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1074 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001075
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001076 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001077 meInstance, err := oFsm.pOmciCC.SendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1078 oFsm.PAdaptFsm.CommChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001079 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001080 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001081 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001083 if pConfigAniStateAFsm != nil {
1084 oFsm.mutexPLastTxMeInstance.Unlock()
1085 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001086 go func(aPAFsm *cmn.AdapterFsm) {
1087 if aPAFsm != nil && aPAFsm.PFsm != nil {
1088 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001089 }
1090 }(pConfigAniStateAFsm)
1091 return
1092 }
1093 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001094 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001095 oFsm.mutexPLastTxMeInstance.Unlock()
1096
mpagenko8b07c1b2020-11-26 10:36:31 +00001097}
1098
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001099func (oFsm *UniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301100 logger.Info(ctx, "UniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001101 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001102
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001103 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001104 meInstance, err := oFsm.pOmciCC.SendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1105 oFsm.PAdaptFsm.CommChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001106 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001107 logger.Errorw(ctx, "MBPConfigData delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001108 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001109 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001110 if pConfigAniStateAFsm != nil {
1111 oFsm.mutexPLastTxMeInstance.Unlock()
1112 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113 go func(aPAFsm *cmn.AdapterFsm) {
1114 if aPAFsm != nil && aPAFsm.PFsm != nil {
1115 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001116 }
1117 }(pConfigAniStateAFsm)
1118 return
1119 }
1120 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001121 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001122 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001123}
1124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001125func (oFsm *UniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301126 logger.Info(ctx, "UniPonAniConfigFsm ani removal done", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001128 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001129 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001130 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001131 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001132 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001133 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1134 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001135 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001136 }
1137
1138 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001139 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko8b07c1b2020-11-26 10:36:31 +00001140 if pConfigAniStateAFsm != nil {
1141 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001142 go func(aPAFsm *cmn.AdapterFsm) {
1143 if aPAFsm != nil && aPAFsm.PFsm != nil {
1144 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenko8b07c1b2020-11-26 10:36:31 +00001145 }
1146 }(pConfigAniStateAFsm)
1147 }
1148}
1149
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001150func (oFsm *UniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1151 logger.Debugw(ctx, "UniPonAniConfigFsm resetting", log.Fields{
1152 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001153
mpagenko45cc6a32021-07-23 10:06:57 +00001154 if oFsm.isChanSet() {
1155 // indicate processing error to the caller (in case there was still some open request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001156 logger.Debugw(ctx, "UniPonAniConfigFsm processingError on channel", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001157 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1158 //use non-blocking channel send to avoid blocking because of non-existing receiver
1159 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1160 select {
1161 case oFsm.chSuccess <- 0:
1162 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001163 logger.Debugw(ctx, "UniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001164 "device-id": oFsm.deviceID})
1165 }
1166 oFsm.setChanSet(false) //reset the internal channel state
1167 }
1168
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001169 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +00001170 if pConfigAniStateAFsm != nil {
1171 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001172 fsmAbortMsg := cmn.Message{
1173 Type: cmn.TestMsg,
1174 Data: cmn.TestMessage{
1175 TestMessageVal: cmn.AbortMessageProcessing,
mpagenko3dbcdd22020-07-22 07:38:45 +00001176 },
1177 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 pConfigAniStateAFsm.CommChan <- fsmAbortMsg
mpagenko3dbcdd22020-07-22 07:38:45 +00001179
1180 //try to restart the FSM to 'disabled', decouple event transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001181 go func(aPAFsm *cmn.AdapterFsm) {
1182 if aPAFsm != nil && aPAFsm.PFsm != nil {
1183 _ = aPAFsm.PFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001184 }
1185 }(pConfigAniStateAFsm)
1186 }
1187}
1188
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001189func (oFsm *UniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1190 logger.Debugw(ctx, "UniPonAniConfigFsm enters disabled state", log.Fields{
1191 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001192 oFsm.mutexPLastTxMeInstance.Lock()
1193 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001194 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001195}
1196
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001197func (oFsm *UniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301198 logger.Info(ctx, "Start UniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001199loop:
1200 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001201 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001202 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001203 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001204 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301205 if !ok {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301206 logger.Warn(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301207 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001208 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301209 break loop
1210 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001211 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301212
1213 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001214 case cmn.TestMsg:
1215 msg, _ := message.Data.(cmn.TestMessage)
1216 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001217 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001218 break loop
1219 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001221 case cmn.OMCI:
1222 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301224 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301226 "message.Type": message.Type})
1227 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001228
Himani Chawla4d908332020-08-31 12:30:20 +05301229 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001230 logger.Infow(ctx, "End UniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301231}
1232
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001233func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301234 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1235 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001237 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301238 return
1239 }
1240 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1241 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001243 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301244 return
1245 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001246 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001247 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1248 //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 +00001249 oFsm.mutexPLastTxMeInstance.RLock()
1250 if oFsm.pLastTxMeInstance != nil {
1251 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1252 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1253 // maybe we can use just the same eventName for different state transitions like "forward"
1254 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1255 switch oFsm.pLastTxMeInstance.GetName() {
1256 case "Ieee8021PMapperServiceProfile":
1257 { // let the FSM proceed ...
1258 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapCResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001260 }
1261 case "MacBridgePortConfigurationData":
1262 { // let the FSM proceed ...
1263 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001264 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxMbpcdResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001265 }
1266 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1267 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1268 oFsm.mutexPLastTxMeInstance.RUnlock()
1269 oFsm.omciMIdsResponseReceived <- true
1270 }
1271 default:
1272 {
1273 oFsm.mutexPLastTxMeInstance.RUnlock()
1274 logger.Warnw(ctx, "Unsupported ME name received!",
1275 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1276 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001277 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001278 } else {
1279 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001280 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001281 } else {
1282 oFsm.mutexPLastTxMeInstance.RUnlock()
1283 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001284 }
1285 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001286 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1287 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001288 // possibly force FSM into abort or ignore some errors for some messages?
1289 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1290 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
Himani Chawla4d908332020-08-31 12:30:20 +05301291 return
1292 }
Himani Chawla4d908332020-08-31 12:30:20 +05301293}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
Mahir Gunyel01034b62021-06-29 11:25:09 -07001295 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1296 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1297 oFsm.mutexPLastTxMeInstance.RLock()
1298 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1299 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1300 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1301 switch oFsm.pLastTxMeInstance.GetName() {
1302 case "TCont":
1303 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1304 //We should revert DB
1305 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1306 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1307 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 if oFsm.pOnuDeviceEntry != nil {
1309 oFsm.pOnuDeviceEntry.FreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001310 } else {
1311 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1312 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1313 }
1314 }
1315 default:
1316 logger.Warnw(ctx, "Unsupported ME name received with error!",
1317 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1318 }
1319 }
1320}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001321func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301322 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1323 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001324 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001325 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301326 return
1327 }
1328 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1329 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001330 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001331 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301332 return
1333 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001334 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301335 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001336 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001337 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001338 // possibly force FSM into abort or ignore some errors for some messages?
1339 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1340 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001341 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301342 return
1343 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001344 oFsm.mutexPLastTxMeInstance.RLock()
1345 if oFsm.pLastTxMeInstance != nil {
1346 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1347 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1348 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1349 // if, then something like:
1350 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301351
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001352 switch oFsm.pLastTxMeInstance.GetName() {
1353 case "TCont":
1354 { // let the FSM proceed ...
1355 oFsm.mutexPLastTxMeInstance.RUnlock()
1356 if oFsm.requestEventOffset == 0 { //from TCont config request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001357 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxTcontsResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001358 } else { // from T-Cont reset request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxResetTcontResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001360 }
1361 }
1362 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1363 { // let the PrioQueue init proceed by stopping the wait function
1364 oFsm.mutexPLastTxMeInstance.RUnlock()
1365 oFsm.omciMIdsResponseReceived <- true
1366 }
1367 case "Ieee8021PMapperServiceProfile":
1368 { // let the FSM proceed ...
1369 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001370 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001371 }
1372 default:
1373 {
1374 oFsm.mutexPLastTxMeInstance.RUnlock()
1375 logger.Warnw(ctx, "Unsupported ME name received!",
1376 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001377 }
Himani Chawla4d908332020-08-31 12:30:20 +05301378 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001379 } else {
1380 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301381 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001382 } else {
1383 oFsm.mutexPLastTxMeInstance.RUnlock()
1384 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301385 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001386}
1387
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001388func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001389 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1390 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001391 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001392 log.Fields{"device-id": oFsm.deviceID})
1393 return
1394 }
1395 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1396 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001397 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001398 log.Fields{"device-id": oFsm.deviceID})
1399 return
1400 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001401 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001402 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001403 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001404 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1405 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001406 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
1407 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko8b07c1b2020-11-26 10:36:31 +00001408 return
1409 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001410 oFsm.mutexPLastTxMeInstance.RLock()
1411 if oFsm.pLastTxMeInstance != nil {
1412 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1413 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1414 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1415 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001416
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001417 switch oFsm.pLastTxMeInstance.GetName() {
1418 case "GemInterworkingTerminationPoint":
1419 { // let the FSM proceed ...
1420 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001421 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemiwResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001422 }
1423 case "GemPortNetworkCtp":
1424 { // let the FSM proceed ...
1425 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001426 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemntpResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001427 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001428 case "TrafficDescriptor":
1429 { // let the FSM proceed ...
1430 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001431 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemTdResp)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001432 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001433 case "Ieee8021PMapperServiceProfile":
1434 { // let the FSM proceed ...
1435 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001436 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRem1pMapperResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001437 }
1438 case "MacBridgePortConfigurationData":
1439 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1440 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001441 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemAniBPCDResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001442 }
1443 default:
1444 {
1445 oFsm.mutexPLastTxMeInstance.RUnlock()
1446 logger.Warnw(ctx, "Unsupported ME name received!",
1447 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1448 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001449 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001450 } else {
1451 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001452 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001453 } else {
1454 oFsm.mutexPLastTxMeInstance.RUnlock()
1455 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001456 }
1457}
1458
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001459func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001461 "msgType": msg.OmciMsg.MessageType})
1462
1463 switch msg.OmciMsg.MessageType {
1464 case omci.CreateResponseType:
1465 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001466 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301467
mpagenko3dbcdd22020-07-22 07:38:45 +00001468 } //CreateResponseType
1469 case omci.SetResponseType:
1470 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001472
mpagenko3dbcdd22020-07-22 07:38:45 +00001473 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001474 case omci.DeleteResponseType:
1475 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001476 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001477
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001478 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001479 default:
1480 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001481 logger.Errorw(ctx, "UniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001482 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001483 return
1484 }
1485 }
1486}
1487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001488func (oFsm *UniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001489 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1490 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301491 logger.Info(ctx, "UniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001492 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1493 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001494 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001495 meParams := me.ParamData{
1496 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1497 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001498 me.GemPortNetworkCtp_PortId: gemPortAttribs.gemPortID,
1499 me.GemPortNetworkCtp_TContPointer: oFsm.tcont0ID,
1500 me.GemPortNetworkCtp_Direction: gemPortAttribs.direction,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001501 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1502 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001503 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1504 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: gemPortAttribs.downQueueID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001505 },
1506 }
Holger Hildebrandtc408f492022-07-14 08:39:24 +00001507 if oFsm.techProfileType == cTechProfileTypeXgsPon {
1508 meParams.Attributes[me.GemPortNetworkCtp_EncryptionKeyRing] = GemEncryptKeyRingUnicastDownstreamOnly
1509 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001510 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001511 meInstance, err := oFsm.pOmciCC.SendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1512 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001513 if err != nil {
1514 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001515 logger.Errorw(ctx, "GemNCTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001516 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001518 return
1519 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001520 //accept also nil as (error) return value for writing to LastTx
1521 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001522 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001523 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001524 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001525 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001526 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001528 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001530 return
1531 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301532 oFsm.pOnuDB.PutMe(ctx, me.GemPortNetworkCtpClassID, gemPortAttribs.gemPortID, meParams.Attributes)
Girish Gowdra50e56422021-06-01 16:46:04 -07001533 // Mark the gem port to be added for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001534 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
1535 if OnuMetricsManager != nil {
1536 OnuMetricsManager.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001537 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001538 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001539
1540 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001543}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001544func (oFsm *UniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001545 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1546 if gemPortAttribs.isMulticast {
1547 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1548 return true
1549 }
1550 }
1551 return false
1552}
mpagenko3dbcdd22020-07-22 07:38:45 +00001553
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001554func (oFsm *UniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001555 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1556 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301557 logger.Info(ctx, "UniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001558 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1559 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001560 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001561
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301562 var meParams me.ParamData
ozgecanetsia4b232302020-11-11 10:58:10 +03001563 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1564 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001565
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301566 meParams = me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001567 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001568 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001569 me.MulticastGemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.multicastGemID,
1570 me.MulticastGemInterworkingTerminationPoint_InterworkingOption: 0, // Don't Care
1571 me.MulticastGemInterworkingTerminationPoint_ServiceProfilePointer: 0, // Don't Care
1572 me.MulticastGemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001573 },
1574 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001575 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1576 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1577 continue
1578 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001579 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001580 meInstance, err := oFsm.pOmciCC.SendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1581 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001582 if err != nil {
1583 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001584 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001585 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001586 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001587 return
1588
1589 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001590 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001591 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001592 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001593 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001594 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001595 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001596 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001597 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001598 return
1599 }
1600 ipv4MulticastTable := make([]uint8, 12)
1601 //Gem Port ID
1602 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1603 //Secondary Key
1604 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1605 // Multicast IP range start This is the 224.0.0.1 address
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001606 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], cmn.IPToInt32(net.IPv4(224, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001607 // MulticastIp range stop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001608 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001609
1610 meIPV4MCTableParams := me.ParamData{
1611 EntityID: gemPortAttribs.multicastGemID,
1612 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001613 me.MulticastGemInterworkingTerminationPoint_Ipv4MulticastAddressTable: ipv4MulticastTable,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001614 },
1615 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001616 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001617 meIPV4MCTableInstance, err := oFsm.pOmciCC.SendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1618 true, oFsm.PAdaptFsm.CommChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001619 if err != nil {
1620 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001622 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001624 return
1625 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001626 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001627 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001628
1629 } else {
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301630 meParams = me.ParamData{
ozgecanetsia4b232302020-11-11 10:58:10 +03001631 EntityID: gemPortAttribs.gemPortID,
1632 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001633 me.GemInterworkingTerminationPoint_GemPortNetworkCtpConnectivityPointer: gemPortAttribs.gemPortID, //same as EntityID, see above
1634 me.GemInterworkingTerminationPoint_InterworkingOption: 5, //fixed model:: G.998 .1pMapper
1635 me.GemInterworkingTerminationPoint_ServiceProfilePointer: oFsm.mapperSP0ID,
1636 me.GemInterworkingTerminationPoint_InterworkingTerminationPointPointer: 0, //not used with .1PMapper Mac bridge
1637 me.GemInterworkingTerminationPoint_GalProfilePointer: cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001638 },
1639 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001640 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001641 meInstance, err := oFsm.pOmciCC.SendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1642 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001643 if err != nil {
1644 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001645 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001646 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001647 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001648 return
1649 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001650 //accept also nil as (error) return value for writing to LastTx
1651 // - this avoids misinterpretation of new received OMCI messages
1652 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001653 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001654 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001655 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001657 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001658 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001659 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001660 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001661 return
1662 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301663 logger.Infow(ctx, "Adding GemIWTP to the ONU DB ", log.Fields{"device-id": oFsm.deviceID, "GEMID": gemPortAttribs.gemPortID})
1664 oFsm.pOnuDB.PutMe(ctx, me.GemInterworkingTerminationPointClassID, gemPortAttribs.gemPortID, meParams.Attributes)
1665
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001666 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001667
1668 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001671}
1672
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673func (oFsm *UniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001674 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1675 if oFsm.tcontSetBefore {
1676 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1677 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001678 "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001679 "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001680 go func(aPAFsm *cmn.AdapterFsm) {
1681 if aPAFsm != nil && aPAFsm.PFsm != nil {
1682 _ = aPAFsm.PFsm.Event(aniEvRxPrioqsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001683 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001684 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001685 return
1686 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001687 const cu16StrictPrioWeight uint16 = 0xFFFF
1688 //find all upstream PrioQueues related to this T-Cont
1689 loQueueMap := ordered_map.NewOrderedMap()
1690 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001691 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001692 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001693 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1694 "prioString": gemPortAttribs.pbitString})
1695 continue
1696 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001697 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301698 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001699 //key does not yet exist
1700 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1701 }
1702 } else {
1703 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1704 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001705 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001706
Girish Gowdra09e5f212021-09-30 16:28:36 -07001707 trafficSchedPtrSetSupported := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 loOnu2g := oFsm.pOnuDB.GetMe(me.Onu2GClassID, cmn.Onu2gMeID)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001709 if loOnu2g == nil {
1710 logger.Errorw(ctx, "onu2g is nil, cannot read qos configuration flexibility parameter",
1711 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001712 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001713 return
1714 }
1715 returnVal := loOnu2g["QualityOfServiceQosConfigurationFlexibility"]
1716 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001717 if qosCfgFlexParam, err := oFsm.pOnuDB.GetUint16Attrib(returnVal); err == nil {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001718 trafficSchedPtrSetSupported = qosCfgFlexParam&bitTrafficSchedulerPtrSetPermitted == bitTrafficSchedulerPtrSetPermitted
1719 logger.Debugw(ctx, "trafficSchedPtrSetSupported set",
1720 log.Fields{"qosCfgFlexParam": qosCfgFlexParam, "trafficSchedPtrSetSupported": trafficSchedPtrSetSupported})
1721 } else {
1722 logger.Errorw(ctx, "Cannot extract qos configuration flexibility parameter",
1723 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001724 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001725 return
1726 }
1727 } else {
1728 logger.Errorw(ctx, "Cannot read qos configuration flexibility parameter",
1729 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001730 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001731 return
1732 }
1733
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001734 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1735 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1736 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1737 // or even be finished without correct SP/WRR setting
1738
1739 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1740 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1741 // even though its T-Cont seems to be wrong ...
1742 loTrafficSchedulerEID := 0x8000
1743 //for all found queues
1744 iter := loQueueMap.IterFunc()
1745 for kv, ok := iter(); ok; kv, ok = iter() {
1746 queueIndex := (kv.Key).(uint16)
1747 meParams := me.ParamData{
1748 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301749 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001750 }
Girish Gowdra09e5f212021-09-30 16:28:36 -07001751 if trafficSchedPtrSetSupported {
1752 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1753 //StrictPrio indication
1754 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
1755 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1756 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001757 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = 0 //ensure T-Cont defined StrictPrio scheduling
Girish Gowdra09e5f212021-09-30 16:28:36 -07001758 } else {
1759 //WRR indication
1760 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
1761 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1762 "Weight": kv.Value,
1763 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001764 meParams.Attributes[me.PriorityQueue_TrafficSchedulerPointer] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1765 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Girish Gowdra09e5f212021-09-30 16:28:36 -07001766 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001767 } else {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001768 // setting Traffic Scheduler (TS) pointer is not supported unless we point to another TS that points to the same TCONT.
1769 // 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.
1770 // 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.
1771 if (kv.Value).(uint16) == cu16StrictPrioWeight { // SP case, nothing to be done. Proceed to the next queue
1772 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio, traffic sched ptr set unsupported", log.Fields{
1773 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1774 "device-id": oFsm.deviceID})
1775 continue
1776 }
1777 // WRR case, update weight.
1778 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR, traffic sched ptr set unsupported", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001779 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1780 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001781 "device-id": oFsm.deviceID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001782 meParams.Attributes[me.PriorityQueue_Weight] = uint8(kv.Value.(uint16))
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001783 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001784 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001785 meInstance, err := oFsm.pOmciCC.SendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1786 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001787 if err != nil {
1788 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001789 logger.Errorw(ctx, "PrioQueueVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001790 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001791 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001792 return
1793 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001794 //accept also nil as (error) return value for writing to LastTx
1795 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001796 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001797 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001798
1799 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001800 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001801 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001803 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001804 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001805 return
1806 }
1807
1808 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1809 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1810 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1811 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1812
1813 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001814
1815 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001817 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001818}
1819
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001820func (oFsm *UniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001821 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001822 if oFsm.isCanceled {
1823 // FSM already canceled before entering wait
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001824 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 +00001825 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001826 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00001827 }
mpagenko7d6bb022021-03-11 15:07:55 +00001828 oFsm.isAwaitingResponse = true
1829 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001830 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301831 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001832 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001833 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001834 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 +00001835 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001836 oFsm.mutexIsAwaitingResponse.Lock()
1837 oFsm.isAwaitingResponse = false
1838 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00001839 oFsm.mutexPLastTxMeInstance.RLock()
1840 if oFsm.pLastTxMeInstance != nil {
1841 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
1842 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
1843 }
1844 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001845 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001846 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301847 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001848 logger.Debugw(ctx, "UniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001849 oFsm.mutexIsAwaitingResponse.Lock()
1850 oFsm.isAwaitingResponse = false
1851 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001852 return nil
1853 }
mpagenko7d6bb022021-03-11 15:07:55 +00001854 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001855 logger.Debugw(ctx, "UniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001856 oFsm.mutexIsAwaitingResponse.Lock()
1857 oFsm.isAwaitingResponse = false
1858 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001859 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001860 }
1861}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001862
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001863func (oFsm *UniPonAniConfigFsm) setChanSet(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001864 oFsm.mutexChanSet.Lock()
1865 oFsm.chanSet = flagValue
1866 oFsm.mutexChanSet.Unlock()
1867}
1868
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001869func (oFsm *UniPonAniConfigFsm) isChanSet() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001870 oFsm.mutexChanSet.RLock()
1871 flagValue := oFsm.chanSet
1872 oFsm.mutexChanSet.RUnlock()
1873 return flagValue
1874}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001875
1876// PrepareForGarbageCollection - remove references to prepare for garbage collection
1877func (oFsm *UniPonAniConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301878 logger.Info(ctx, "prepare for garbage collection", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001879 oFsm.pDeviceHandler = nil
1880 oFsm.pOnuDeviceEntry = nil
1881 oFsm.pOmciCC = nil
1882}