blob: cc023bac60b678cd79c6d68ac5eee1582838a581 [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package avcfg provides anig and vlan configuration functionality
18package avcfg
mpagenko3dbcdd22020-07-22 07:38:45 +000019
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
mpagenko7d6bb022021-03-11 15:07:55 +000026 "sync"
mpagenko3dbcdd22020-07-22 07:38:45 +000027 "time"
28
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000029 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000031 "github.com/opencord/omci-lib-go/v2"
32 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000034
khenaidoo7d3c5582021-08-11 18:09:44 -040035 //ic "github.com/opencord/voltha-protos/v5/go/inter_container"
36 //"github.com/opencord/voltha-protos/v5/go/openflow_13"
37 //"github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000038 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
39 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
mpagenko3dbcdd22020-07-22 07:38:45 +000040)
41
mpagenko1cc3cb42020-07-27 15:24:38 +000042const (
43 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000044 aniEvStart = "aniEvStart"
45 aniEvStartConfig = "aniEvStartConfig"
46 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
47 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
48 aniEvRxTcontsResp = "aniEvRxTcontsResp"
49 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
50 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
51 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
52 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
53 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080054 aniEvWaitFlowRem = "aniEvWaitFlowRem"
55 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000056 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
57 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030058 aniEvRxRemTdResp = "aniEvRxRemTdResp"
mpagenko8b07c1b2020-11-26 10:36:31 +000059 aniEvRemTcontPath = "aniEvRemTcontPath"
60 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
61 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
62 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
63 aniEvTimeoutSimple = "aniEvTimeoutSimple"
64 aniEvTimeoutMids = "aniEvTimeoutMids"
65 aniEvReset = "aniEvReset"
66 aniEvRestart = "aniEvRestart"
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +000067 aniEvSkipOmciConfig = "aniEvSkipOmciConfig"
Mahir Gunyel9545be22021-07-04 15:53:16 -070068 aniEvRemGemDone = "aniEvRemGemDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000069)
70const (
71 // states of config PON ANI port FSM
72 aniStDisabled = "aniStDisabled"
73 aniStStarting = "aniStStarting"
74 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
75 aniStCreatingMBPCD = "aniStCreatingMBPCD"
76 aniStSettingTconts = "aniStSettingTconts"
77 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
78 aniStCreatingGemIWs = "aniStCreatingGemIWs"
79 aniStSettingPQs = "aniStSettingPQs"
80 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
81 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000082 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080083 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000084 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030085 aniStRemovingTD = "aniStRemovingTD"
mpagenko8b07c1b2020-11-26 10:36:31 +000086 aniStResetTcont = "aniStResetTcont"
87 aniStRemDot1PMapper = "aniStRemDot1PMapper"
88 aniStRemAniBPCD = "aniStRemAniBPCD"
89 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000090 aniStResetting = "aniStResetting"
91)
92
Girish Gowdra09e5f212021-09-30 16:28:36 -070093const (
94 bitTrafficSchedulerPtrSetPermitted = 0x0002 // Refer section 9.1.2 ONU-2G, table for "Quality of service (QoS) configuration flexibility" IE
95)
96
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000097// CAniFsmIdleState - TODO: add comment
98const CAniFsmIdleState = aniStConfigDone
99
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000100type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +0300101 gemPortID uint16
102 upQueueID uint16
103 downQueueID uint16
104 direction uint8
105 qosPolicy string
106 weight uint8
107 pbitString string
108 isMulticast bool
109 multicastGemID uint16
110 staticACL string
111 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000112}
113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000114//UniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
115type UniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000116 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117 pDeviceHandler cmn.IdeviceHandler
118 pOnuDeviceEntry cmn.IonuDeviceEntry
119 pOmciCC *cmn.OmciCC
120 pOnuUniPort *cmn.OnuUniPort
121 pUniTechProf *OnuUniTechProf
122 pOnuDB *devdb.OnuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800123 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000124 uniTpKey uniTP
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125 requestEvent cmn.OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000126 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000127 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000128 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530129 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000130 PAdaptFsm *cmn.AdapterFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000131 chSuccess chan<- uint8
132 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000133 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000134 chanSet bool
135 mapperSP0ID uint16
136 macBPCD0ID uint16
137 tcont0ID uint16
138 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000139 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000140 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000141 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000142 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000143 isWaitingForFlowDelete bool
144 waitFlowDeleteChannel chan bool
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700145 tcontSetBefore bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000146}
147
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000148//NewUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
149func NewUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort, apUniTechProf *OnuUniTechProf,
150 apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8, aRequestEvent cmn.OnuDeviceEvent, aName string,
151 apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, aCommChannel chan cmn.Message) *UniPonAniConfigFsm {
152 instFsm := &UniPonAniConfigFsm{
153 pDeviceHandler: apDeviceHandler,
154 pOnuDeviceEntry: apOnuDeviceEntry,
155 deviceID: apDeviceHandler.GetDeviceID(),
156 pOmciCC: apDevOmciCC,
157 pOnuUniPort: apUniPort,
158 pUniTechProf: apUniTechProf,
159 pOnuDB: apOnuDB,
160 techProfileID: aTechProfileID,
161 requestEvent: aRequestEvent,
162 chanSet: false,
163 tcontSetBefore: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000164 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000165 instFsm.uniTpKey = uniTP{uniID: apUniPort.UniID, tpID: aTechProfileID}
mpagenkobb47bc22021-04-20 13:29:09 +0000166 instFsm.waitFlowDeleteChannel = make(chan bool)
mpagenko8b07c1b2020-11-26 10:36:31 +0000167
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000168 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
169 if instFsm.PAdaptFsm == nil {
170 logger.Errorw(ctx, "UniPonAniConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000171 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000172 return nil
173 }
174
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000175 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000176 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000177 fsm.Events{
178
mpagenko1cc3cb42020-07-27 15:24:38 +0000179 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000180
181 //Note: .1p-Mapper and MBPCD might also have multi instances (per T-Cont) - by now only one 1 T-Cont considered!
mpagenko1cc3cb42020-07-27 15:24:38 +0000182 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000183 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000184 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
185 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000186 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000187 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000188 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000189 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000190 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000191 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000192 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000193
mpagenko8b07c1b2020-11-26 10:36:31 +0000194 //for removing Gem related resources
195 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800196 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
197 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000198 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300199 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700200 {Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStRemDot1PMapper},
201 {Name: aniEvRemGemDone, Src: []string{aniStRemDot1PMapper}, Dst: aniStConfigDone},
202 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
203 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000204
205 //for removing TCONT related resources
206 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700207 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStConfigDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000208
209 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300210 aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000211 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000212 {Name: aniEvTimeoutMids, Src: []string{
213 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000214
mpagenko1cc3cb42020-07-27 15:24:38 +0000215 // exceptional treatment for all states except aniStResetting
216 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
217 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300218 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000219 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000220 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000221 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000222 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000223 },
224
225 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000226 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
228 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
229 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
230 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
231 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
232 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
233 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
234 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
235 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
236 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000237 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000238 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300239 ("enter_" + aniStRemovingTD): func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000240 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
241 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
242 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
243 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
244 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
245 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000246 },
247 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 if instFsm.PAdaptFsm.PFsm == nil {
249 logger.Errorw(ctx, "UniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000250 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000251 return nil
252 }
253
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 logger.Debugw(ctx, "UniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000255 return instFsm
256}
257
Himani Chawla6d2ae152020-09-02 13:11:20 +0530258//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259func (oFsm *UniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000260 oFsm.chSuccess = aChSuccess
261 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000262 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000263}
264
mpagenko7d6bb022021-03-11 15:07:55 +0000265//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000266func (oFsm *UniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko73143992021-04-09 15:17:10 +0000267 //early indication about started reset processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000268 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000269 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000270 oFsm.mutexIsAwaitingResponse.Lock()
271 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000272 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000273 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
274 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
275 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000276 //use channel to indicate that the response waiting shall be aborted
277 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000278 } else {
279 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000280 }
mpagenkocf48e452021-04-23 09:23:00 +0000281
282 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000283 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000284 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000285 //use channel to indicate that the response waiting shall be aborted
286 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000287 } else {
288 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000289 }
mpagenkocf48e452021-04-23 09:23:00 +0000290
mpagenko7d6bb022021-03-11 15:07:55 +0000291 // 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 +0000292 PAdaptFsm := oFsm.PAdaptFsm
293 if PAdaptFsm != nil {
mpagenko7d6bb022021-03-11 15:07:55 +0000294 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000295 go func(aPAFsm *cmn.AdapterFsm) {
296 if aPAFsm.PFsm != nil {
297 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
mpagenko7d6bb022021-03-11 15:07:55 +0000298 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000299 }(PAdaptFsm)
mpagenko7d6bb022021-03-11 15:07:55 +0000300 }
mpagenko73143992021-04-09 15:17:10 +0000301
mpagenko45cc6a32021-07-23 10:06:57 +0000302 // possible access conflicts on internal data by next needed data clearance
303 // are avoided by using mutexTPState also from within clearAniSideConfig
304 // do not try to lock TpProcMutex here as done in previous code version
305 // as it may result in deadlock situations (as observed at soft-reboot handling where
306 // TpProcMutex is already locked by some ongoing TechProfile config/removal processing
mpagenko73143992021-04-09 15:17:10 +0000307 //remove all TechProf related internal data to allow for new configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000308 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.UniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000309}
310
Mahir Gunyel6781f962021-05-16 23:30:08 -0700311//nolint: gocyclo
312//TODO:visit here for refactoring for gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000313func (oFsm *UniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *cmn.AdapterFsm) {
314 if aPAFsm != nil && aPAFsm.PFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700315 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000316 oFsm.mapperSP0ID, err = cmn.GenerateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.techProfileID))
Mahir Gunyel6781f962021-05-16 23:30:08 -0700317 if err != nil {
318 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
319 "techProfileID": oFsm.techProfileID, "error": err})
320 return
321 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000322 oFsm.macBPCD0ID, err = cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.techProfileID))
Mahir Gunyel6781f962021-05-16 23:30:08 -0700323 if err != nil {
324 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
325 "techProfileID": oFsm.techProfileID, "error": err})
326 return
327 }
328 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
329 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000330 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "techProfileID": oFsm.techProfileID})
331 if oFsm.pOnuDeviceEntry == nil {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700332 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800333 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530334 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000335 tcontInstID, tcontAlreadyExist, err := oFsm.pOnuDeviceEntry.AllocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700336 if err != nil {
337 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700338 //reset the state machine to enable usage on subsequent requests
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000339 _ = aPAFsm.PFsm.Event(aniEvReset)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700340 return
341 }
342 oFsm.tcont0ID = tcontInstID
343 oFsm.tcontSetBefore = tcontAlreadyExist
344 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
345 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
346 "tcontAlreadyExist": tcontAlreadyExist,
347 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800348
349 // Access critical state with lock
mpagenko3ce9fa02021-07-28 13:26:54 +0000350 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000351 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
352 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko3ce9fa02021-07-28 13:26:54 +0000353 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800354
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800356 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300357 loGemPortAttribs := ponAniGemPortAttribs{}
358
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
360
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 if queueInstKeys := oFsm.pOnuDB.GetSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530362
363 loGemPortAttribs.gemPortID = gemEntry.gemPortID
364 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
365 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
366 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
367 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
368
369 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000370 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.UniID,
Himani Chawla26e555c2020-08-31 12:30:20 +0530371 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
372 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
373 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.UniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
Himani Chawla26e555c2020-08-31 12:30:20 +0530375
376 usQueueFound := false
377 dsQueueFound := false
378 for _, mgmtEntityID := range queueInstKeys {
379 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
380 returnVal := meAttributes["RelatedPort"]
381 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 if relatedPort, err := oFsm.pOnuDB.GetUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530383 if relatedPort == usQrelPortMask {
384 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000385 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000386 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 usQueueFound = true
388 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
389 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000391 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 dsQueueFound = true
393 }
394 if usQueueFound && dsQueueFound {
395 break
396 }
397 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 }
400 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000401 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530402 }
403 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000404 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000405 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530406 }
407 }
408 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000409 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 }
411 loGemPortAttribs.direction = gemEntry.direction
412 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
413 loGemPortAttribs.weight = gemEntry.queueWeight
414 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300415
ozgecanetsia4b232302020-11-11 10:58:10 +0300416 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300417 //TODO this might effectively ignore the for loop starting at line 316
418 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300419 loGemPortAttribs.isMulticast = true
420 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
421 loGemPortAttribs.staticACL = gemEntry.staticACL
422 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530423
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300425 "gemPortID": loGemPortAttribs.gemPortID,
426 "isMulticast": loGemPortAttribs.isMulticast,
427 "multicastGemID": loGemPortAttribs.multicastGemID,
428 "staticACL": loGemPortAttribs.staticACL,
429 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000430 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300431 })
432
433 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000434 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300435 "gemPortID": loGemPortAttribs.gemPortID,
436 "upQueueID": loGemPortAttribs.upQueueID,
437 "downQueueID": loGemPortAttribs.downQueueID,
438 "pbitString": loGemPortAttribs.pbitString,
439 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000440 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300441 })
442 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530443
444 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
445 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000446 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
447 _ = aPAFsm.PFsm.Event(aniEvStartConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000448 } else {
449 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000450 _ = aPAFsm.PFsm.Event(aniEvSkipOmciConfig)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000451 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 }
453}
454
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455func (oFsm *UniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000456 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000457 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000458 // in case the used channel is not yet defined (can be re-used after restarts)
459 if oFsm.omciMIdsResponseReceived == nil {
460 oFsm.omciMIdsResponseReceived = make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000461 logger.Debug(ctx, "UniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000462 } else {
463 // as we may 're-use' this instance of FSM and the connected channel
464 // make sure there is no 'lingering' request in the already existing channel:
465 // (simple loop sufficient as we are the only receiver)
466 for len(oFsm.omciMIdsResponseReceived) > 0 {
467 <-oFsm.omciMIdsResponseReceived
468 }
469 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000470 //ensure internal slices are empty (which might be set from previous run) - release memory
471 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000472 oFsm.mutexIsAwaitingResponse.Lock()
473 //reset the canceled state possibly existing from previous reset
474 oFsm.isCanceled = false
475 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000476
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000477 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000479
480 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000481 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +0000482 if pConfigAniStateAFsm != nil {
483 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000485
mpagenko3dbcdd22020-07-22 07:38:45 +0000486 }
487}
488
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000489func (oFsm *UniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
490 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000491 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000493 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000494 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000495 meInstance, err := oFsm.pOmciCC.SendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
496 oFsm.mapperSP0ID, oFsm.PAdaptFsm.CommChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300497 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 logger.Errorw(ctx, "Dot1PMapper create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300499 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000500 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300501 if pConfigAniStateAFsm != nil {
502 oFsm.mutexPLastTxMeInstance.Unlock()
503 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000504 go func(aPAFsm *cmn.AdapterFsm) {
505 if aPAFsm != nil && aPAFsm.PFsm != nil {
506 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300507 }
508 }(pConfigAniStateAFsm)
509 return
510 }
511 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000512 //accept also nil as (error) return value for writing to LastTx
513 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000514 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300515 oFsm.mutexPLastTxMeInstance.Unlock()
516
mpagenko3dbcdd22020-07-22 07:38:45 +0000517}
518
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000519func (oFsm *UniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
520 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000521 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
522 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
524 bridgePtr := cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
mpagenko3dbcdd22020-07-22 07:38:45 +0000525 meParams := me.ParamData{
526 EntityID: oFsm.macBPCD0ID,
527 Attributes: me.AttributeValueMap{
528 "BridgeIdPointer": bridgePtr,
529 "PortNum": 0xFF, //fixed unique ANI side indication
530 "TpType": 3, //for .1PMapper
531 "TpPointer": oFsm.mapperSP0ID,
532 },
533 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000534 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
536 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300537 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000538 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300539 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300541 if pConfigAniStateAFsm != nil {
542 oFsm.mutexPLastTxMeInstance.Unlock()
543 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000544 go func(aPAFsm *cmn.AdapterFsm) {
545 if aPAFsm != nil && aPAFsm.PFsm != nil {
546 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300547 }
548 }(pConfigAniStateAFsm)
549 return
550 }
551 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000552 //accept also nil as (error) return value for writing to LastTx
553 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000554 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300555 oFsm.mutexPLastTxMeInstance.Unlock()
556
mpagenko3dbcdd22020-07-22 07:38:45 +0000557}
558
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000559func (oFsm *UniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
560 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000561 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
562 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000563 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700564 "tcontExist": oFsm.tcontSetBefore})
565 //If tcont was set before, then no need to set it again. Let state machine to proceed.
566 if oFsm.tcontSetBefore {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000567 go func(aPAFsm *cmn.AdapterFsm) {
568 if aPAFsm != nil && aPAFsm.PFsm != nil {
569 _ = aPAFsm.PFsm.Event(aniEvRxTcontsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700570 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700572 return
573 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000574 meParams := me.ParamData{
575 EntityID: oFsm.tcont0ID,
576 Attributes: me.AttributeValueMap{
577 "AllocId": oFsm.alloc0ID,
578 },
579 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000580 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000581 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
582 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300583 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300585 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000586 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300587 if pConfigAniStateAFsm != nil {
588 oFsm.mutexPLastTxMeInstance.Unlock()
589 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 go func(aPAFsm *cmn.AdapterFsm) {
591 if aPAFsm != nil && aPAFsm.PFsm != nil {
592 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300593 }
594 }(pConfigAniStateAFsm)
595 return
596 }
597 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000598 //accept also nil as (error) return value for writing to LastTx
599 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000600 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300601 oFsm.mutexPLastTxMeInstance.Unlock()
602
mpagenko3dbcdd22020-07-22 07:38:45 +0000603}
604
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605func (oFsm *UniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
606 logger.Debugw(ctx, "UniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
607 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000609}
610
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611func (oFsm *UniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
612 logger.Debugw(ctx, "UniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
613 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000615}
616
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000617func (oFsm *UniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
618 logger.Debugw(ctx, "UniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000619 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000621}
622
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000623func (oFsm *UniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300624
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000625 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000626 "toGemIw": 1024, /* cmp above */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000627 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000628
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000629 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000630 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000631 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000632
mpagenko3dbcdd22020-07-22 07:38:45 +0000633 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000634 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530635 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000636 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000637
638 //assign the GemPorts according to the configured Prio
639 var loPrioGemPortArray [8]uint16
640 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300641 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300643 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
644 "prioString": gemPortAttribs.pbitString})
645 continue
646 }
647 if gemPortAttribs.pbitString == "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300649 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
650 "prioString": gemPortAttribs.pbitString})
651 continue
652 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000653 for i := 0; i < 8; i++ {
654 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
655 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
656 if prio == 1 { // Check this p-bit is set
657 if loPrioGemPortArray[i] == 0 {
658 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
659 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000660 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000661 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000662 "SetGemPort": loPrioGemPortArray[i]})
663 }
664 }
665 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000666 logger.Warnw(ctx, "UniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000667 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000668 "prioString": gemPortAttribs.pbitString, "position": i})
669 }
670
671 }
672 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300673
ozgecanetsia4b232302020-11-11 10:58:10 +0300674 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530675 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300676 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530677 if value != 0 {
678 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530679 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000681 "for Prio": index,
682 "IwPtr": strconv.FormatInt(int64(value), 16),
683 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300684 } else {
685 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000686 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
687 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300688 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530689 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000690 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300691 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000692 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
693 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300694 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530695
696 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000698 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300699 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
700 // 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 +0000701 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000702 //pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300703 //if pConfigAniStateAFsm != nil {
704 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000705 // go func(aPAFsm *cmn.AdapterFsm) {
706 // if aPAFsm != nil && aPAFsm.PFsm != nil {
707 // _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300708 // }
709 // }(pConfigAniStateAFsm)
710 //}
711 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000712 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000713 if pConfigAniStateAFsm != nil {
714 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000715 go func(aPAFsm *cmn.AdapterFsm) {
716 if aPAFsm != nil && aPAFsm.PFsm != nil {
717 _ = aPAFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000718 }
719 }(pConfigAniStateAFsm)
720 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300721 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000722 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000723 meInstance, err := oFsm.pOmciCC.SendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
724 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300725 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000726 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300727 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000728 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300729 if pConfigAniStateAFsm != nil {
730 oFsm.mutexPLastTxMeInstance.Unlock()
731 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000732 go func(aPAFsm *cmn.AdapterFsm) {
733 if aPAFsm != nil && aPAFsm.PFsm != nil {
734 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300735 }
736 }(pConfigAniStateAFsm)
737 return
738 }
739 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300740 //accept also nil as (error) return value for writing to LastTx
741 // - this avoids misinterpretation of new received OMCI messages
742 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300743 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000744 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000745}
746
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000747func (oFsm *UniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
748 logger.Debugw(ctx, "UniPonAniConfigFsm ani config done", log.Fields{
749 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000750 //store that the UNI related techProfile processing is done for the given Profile and Uni
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000751 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.UniID, oFsm.techProfileID, true)
752 if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000753 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000754 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000755 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
756 // but only in case the techProfile was configured (not deleted)
757 if oFsm.requestEventOffset == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000758 go oFsm.pDeviceHandler.VerifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000759 }
760 } else {
761 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000762 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000763 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000764 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000765 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000766 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
767 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000768 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000769 }
mpagenko01e726e2020-10-23 09:45:29 +0000770
771 //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 +0000772}
773
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000774func (oFsm *UniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000775 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
776 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000777 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
778 select {
779 case <-oFsm.waitFlowDeleteChannel:
780 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
781 default:
782 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000783
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000784 uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.UniID)
785 if uniVlanConfigFsm != nil {
mpagenko3ce9fa02021-07-28 13:26:54 +0000786 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000787 if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000788 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000789 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000790 // 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 +0000791 pConfigAniStateAFsm := oFsm.PAdaptFsm
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000792 if pConfigAniStateAFsm != nil {
793 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000794 go func(aPAFsm *cmn.AdapterFsm) {
795 if aPAFsm != nil && aPAFsm.PFsm != nil {
796 _ = aPAFsm.PFsm.Event(aniEvWaitFlowRem)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000797 }
798 }(pConfigAniStateAFsm)
799 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800 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 +0000801 }
802 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800803 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000804 } else {
805 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
806 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800807 }
808
mpagenko3ce9fa02021-07-28 13:26:54 +0000809 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000810 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000811 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000812 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000813 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
814 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000815 "GemIwTp-entity-id": loGemPortID})
816 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
817
818 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000819 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820 meInstance, err := oFsm.pOmciCC.SendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
821 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300822 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 logger.Errorw(ctx, "GemIWTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300824 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000825 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300826 if pConfigAniStateAFsm != nil {
827 oFsm.mutexPLastTxMeInstance.Unlock()
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 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300832 }
833 }(pConfigAniStateAFsm)
834 return
835 }
836 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000837 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300838 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000839}
840
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000841func (oFsm *UniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
mpagenkobb47bc22021-04-20 13:29:09 +0000842 oFsm.mutexIsAwaitingResponse.Lock()
843 oFsm.isWaitingForFlowDelete = true
844 oFsm.mutexIsAwaitingResponse.Unlock()
845 select {
846 // maybe be also some outside cancel (but no context modeled for the moment ...)
847 // case <-ctx.Done():
848 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000849 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 +0000850 logger.Warnw(ctx, "UniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
851 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000852 oFsm.mutexIsAwaitingResponse.Lock()
853 oFsm.isWaitingForFlowDelete = false
854 oFsm.mutexIsAwaitingResponse.Unlock()
855 //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 +0000856 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000857 if pConfigAniStateAFsm != nil {
858 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 go func(aPAFsm *cmn.AdapterFsm) {
860 if aPAFsm != nil && aPAFsm.PFsm != nil {
861 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000862 }
863 }(pConfigAniStateAFsm)
864 } else {
865 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000867 }
868 return
869
870 case success := <-oFsm.waitFlowDeleteChannel:
871 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000872 logger.Debugw(ctx, "UniPonAniConfigFsm flow removed info received", log.Fields{
873 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000874 oFsm.mutexIsAwaitingResponse.Lock()
875 oFsm.isWaitingForFlowDelete = false
876 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000878 if pConfigAniStateAFsm != nil {
879 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 go func(aPAFsm *cmn.AdapterFsm) {
881 if aPAFsm != nil && aPAFsm.PFsm != nil {
882 _ = aPAFsm.PFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000883 }
884 }(pConfigAniStateAFsm)
885 } else {
886 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000887 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000888 }
889 return
890 }
891 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 logger.Debugw(ctx, "UniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
893 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
mpagenkobb47bc22021-04-20 13:29:09 +0000894 oFsm.mutexIsAwaitingResponse.Lock()
895 oFsm.isWaitingForFlowDelete = false
896 oFsm.mutexIsAwaitingResponse.Unlock()
897 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000898 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenkobb47bc22021-04-20 13:29:09 +0000899 if pConfigAniStateAFsm != nil {
900 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 go func(aPAFsm *cmn.AdapterFsm) {
902 if aPAFsm != nil && aPAFsm.PFsm != nil {
903 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenkobb47bc22021-04-20 13:29:09 +0000904 }
905 }(pConfigAniStateAFsm)
906 }
907 return
908 }
909}
910
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911func (oFsm *UniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000912 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000913 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000914 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000915 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
916 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000917 "GemNCTP-entity-id": loGemPortID})
918 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000919 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000920 meInstance, err := oFsm.pOmciCC.SendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
921 oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300922 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000923 logger.Errorw(ctx, "GemNCTP delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300924 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000925 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300926 if pConfigAniStateAFsm != nil {
927 oFsm.mutexPLastTxMeInstance.Unlock()
928 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000929 go func(aPAFsm *cmn.AdapterFsm) {
930 if aPAFsm != nil && aPAFsm.PFsm != nil {
931 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300932 }
933 }(pConfigAniStateAFsm)
934 return
935 }
936 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000937 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000938 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300939
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800940 // Mark the gem port to be removed for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
942 if OnuMetricsManager != nil {
943 OnuMetricsManager.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800944 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000945}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000946func (oFsm *UniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000947 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300948 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000949 oFsm.pUniTechProf.mutexTPState.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000950 logger.Debugw(ctx, "UniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
951 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300952 "TD-entity-id": loGemPortID})
953
954 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 meInstance, err := oFsm.pOmciCC.SendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
956 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, loGemPortID)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300957
958 if err != nil {
959 logger.Errorw(ctx, "TD delete failed - proceed fsm",
960 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000961 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300962 if pConfigAniStateAFsm != nil {
963 oFsm.mutexPLastTxMeInstance.Unlock()
964 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 go func(aPAFsm *cmn.AdapterFsm) {
966 if aPAFsm != nil && aPAFsm.PFsm != nil {
967 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300968 }
969 }(pConfigAniStateAFsm)
970 return
971 }
972 }
973 oFsm.pLastTxMeInstance = meInstance
974 oFsm.mutexPLastTxMeInstance.Unlock()
975}
mpagenko8b07c1b2020-11-26 10:36:31 +0000976
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000977func (oFsm *UniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
978 logger.Debugw(ctx, "UniPonAniConfigFsm - start resetting the TCont", log.Fields{
979 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000980
981 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
982 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
983 meParams := me.ParamData{
984 EntityID: oFsm.tcont0ID,
985 Attributes: me.AttributeValueMap{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000986 "AllocId": cmn.UnusedTcontAllocID,
mpagenko8b07c1b2020-11-26 10:36:31 +0000987 },
988 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000989 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 meInstance, err := oFsm.pOmciCC.SendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
991 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300992 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 logger.Errorw(ctx, "TcontVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +0300994 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000995 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +0300996 if pConfigAniStateAFsm != nil {
997 oFsm.mutexPLastTxMeInstance.Unlock()
998 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 go func(aPAFsm *cmn.AdapterFsm) {
1000 if aPAFsm != nil && aPAFsm.PFsm != nil {
1001 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001002 }
1003 }(pConfigAniStateAFsm)
1004 return
1005 }
1006 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001007 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001008 oFsm.mutexPLastTxMeInstance.Unlock()
1009
mpagenko8b07c1b2020-11-26 10:36:31 +00001010}
1011
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012func (oFsm *UniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
1013 logger.Debugw(ctx, "UniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
1014 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Mahir Gunyel9545be22021-07-04 15:53:16 -07001015 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1016 unicastGemCount := 0
1017 for _, gemEntry := range mapGemPortParams {
1018 if !gemEntry.isMulticast {
1019 unicastGemCount++
1020 }
1021 }
1022 if unicastGemCount > 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001023 logger.Debugw(ctx, "UniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1024 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1025 pConfigAniStateAFsm := oFsm.PAdaptFsm
Mahir Gunyel9545be22021-07-04 15:53:16 -07001026 if pConfigAniStateAFsm != nil {
1027 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 go func(aPAFsm *cmn.AdapterFsm) {
1029 if aPAFsm != nil && aPAFsm.PFsm != nil {
1030 _ = aPAFsm.PFsm.Event(aniEvRemGemDone)
Mahir Gunyel9545be22021-07-04 15:53:16 -07001031 }
1032 }(pConfigAniStateAFsm)
1033 return
1034 }
1035 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 logger.Debugw(ctx, "UniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1037 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001038
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001039 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 meInstance, err := oFsm.pOmciCC.SendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1041 oFsm.PAdaptFsm.CommChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001042 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001043 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001044 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001045 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001046 if pConfigAniStateAFsm != nil {
1047 oFsm.mutexPLastTxMeInstance.Unlock()
1048 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 go func(aPAFsm *cmn.AdapterFsm) {
1050 if aPAFsm != nil && aPAFsm.PFsm != nil {
1051 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001052 }
1053 }(pConfigAniStateAFsm)
1054 return
1055 }
1056 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001057 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001058 oFsm.mutexPLastTxMeInstance.Unlock()
1059
mpagenko8b07c1b2020-11-26 10:36:31 +00001060}
1061
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001062func (oFsm *UniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1063 logger.Debugw(ctx, "UniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
1064 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001065
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001066 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001067 meInstance, err := oFsm.pOmciCC.SendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1068 oFsm.PAdaptFsm.CommChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001069 if err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001070 logger.Errorw(ctx, "MBPConfigData delete failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001071 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001072 pConfigAniStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001073 if pConfigAniStateAFsm != nil {
1074 oFsm.mutexPLastTxMeInstance.Unlock()
1075 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001076 go func(aPAFsm *cmn.AdapterFsm) {
1077 if aPAFsm != nil && aPAFsm.PFsm != nil {
1078 _ = aPAFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001079 }
1080 }(pConfigAniStateAFsm)
1081 return
1082 }
1083 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001084 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001085 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001086}
1087
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001088func (oFsm *UniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1089 logger.Debugw(ctx, "UniPonAniConfigFsm ani removal done", log.Fields{
1090 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001091 //use DeviceHandler event notification directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001092 oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001093 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001094 // indicate processing done to the caller
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001095 logger.Debugw(ctx, "UniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001096 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1097 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001098 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001099 }
1100
1101 //let's reset the state machine in order to release all resources now
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001102 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko8b07c1b2020-11-26 10:36:31 +00001103 if pConfigAniStateAFsm != nil {
1104 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001105 go func(aPAFsm *cmn.AdapterFsm) {
1106 if aPAFsm != nil && aPAFsm.PFsm != nil {
1107 _ = aPAFsm.PFsm.Event(aniEvReset)
mpagenko8b07c1b2020-11-26 10:36:31 +00001108 }
1109 }(pConfigAniStateAFsm)
1110 }
1111}
1112
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113func (oFsm *UniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1114 logger.Debugw(ctx, "UniPonAniConfigFsm resetting", log.Fields{
1115 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001116
mpagenko45cc6a32021-07-23 10:06:57 +00001117 if oFsm.isChanSet() {
1118 // indicate processing error to the caller (in case there was still some open request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001119 logger.Debugw(ctx, "UniPonAniConfigFsm processingError on channel", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001120 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1121 //use non-blocking channel send to avoid blocking because of non-existing receiver
1122 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1123 select {
1124 case oFsm.chSuccess <- 0:
1125 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001126 logger.Debugw(ctx, "UniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
mpagenko45cc6a32021-07-23 10:06:57 +00001127 "device-id": oFsm.deviceID})
1128 }
1129 oFsm.setChanSet(false) //reset the internal channel state
1130 }
1131
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001132 pConfigAniStateAFsm := oFsm.PAdaptFsm
mpagenko3dbcdd22020-07-22 07:38:45 +00001133 if pConfigAniStateAFsm != nil {
1134 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001135 fsmAbortMsg := cmn.Message{
1136 Type: cmn.TestMsg,
1137 Data: cmn.TestMessage{
1138 TestMessageVal: cmn.AbortMessageProcessing,
mpagenko3dbcdd22020-07-22 07:38:45 +00001139 },
1140 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001141 pConfigAniStateAFsm.CommChan <- fsmAbortMsg
mpagenko3dbcdd22020-07-22 07:38:45 +00001142
1143 //try to restart the FSM to 'disabled', decouple event transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001144 go func(aPAFsm *cmn.AdapterFsm) {
1145 if aPAFsm != nil && aPAFsm.PFsm != nil {
1146 _ = aPAFsm.PFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001147 }
1148 }(pConfigAniStateAFsm)
1149 }
1150}
1151
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001152func (oFsm *UniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1153 logger.Debugw(ctx, "UniPonAniConfigFsm enters disabled state", log.Fields{
1154 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001155 oFsm.mutexPLastTxMeInstance.Lock()
1156 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001157 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001158}
1159
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001160func (oFsm *UniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1161 logger.Debugw(ctx, "Start UniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001162loop:
1163 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001164 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001165 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001166 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001167 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301168 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301170 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001171 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301172 break loop
1173 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001174 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301175
1176 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001177 case cmn.TestMsg:
1178 msg, _ := message.Data.(cmn.TestMessage)
1179 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001180 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001181 break loop
1182 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001183 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001184 case cmn.OMCI:
1185 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001186 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301187 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301189 "message.Type": message.Type})
1190 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001191
Himani Chawla4d908332020-08-31 12:30:20 +05301192 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001193 logger.Infow(ctx, "End UniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301194}
1195
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001196func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301197 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1198 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001199 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001200 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301201 return
1202 }
1203 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1204 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001206 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301207 return
1208 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001209 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001210 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1211 //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 +00001212 oFsm.mutexPLastTxMeInstance.RLock()
1213 if oFsm.pLastTxMeInstance != nil {
1214 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1215 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1216 // maybe we can use just the same eventName for different state transitions like "forward"
1217 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1218 switch oFsm.pLastTxMeInstance.GetName() {
1219 case "Ieee8021PMapperServiceProfile":
1220 { // let the FSM proceed ...
1221 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001222 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapCResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001223 }
1224 case "MacBridgePortConfigurationData":
1225 { // let the FSM proceed ...
1226 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001227 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxMbpcdResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001228 }
1229 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1230 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1231 oFsm.mutexPLastTxMeInstance.RUnlock()
1232 oFsm.omciMIdsResponseReceived <- true
1233 }
1234 default:
1235 {
1236 oFsm.mutexPLastTxMeInstance.RUnlock()
1237 logger.Warnw(ctx, "Unsupported ME name received!",
1238 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1239 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001240 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001241 } else {
1242 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001243 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001244 } else {
1245 oFsm.mutexPLastTxMeInstance.RUnlock()
1246 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001247 }
1248 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001249 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1250 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301251 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1252 return
1253 }
Himani Chawla4d908332020-08-31 12:30:20 +05301254}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001255func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
Mahir Gunyel01034b62021-06-29 11:25:09 -07001256 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1257 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1258 oFsm.mutexPLastTxMeInstance.RLock()
1259 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1260 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1261 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1262 switch oFsm.pLastTxMeInstance.GetName() {
1263 case "TCont":
1264 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1265 //We should revert DB
1266 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1267 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1268 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 if oFsm.pOnuDeviceEntry != nil {
1270 oFsm.pOnuDeviceEntry.FreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
Mahir Gunyel01034b62021-06-29 11:25:09 -07001271 } else {
1272 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1273 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1274 }
1275 }
1276 default:
1277 logger.Warnw(ctx, "Unsupported ME name received with error!",
1278 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1279 }
1280 }
1281}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301283 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1284 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001286 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301287 return
1288 }
1289 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1290 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001292 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301293 return
1294 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001295 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301296 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001297 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001298 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301299 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001300
Mahir Gunyel01034b62021-06-29 11:25:09 -07001301 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301302 return
1303 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001304 oFsm.mutexPLastTxMeInstance.RLock()
1305 if oFsm.pLastTxMeInstance != nil {
1306 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1307 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1308 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1309 // if, then something like:
1310 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301311
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001312 switch oFsm.pLastTxMeInstance.GetName() {
1313 case "TCont":
1314 { // let the FSM proceed ...
1315 oFsm.mutexPLastTxMeInstance.RUnlock()
1316 if oFsm.requestEventOffset == 0 { //from TCont config request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxTcontsResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001318 } else { // from T-Cont reset request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxResetTcontResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001320 }
1321 }
1322 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1323 { // let the PrioQueue init proceed by stopping the wait function
1324 oFsm.mutexPLastTxMeInstance.RUnlock()
1325 oFsm.omciMIdsResponseReceived <- true
1326 }
1327 case "Ieee8021PMapperServiceProfile":
1328 { // let the FSM proceed ...
1329 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001330 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001331 }
1332 default:
1333 {
1334 oFsm.mutexPLastTxMeInstance.RUnlock()
1335 logger.Warnw(ctx, "Unsupported ME name received!",
1336 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001337 }
Himani Chawla4d908332020-08-31 12:30:20 +05301338 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001339 } else {
1340 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301341 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001342 } else {
1343 oFsm.mutexPLastTxMeInstance.RUnlock()
1344 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301345 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001346}
1347
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001348func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001349 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1350 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001352 log.Fields{"device-id": oFsm.deviceID})
1353 return
1354 }
1355 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1356 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001357 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001358 log.Fields{"device-id": oFsm.deviceID})
1359 return
1360 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001361 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001362 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001363 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001364 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1365 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1366 // store error for mgmt display?
1367 return
1368 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001369 oFsm.mutexPLastTxMeInstance.RLock()
1370 if oFsm.pLastTxMeInstance != nil {
1371 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1372 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1373 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1374 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001375
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001376 switch oFsm.pLastTxMeInstance.GetName() {
1377 case "GemInterworkingTerminationPoint":
1378 { // let the FSM proceed ...
1379 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001380 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemiwResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001381 }
1382 case "GemPortNetworkCtp":
1383 { // let the FSM proceed ...
1384 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001385 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemGemntpResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001386 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001387 case "TrafficDescriptor":
1388 { // let the FSM proceed ...
1389 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001390 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemTdResp)
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001391 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001392 case "Ieee8021PMapperServiceProfile":
1393 { // let the FSM proceed ...
1394 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001395 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRem1pMapperResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001396 }
1397 case "MacBridgePortConfigurationData":
1398 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1399 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001400 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxRemAniBPCDResp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001401 }
1402 default:
1403 {
1404 oFsm.mutexPLastTxMeInstance.RUnlock()
1405 logger.Warnw(ctx, "Unsupported ME name received!",
1406 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1407 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001408 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001409 } else {
1410 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001411 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001412 } else {
1413 oFsm.mutexPLastTxMeInstance.RUnlock()
1414 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001415 }
1416}
1417
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001418func (oFsm *UniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001420 "msgType": msg.OmciMsg.MessageType})
1421
1422 switch msg.OmciMsg.MessageType {
1423 case omci.CreateResponseType:
1424 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301426
mpagenko3dbcdd22020-07-22 07:38:45 +00001427 } //CreateResponseType
1428 case omci.SetResponseType:
1429 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001431
mpagenko3dbcdd22020-07-22 07:38:45 +00001432 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001433 case omci.DeleteResponseType:
1434 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001435 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001436
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001437 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001438 default:
1439 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001440 logger.Errorw(ctx, "UniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001441 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001442 return
1443 }
1444 }
1445}
1446
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447func (oFsm *UniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001448 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1449 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001450 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001451 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1452 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001453 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001454 meParams := me.ParamData{
1455 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1456 Attributes: me.AttributeValueMap{
1457 "PortId": gemPortAttribs.gemPortID,
1458 "TContPointer": oFsm.tcont0ID,
1459 "Direction": gemPortAttribs.direction,
1460 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1461 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1462 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1463 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1464 },
1465 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001466 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001467 meInstance, err := oFsm.pOmciCC.SendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1468 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001469 if err != nil {
1470 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001471 logger.Errorw(ctx, "GemNCTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001472 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001473 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001474 return
1475 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001476 //accept also nil as (error) return value for writing to LastTx
1477 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001478 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001479 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001480 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001481 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001482 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001484 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001485 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001486 return
1487 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001488 // Mark the gem port to be added for Performance History monitoring
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001489 OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
1490 if OnuMetricsManager != nil {
1491 OnuMetricsManager.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001492 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001493 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001494
1495 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001496 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001497 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001498}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001499func (oFsm *UniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001500 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1501 if gemPortAttribs.isMulticast {
1502 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1503 return true
1504 }
1505 }
1506 return false
1507}
mpagenko3dbcdd22020-07-22 07:38:45 +00001508
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001509func (oFsm *UniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001510 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1511 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001512 logger.Debugw(ctx, "UniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001513 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1514 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001515 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001516
ozgecanetsia4b232302020-11-11 10:58:10 +03001517 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1518 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001519
1520 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001521 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001522 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001523 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001524 "InterworkingOption": 0, // Don't Care
1525 "ServiceProfilePointer": 0, // Don't Care
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001526 "GalProfilePointer": cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001527 },
1528 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001529 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1530 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1531 continue
1532 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001533 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001534 meInstance, err := oFsm.pOmciCC.SendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1535 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001536 if err != nil {
1537 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001538 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001539 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001540 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001541 return
1542
1543 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001544 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001545 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001546 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001547 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001548 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001549 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001550 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001551 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001552 return
1553 }
1554 ipv4MulticastTable := make([]uint8, 12)
1555 //Gem Port ID
1556 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1557 //Secondary Key
1558 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1559 // Multicast IP range start This is the 224.0.0.1 address
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001560 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], cmn.IPToInt32(net.IPv4(224, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001561 // MulticastIp range stop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001562 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001563
1564 meIPV4MCTableParams := me.ParamData{
1565 EntityID: gemPortAttribs.multicastGemID,
1566 Attributes: me.AttributeValueMap{
1567 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1568 },
1569 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001570 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001571 meIPV4MCTableInstance, err := oFsm.pOmciCC.SendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
1572 true, oFsm.PAdaptFsm.CommChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001573 if err != nil {
1574 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001576 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001577 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001578 return
1579 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001580 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001581 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001582
1583 } else {
1584 meParams := me.ParamData{
1585 EntityID: gemPortAttribs.gemPortID,
1586 Attributes: me.AttributeValueMap{
1587 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1588 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1589 "ServiceProfilePointer": oFsm.mapperSP0ID,
1590 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001591 "GalProfilePointer": cmn.GalEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001592 },
1593 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001594 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001595 meInstance, err := oFsm.pOmciCC.SendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1596 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001597 if err != nil {
1598 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001599 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001600 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001602 return
1603 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001604 //accept also nil as (error) return value for writing to LastTx
1605 // - this avoids misinterpretation of new received OMCI messages
1606 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001607 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001608 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001609 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001611 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001613 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001614 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001615 return
1616 }
1617 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001618
1619 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001622}
1623
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624func (oFsm *UniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001625 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1626 if oFsm.tcontSetBefore {
1627 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1628 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001629 "uni-id": oFsm.pOnuUniPort.UniID,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001630 "techProfile-id": oFsm.techProfileID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001631 go func(aPAFsm *cmn.AdapterFsm) {
1632 if aPAFsm != nil && aPAFsm.PFsm != nil {
1633 _ = aPAFsm.PFsm.Event(aniEvRxPrioqsResp)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001634 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001635 }(oFsm.PAdaptFsm)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001636 return
1637 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001638 const cu16StrictPrioWeight uint16 = 0xFFFF
1639 //find all upstream PrioQueues related to this T-Cont
1640 loQueueMap := ordered_map.NewOrderedMap()
1641 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001642 if gemPortAttribs.isMulticast {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001643 logger.Debugw(ctx, "UniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001644 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1645 "prioString": gemPortAttribs.pbitString})
1646 continue
1647 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001648 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301649 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001650 //key does not yet exist
1651 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1652 }
1653 } else {
1654 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1655 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001656 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001657
Girish Gowdra09e5f212021-09-30 16:28:36 -07001658 trafficSchedPtrSetSupported := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001659 loOnu2g := oFsm.pOnuDB.GetMe(me.Onu2GClassID, cmn.Onu2gMeID)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001660 if loOnu2g == nil {
1661 logger.Errorw(ctx, "onu2g is nil, cannot read qos configuration flexibility parameter",
1662 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001663 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001664 return
1665 }
1666 returnVal := loOnu2g["QualityOfServiceQosConfigurationFlexibility"]
1667 if returnVal != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001668 if qosCfgFlexParam, err := oFsm.pOnuDB.GetUint16Attrib(returnVal); err == nil {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001669 trafficSchedPtrSetSupported = qosCfgFlexParam&bitTrafficSchedulerPtrSetPermitted == bitTrafficSchedulerPtrSetPermitted
1670 logger.Debugw(ctx, "trafficSchedPtrSetSupported set",
1671 log.Fields{"qosCfgFlexParam": qosCfgFlexParam, "trafficSchedPtrSetSupported": trafficSchedPtrSetSupported})
1672 } else {
1673 logger.Errorw(ctx, "Cannot extract qos configuration flexibility parameter",
1674 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001676 return
1677 }
1678 } else {
1679 logger.Errorw(ctx, "Cannot read qos configuration flexibility parameter",
1680 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001681 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Girish Gowdra09e5f212021-09-30 16:28:36 -07001682 return
1683 }
1684
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001685 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1686 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1687 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1688 // or even be finished without correct SP/WRR setting
1689
1690 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1691 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1692 // even though its T-Cont seems to be wrong ...
1693 loTrafficSchedulerEID := 0x8000
1694 //for all found queues
1695 iter := loQueueMap.IterFunc()
1696 for kv, ok := iter(); ok; kv, ok = iter() {
1697 queueIndex := (kv.Key).(uint16)
1698 meParams := me.ParamData{
1699 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301700 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001701 }
Girish Gowdra09e5f212021-09-30 16:28:36 -07001702 if trafficSchedPtrSetSupported {
1703 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1704 //StrictPrio indication
1705 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
1706 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1707 "device-id": oFsm.deviceID})
1708 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1709 } else {
1710 //WRR indication
1711 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
1712 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1713 "Weight": kv.Value,
1714 "device-id": oFsm.deviceID})
1715 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1716 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1717 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001718 } else {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001719 // setting Traffic Scheduler (TS) pointer is not supported unless we point to another TS that points to the same TCONT.
1720 // 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.
1721 // 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.
1722 if (kv.Value).(uint16) == cu16StrictPrioWeight { // SP case, nothing to be done. Proceed to the next queue
1723 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio, traffic sched ptr set unsupported", log.Fields{
1724 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1725 "device-id": oFsm.deviceID})
1726 continue
1727 }
1728 // WRR case, update weight.
1729 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR, traffic sched ptr set unsupported", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001730 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1731 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001732 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001733 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1734 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001735 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001736 meInstance, err := oFsm.pOmciCC.SendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1737 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001738 if err != nil {
1739 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001740 logger.Errorw(ctx, "PrioQueueVar set failed, aborting UniPonAniConfigFsm!",
ozgecanetsiab36ed572021-04-01 10:38:48 +03001741 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001742 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001743 return
1744 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001745 //accept also nil as (error) return value for writing to LastTx
1746 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001747 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001748 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001749
1750 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001751 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001752 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001754 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001755 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001756 return
1757 }
1758
1759 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1760 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1761 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1762 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1763
1764 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001765
1766 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001768 _ = oFsm.PAdaptFsm.PFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001769}
1770
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001771func (oFsm *UniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001772 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001773 if oFsm.isCanceled {
1774 // FSM already canceled before entering wait
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001775 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 +00001776 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001777 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00001778 }
mpagenko7d6bb022021-03-11 15:07:55 +00001779 oFsm.isAwaitingResponse = true
1780 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001781 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301782 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001783 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001784 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001785 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 +00001786 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001787 oFsm.mutexIsAwaitingResponse.Lock()
1788 oFsm.isAwaitingResponse = false
1789 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001790 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001791 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301792 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001793 logger.Debugw(ctx, "UniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001794 oFsm.mutexIsAwaitingResponse.Lock()
1795 oFsm.isAwaitingResponse = false
1796 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001797 return nil
1798 }
mpagenko7d6bb022021-03-11 15:07:55 +00001799 // waiting was aborted (probably on external request)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001800 logger.Debugw(ctx, "UniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001801 oFsm.mutexIsAwaitingResponse.Lock()
1802 oFsm.isAwaitingResponse = false
1803 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001804 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001805 }
1806}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001807
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001808func (oFsm *UniPonAniConfigFsm) setChanSet(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001809 oFsm.mutexChanSet.Lock()
1810 oFsm.chanSet = flagValue
1811 oFsm.mutexChanSet.Unlock()
1812}
1813
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001814func (oFsm *UniPonAniConfigFsm) isChanSet() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001815 oFsm.mutexChanSet.RLock()
1816 flagValue := oFsm.chanSet
1817 oFsm.mutexChanSet.RUnlock()
1818 return flagValue
1819}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00001820
1821// PrepareForGarbageCollection - remove references to prepare for garbage collection
1822func (oFsm *UniPonAniConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
1823 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": oFsm.deviceID})
1824 oFsm.pDeviceHandler = nil
1825 oFsm.pOnuDeviceEntry = nil
1826 oFsm.pOmciCC = nil
1827}