blob: 3985f00129eadeda82a278a8371cfedf4a099015 [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
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
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"
mpagenko3dbcdd22020-07-22 07:38:45 +000031 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070033 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000034 //ic "github.com/opencord/voltha-protos/v4/go/inter_container"
35 //"github.com/opencord/voltha-protos/v4/go/openflow_13"
36 //"github.com/opencord/voltha-protos/v4/go/voltha"
mpagenko3dbcdd22020-07-22 07:38:45 +000037)
38
mpagenko1cc3cb42020-07-27 15:24:38 +000039const (
40 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000041 aniEvStart = "aniEvStart"
42 aniEvStartConfig = "aniEvStartConfig"
43 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
44 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
45 aniEvRxTcontsResp = "aniEvRxTcontsResp"
46 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
47 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
48 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
49 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
50 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080051 aniEvWaitFlowRem = "aniEvWaitFlowRem"
52 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000053 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
54 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030055 aniEvRxRemTdResp = "aniEvRxRemTdResp"
mpagenko8b07c1b2020-11-26 10:36:31 +000056 aniEvRemTcontPath = "aniEvRemTcontPath"
57 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
58 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
59 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
60 aniEvTimeoutSimple = "aniEvTimeoutSimple"
61 aniEvTimeoutMids = "aniEvTimeoutMids"
62 aniEvReset = "aniEvReset"
63 aniEvRestart = "aniEvRestart"
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +000064 aniEvSkipOmciConfig = "aniEvSkipOmciConfig"
mpagenko1cc3cb42020-07-27 15:24:38 +000065)
66const (
67 // states of config PON ANI port FSM
68 aniStDisabled = "aniStDisabled"
69 aniStStarting = "aniStStarting"
70 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
71 aniStCreatingMBPCD = "aniStCreatingMBPCD"
72 aniStSettingTconts = "aniStSettingTconts"
73 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
74 aniStCreatingGemIWs = "aniStCreatingGemIWs"
75 aniStSettingPQs = "aniStSettingPQs"
76 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
77 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000078 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080079 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000080 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030081 aniStRemovingTD = "aniStRemovingTD"
mpagenko8b07c1b2020-11-26 10:36:31 +000082 aniStResetTcont = "aniStResetTcont"
83 aniStRemDot1PMapper = "aniStRemDot1PMapper"
84 aniStRemAniBPCD = "aniStRemAniBPCD"
85 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000086 aniStResetting = "aniStResetting"
87)
Holger Hildebrandt10d98192021-01-27 15:29:31 +000088const cAniFsmIdleState = aniStConfigDone
mpagenko1cc3cb42020-07-27 15:24:38 +000089
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000090type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030091 gemPortID uint16
92 upQueueID uint16
93 downQueueID uint16
94 direction uint8
95 qosPolicy string
96 weight uint8
97 pbitString string
98 isMulticast bool
99 multicastGemID uint16
100 staticACL string
101 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000102}
103
Himani Chawla6d2ae152020-09-02 13:11:20 +0530104//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
105type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000106 pDeviceHandler *deviceHandler
107 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530108 pOmciCC *omciCC
109 pOnuUniPort *onuUniPort
110 pUniTechProf *onuUniTechProf
111 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800112 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000113 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000114 requestEvent OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000115 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000116 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000117 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530118 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000119 pAdaptFsm *AdapterFsm
120 chSuccess chan<- uint8
121 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000122 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000123 chanSet bool
124 mapperSP0ID uint16
125 macBPCD0ID uint16
126 tcont0ID uint16
127 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000128 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000129 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000130 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000131 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000132 isWaitingForFlowDelete bool
133 waitFlowDeleteChannel chan bool
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700134 tcontSetBefore bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000135}
136
Himani Chawla6d2ae152020-09-02 13:11:20 +0530137//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000138func newUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800139 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000140 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530141 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000142 pDeviceHandler: apDeviceHandler,
143 deviceID: apDeviceHandler.deviceID,
144 pOmciCC: apDevOmciCC,
145 pOnuUniPort: apUniPort,
146 pUniTechProf: apUniTechProf,
147 pOnuDB: apOnuDB,
148 techProfileID: aTechProfileID,
149 requestEvent: aRequestEvent,
150 chanSet: false,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700151 tcontSetBefore: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000152 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000153 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
mpagenkobb47bc22021-04-20 13:29:09 +0000154 instFsm.waitFlowDeleteChannel = make(chan bool)
mpagenko8b07c1b2020-11-26 10:36:31 +0000155
mpagenko01e726e2020-10-23 09:45:29 +0000156 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000157 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000158 logger.Errorw(ctx, "uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000159 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000160 return nil
161 }
162
163 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000164 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000165 fsm.Events{
166
mpagenko1cc3cb42020-07-27 15:24:38 +0000167 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000168
169 //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 +0000170 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000171 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000172 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
173 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000174 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000175 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000176 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000177 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000178 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000179 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000180 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000181
mpagenko8b07c1b2020-11-26 10:36:31 +0000182 //for removing Gem related resources
183 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800184 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
185 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000186 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300187 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
188 {Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStConfigDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000189
190 //for removing TCONT related resources
191 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
192 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStRemDot1PMapper},
193 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
194 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
195
196 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300197 aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000198 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000199 {Name: aniEvTimeoutMids, Src: []string{
200 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000201
mpagenko1cc3cb42020-07-27 15:24:38 +0000202 // exceptional treatment for all states except aniStResetting
203 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
204 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300205 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000206 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000207 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000208 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000209 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000210 },
211
212 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000213 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
214 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
215 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
216 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
217 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
218 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
219 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
220 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
221 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
222 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
223 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000224 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000225 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300226 ("enter_" + aniStRemovingTD): func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
228 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
229 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
230 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
231 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
232 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000233 },
234 )
235 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000236 logger.Errorw(ctx, "uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000237 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000238 return nil
239 }
240
dbainbri4d3a0dc2020-12-02 00:33:42 +0000241 logger.Debugw(ctx, "uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000242 return instFsm
243}
244
Himani Chawla6d2ae152020-09-02 13:11:20 +0530245//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
246func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000247 oFsm.chSuccess = aChSuccess
248 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000249 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000250}
251
mpagenko7d6bb022021-03-11 15:07:55 +0000252//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000253func (oFsm *uniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
254 //early indication about started reset processing
255 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000256 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000257 oFsm.mutexIsAwaitingResponse.Lock()
258 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000259 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000260 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
261 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
262 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000263 //use channel to indicate that the response waiting shall be aborted
264 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000265 } else {
266 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000267 }
mpagenkocf48e452021-04-23 09:23:00 +0000268
269 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000270 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000271 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000272 //use channel to indicate that the response waiting shall be aborted
273 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000274 } else {
275 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000276 }
mpagenkocf48e452021-04-23 09:23:00 +0000277
mpagenko7d6bb022021-03-11 15:07:55 +0000278 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
279 pAdaptFsm := oFsm.pAdaptFsm
280 if pAdaptFsm != nil {
281 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
282 go func(aPAFsm *AdapterFsm) {
283 if aPAFsm.pFsm != nil {
284 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
285 }
286 }(pAdaptFsm)
287 }
mpagenko73143992021-04-09 15:17:10 +0000288
mpagenko18eca9c2021-07-26 11:03:45 +0000289 // possible access conflicts on internal data by next needed data clearance
290 // are avoided by using mutexTPState also from within clearAniSideConfig
291 // do not try to lock TpProcMutex here as done in previous code version
292 // as it may result in deadlock situations (as observed at soft-reboot handling where
293 // TpProcMutex is already locked by some ongoing TechProfile config/removal processing
mpagenko73143992021-04-09 15:17:10 +0000294 //remove all TechProf related internal data to allow for new configuration
295 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000296}
297
Mahir Gunyel6781f962021-05-16 23:30:08 -0700298//nolint: gocyclo
299//TODO:visit here for refactoring for gocyclo
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530301 if aPAFsm != nil && aPAFsm.pFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700302 var err error
303 oFsm.mapperSP0ID, err = generateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
304 if err != nil {
305 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
306 "techProfileID": oFsm.techProfileID, "error": err})
307 return
308 }
309 oFsm.macBPCD0ID, err = generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
310 if err != nil {
311 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
312 "techProfileID": oFsm.techProfileID, "error": err})
313 return
314 }
315 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
316 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
317 "macBpNo": oFsm.pOnuUniPort.macBpNo, "techProfileID": oFsm.techProfileID})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700318 pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false)
319 if pDevEntry == nil {
320 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800321 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530322 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700323 tcontInstID, tcontAlreadyExist, err := pDevEntry.allocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
324 if err != nil {
325 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700326 //reset the state machine to enable usage on subsequent requests
327 _ = aPAFsm.pFsm.Event(aniEvReset)
328 return
329 }
330 oFsm.tcont0ID = tcontInstID
331 oFsm.tcontSetBefore = tcontAlreadyExist
332 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
333 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
334 "tcontAlreadyExist": tcontAlreadyExist,
335 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800336
337 // Access critical state with lock
mpagenko7a592192021-07-28 13:32:00 +0000338 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000339 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
340 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko7a592192021-07-28 13:32:00 +0000341 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800342
Himani Chawla26e555c2020-08-31 12:30:20 +0530343 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800344 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300345 loGemPortAttribs := ponAniGemPortAttribs{}
346
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
348
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530350
351 loGemPortAttribs.gemPortID = gemEntry.gemPortID
352 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
353 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
354 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
355 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
356
357 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
358 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
359 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
360 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
361 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
362 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
363
364 usQueueFound := false
365 dsQueueFound := false
366 for _, mgmtEntityID := range queueInstKeys {
367 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
368 returnVal := meAttributes["RelatedPort"]
369 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530370 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530371 if relatedPort == usQrelPortMask {
372 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000373 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000374 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 usQueueFound = true
376 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
377 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000379 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 dsQueueFound = true
381 }
382 if usQueueFound && dsQueueFound {
383 break
384 }
385 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 }
388 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 }
391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000392 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000393 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 }
395 }
396 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000397 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 }
399 loGemPortAttribs.direction = gemEntry.direction
400 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
401 loGemPortAttribs.weight = gemEntry.queueWeight
402 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300403
ozgecanetsia4b232302020-11-11 10:58:10 +0300404 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300405 //TODO this might effectively ignore the for loop starting at line 316
406 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300407 loGemPortAttribs.isMulticast = true
408 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
409 loGemPortAttribs.staticACL = gemEntry.staticACL
410 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530411
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300413 "gemPortID": loGemPortAttribs.gemPortID,
414 "isMulticast": loGemPortAttribs.isMulticast,
415 "multicastGemID": loGemPortAttribs.multicastGemID,
416 "staticACL": loGemPortAttribs.staticACL,
417 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000418 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300419 })
420
421 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000422 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300423 "gemPortID": loGemPortAttribs.gemPortID,
424 "upQueueID": loGemPortAttribs.upQueueID,
425 "downQueueID": loGemPortAttribs.downQueueID,
426 "pbitString": loGemPortAttribs.pbitString,
427 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000428 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300429 })
430 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530431
432 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
433 }
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000434 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
435 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
436 } else {
437 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
438 _ = aPAFsm.pFsm.Event(aniEvSkipOmciConfig)
439 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 }
441}
442
dbainbri4d3a0dc2020-12-02 00:33:42 +0000443func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
444 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000445 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000446 // in case the used channel is not yet defined (can be re-used after restarts)
447 if oFsm.omciMIdsResponseReceived == nil {
448 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000449 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000450 } else {
451 // as we may 're-use' this instance of FSM and the connected channel
452 // make sure there is no 'lingering' request in the already existing channel:
453 // (simple loop sufficient as we are the only receiver)
454 for len(oFsm.omciMIdsResponseReceived) > 0 {
455 <-oFsm.omciMIdsResponseReceived
456 }
457 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000458 //ensure internal slices are empty (which might be set from previous run) - release memory
459 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000460 oFsm.mutexIsAwaitingResponse.Lock()
461 //reset the canceled state possibly existing from previous reset
462 oFsm.isCanceled = false
463 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000464
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000465 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000466 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000467
468 //let the state machine run forward from here directly
469 pConfigAniStateAFsm := oFsm.pAdaptFsm
470 if pConfigAniStateAFsm != nil {
471 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000473
mpagenko3dbcdd22020-07-22 07:38:45 +0000474 }
475}
476
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
478 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000479 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000480 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
481 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000482 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300483 meInstance, err := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000484 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300485 if err != nil {
486 logger.Errorw(ctx, "Dot1PMapper create failed, aborting uniPonAniConfigFsm!",
487 log.Fields{"device-id": oFsm.deviceID})
488 pConfigAniStateAFsm := oFsm.pAdaptFsm
489 if pConfigAniStateAFsm != nil {
490 oFsm.mutexPLastTxMeInstance.Unlock()
491 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
492 go func(aPAFsm *AdapterFsm) {
493 if aPAFsm != nil && aPAFsm.pFsm != nil {
494 _ = aPAFsm.pFsm.Event(aniEvReset)
495 }
496 }(pConfigAniStateAFsm)
497 return
498 }
499 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000500 //accept also nil as (error) return value for writing to LastTx
501 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000502 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300503 oFsm.mutexPLastTxMeInstance.Unlock()
504
mpagenko3dbcdd22020-07-22 07:38:45 +0000505}
506
dbainbri4d3a0dc2020-12-02 00:33:42 +0000507func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
508 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000509 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
510 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000511 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000512 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
513 meParams := me.ParamData{
514 EntityID: oFsm.macBPCD0ID,
515 Attributes: me.AttributeValueMap{
516 "BridgeIdPointer": bridgePtr,
517 "PortNum": 0xFF, //fixed unique ANI side indication
518 "TpType": 3, //for .1PMapper
519 "TpPointer": oFsm.mapperSP0ID,
520 },
521 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000522 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300523 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000524 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300525 if err != nil {
526 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting uniPonAniConfigFsm!",
527 log.Fields{"device-id": oFsm.deviceID})
528 pConfigAniStateAFsm := oFsm.pAdaptFsm
529 if pConfigAniStateAFsm != nil {
530 oFsm.mutexPLastTxMeInstance.Unlock()
531 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
532 go func(aPAFsm *AdapterFsm) {
533 if aPAFsm != nil && aPAFsm.pFsm != nil {
534 _ = aPAFsm.pFsm.Event(aniEvReset)
535 }
536 }(pConfigAniStateAFsm)
537 return
538 }
539 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000540 //accept also nil as (error) return value for writing to LastTx
541 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000542 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300543 oFsm.mutexPLastTxMeInstance.Unlock()
544
mpagenko3dbcdd22020-07-22 07:38:45 +0000545}
546
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
548 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000549 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
550 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700551 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
552 "tcontExist": oFsm.tcontSetBefore})
553 //If tcont was set before, then no need to set it again. Let state machine to proceed.
554 if oFsm.tcontSetBefore {
555 go func(aPAFsm *AdapterFsm) {
556 if aPAFsm != nil && aPAFsm.pFsm != nil {
557 _ = aPAFsm.pFsm.Event(aniEvRxTcontsResp)
558 }
559 }(oFsm.pAdaptFsm)
560 return
561 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000562 meParams := me.ParamData{
563 EntityID: oFsm.tcont0ID,
564 Attributes: me.AttributeValueMap{
565 "AllocId": oFsm.alloc0ID,
566 },
567 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000568 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300569 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000570 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300571 if err != nil {
572 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
573 log.Fields{"device-id": oFsm.deviceID})
574 pConfigAniStateAFsm := oFsm.pAdaptFsm
575 if pConfigAniStateAFsm != nil {
576 oFsm.mutexPLastTxMeInstance.Unlock()
577 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
578 go func(aPAFsm *AdapterFsm) {
579 if aPAFsm != nil && aPAFsm.pFsm != nil {
580 _ = aPAFsm.pFsm.Event(aniEvReset)
581 }
582 }(pConfigAniStateAFsm)
583 return
584 }
585 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000586 //accept also nil as (error) return value for writing to LastTx
587 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000588 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300589 oFsm.mutexPLastTxMeInstance.Unlock()
590
mpagenko3dbcdd22020-07-22 07:38:45 +0000591}
592
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
594 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000595 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000596 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000597}
598
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
600 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000601 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000602 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000603}
604
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
606 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000607 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000609}
610
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300612
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000614 "toGemIw": 1024, /* cmp above */
615 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000616
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000618 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000619 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000620
mpagenko3dbcdd22020-07-22 07:38:45 +0000621 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000622 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530623 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000624 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000625
626 //assign the GemPorts according to the configured Prio
627 var loPrioGemPortArray [8]uint16
628 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300629 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300631 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
632 "prioString": gemPortAttribs.pbitString})
633 continue
634 }
635 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300637 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
638 "prioString": gemPortAttribs.pbitString})
639 continue
640 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000641 for i := 0; i < 8; i++ {
642 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
643 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
644 if prio == 1 { // Check this p-bit is set
645 if loPrioGemPortArray[i] == 0 {
646 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
647 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000649 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000650 "SetGemPort": loPrioGemPortArray[i]})
651 }
652 }
653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000655 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000656 "prioString": gemPortAttribs.pbitString, "position": i})
657 }
658
659 }
660 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300661
ozgecanetsia4b232302020-11-11 10:58:10 +0300662 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530663 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300664 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530665 if value != 0 {
666 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530667 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000669 "for Prio": index,
670 "IwPtr": strconv.FormatInt(int64(value), 16),
671 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300672 } else {
673 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000674 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
675 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300676 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530677 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000678 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300679 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000680 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
681 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300682 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530683
684 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000686 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300687 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
688 // 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 +0000689 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300690 //pConfigAniStateAFsm := oFsm.pAdaptFsm
691 //if pConfigAniStateAFsm != nil {
692 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
693 // go func(aPAFsm *AdapterFsm) {
694 // if aPAFsm != nil && aPAFsm.pFsm != nil {
695 // _ = aPAFsm.pFsm.Event(aniEvReset)
696 // }
697 // }(pConfigAniStateAFsm)
698 //}
699 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000700 pConfigAniStateAFsm := oFsm.pAdaptFsm
701 if pConfigAniStateAFsm != nil {
702 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530703 go func(aPAFsm *AdapterFsm) {
704 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300705 _ = aPAFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000706 }
707 }(pConfigAniStateAFsm)
708 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300709 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000710 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300711 meInstance, err := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300712 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300713 if err != nil {
714 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting uniPonAniConfigFsm!",
715 log.Fields{"device-id": oFsm.deviceID})
716 pConfigAniStateAFsm := oFsm.pAdaptFsm
717 if pConfigAniStateAFsm != nil {
718 oFsm.mutexPLastTxMeInstance.Unlock()
719 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
720 go func(aPAFsm *AdapterFsm) {
721 if aPAFsm != nil && aPAFsm.pFsm != nil {
722 _ = aPAFsm.pFsm.Event(aniEvReset)
723 }
724 }(pConfigAniStateAFsm)
725 return
726 }
727 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300728 //accept also nil as (error) return value for writing to LastTx
729 // - this avoids misinterpretation of new received OMCI messages
730 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300731 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000732 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000733}
734
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
736 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000737 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000738 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800739 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000740 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
741 //use DeviceHandler event notification directly
742 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
743 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
744 // but only in case the techProfile was configured (not deleted)
745 if oFsm.requestEventOffset == 0 {
746 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
747 }
748 } else {
749 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000750 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000751 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000752 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000754 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
755 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000756 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000757 }
mpagenko01e726e2020-10-23 09:45:29 +0000758
759 //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 +0000760}
761
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko7a592192021-07-28 13:32:00 +0000763 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
764 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000765 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
766 select {
767 case <-oFsm.waitFlowDeleteChannel:
768 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
769 default:
770 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000771
772 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID] != nil {
mpagenko7a592192021-07-28 13:32:00 +0000773 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000774 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000775 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
776 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
777 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
778 pConfigAniStateAFsm := oFsm.pAdaptFsm
779 if pConfigAniStateAFsm != nil {
780 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
781 go func(aPAFsm *AdapterFsm) {
782 if aPAFsm != nil && aPAFsm.pFsm != nil {
783 _ = aPAFsm.pFsm.Event(aniEvWaitFlowRem)
784 }
785 }(pConfigAniStateAFsm)
786 } else {
787 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
788 }
789 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800790 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000791 } else {
792 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
793 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800794 }
795
mpagenko7a592192021-07-28 13:32:00 +0000796 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000797 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000798 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko7a592192021-07-28 13:32:00 +0000799 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000801 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
802 "GemIwTp-entity-id": loGemPortID})
803 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
804
805 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000806 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300807 meInstance, err := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000808 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300809 if err != nil {
810 logger.Errorw(ctx, "GemIWTP delete failed, aborting uniPonAniConfigFsm!",
811 log.Fields{"device-id": oFsm.deviceID})
812 pConfigAniStateAFsm := oFsm.pAdaptFsm
813 if pConfigAniStateAFsm != nil {
814 oFsm.mutexPLastTxMeInstance.Unlock()
815 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
816 go func(aPAFsm *AdapterFsm) {
817 if aPAFsm != nil && aPAFsm.pFsm != nil {
818 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
819 }
820 }(pConfigAniStateAFsm)
821 return
822 }
823 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000824 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300825 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000826}
827
mpagenkobb47bc22021-04-20 13:29:09 +0000828func (oFsm *uniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
829 oFsm.mutexIsAwaitingResponse.Lock()
830 oFsm.isWaitingForFlowDelete = true
831 oFsm.mutexIsAwaitingResponse.Unlock()
832 select {
833 // maybe be also some outside cancel (but no context modeled for the moment ...)
834 // case <-ctx.Done():
835 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000836 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)
mpagenkobb47bc22021-04-20 13:29:09 +0000837 logger.Warnw(ctx, "uniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
838 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
839 oFsm.mutexIsAwaitingResponse.Lock()
840 oFsm.isWaitingForFlowDelete = false
841 oFsm.mutexIsAwaitingResponse.Unlock()
842 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
843 pConfigAniStateAFsm := oFsm.pAdaptFsm
844 if pConfigAniStateAFsm != nil {
845 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
846 go func(aPAFsm *AdapterFsm) {
847 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300848 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000849 }
850 }(pConfigAniStateAFsm)
851 } else {
852 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
853 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
854 }
855 return
856
857 case success := <-oFsm.waitFlowDeleteChannel:
858 if success {
859 logger.Debugw(ctx, "uniPonAniConfigFsm flow removed info received", log.Fields{
860 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
861 oFsm.mutexIsAwaitingResponse.Lock()
862 oFsm.isWaitingForFlowDelete = false
863 oFsm.mutexIsAwaitingResponse.Unlock()
864 pConfigAniStateAFsm := oFsm.pAdaptFsm
865 if pConfigAniStateAFsm != nil {
866 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
867 go func(aPAFsm *AdapterFsm) {
868 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300869 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000870 }
871 }(pConfigAniStateAFsm)
872 } else {
873 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
874 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
875 }
876 return
877 }
878 // waiting was aborted (probably on external request)
879 logger.Debugw(ctx, "uniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
880 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
881 oFsm.mutexIsAwaitingResponse.Lock()
882 oFsm.isWaitingForFlowDelete = false
883 oFsm.mutexIsAwaitingResponse.Unlock()
884 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
885 pConfigAniStateAFsm := oFsm.pAdaptFsm
886 if pConfigAniStateAFsm != nil {
887 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
888 go func(aPAFsm *AdapterFsm) {
889 if aPAFsm != nil && aPAFsm.pFsm != nil {
890 _ = aPAFsm.pFsm.Event(aniEvReset)
891 }
892 }(pConfigAniStateAFsm)
893 }
894 return
895 }
896}
897
dbainbri4d3a0dc2020-12-02 00:33:42 +0000898func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko7a592192021-07-28 13:32:00 +0000899 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000900 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko7a592192021-07-28 13:32:00 +0000901 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000902 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000903 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
904 "GemNCTP-entity-id": loGemPortID})
905 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000906 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300907 meInstance, err := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000908 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300909 if err != nil {
910 logger.Errorw(ctx, "GemNCTP delete failed, aborting uniPonAniConfigFsm!",
911 log.Fields{"device-id": oFsm.deviceID})
912 pConfigAniStateAFsm := oFsm.pAdaptFsm
913 if pConfigAniStateAFsm != nil {
914 oFsm.mutexPLastTxMeInstance.Unlock()
915 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
916 go func(aPAFsm *AdapterFsm) {
917 if aPAFsm != nil && aPAFsm.pFsm != nil {
918 _ = aPAFsm.pFsm.Event(aniEvReset)
919 }
920 }(pConfigAniStateAFsm)
921 return
922 }
923 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000924 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000925 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300926
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800927 // Mark the gem port to be removed for Performance History monitoring
928 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -0700929 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800930 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000931}
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300932func (oFsm *uniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko7a592192021-07-28 13:32:00 +0000933 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300934 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko7a592192021-07-28 13:32:00 +0000935 oFsm.pUniTechProf.mutexTPState.RUnlock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300936 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
937 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
938 "TD-entity-id": loGemPortID})
939
940 oFsm.mutexPLastTxMeInstance.Lock()
941 meInstance, err := oFsm.pOmciCC.sendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
942 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, loGemPortID)
943
944 if err != nil {
945 logger.Errorw(ctx, "TD delete failed - proceed fsm",
946 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
947 pConfigAniStateAFsm := oFsm.pAdaptFsm
948 if pConfigAniStateAFsm != nil {
949 oFsm.mutexPLastTxMeInstance.Unlock()
950 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
951 go func(aPAFsm *AdapterFsm) {
952 if aPAFsm != nil && aPAFsm.pFsm != nil {
953 _ = aPAFsm.pFsm.Event(aniEvReset)
954 }
955 }(pConfigAniStateAFsm)
956 return
957 }
958 }
959 oFsm.pLastTxMeInstance = meInstance
960 oFsm.mutexPLastTxMeInstance.Unlock()
961}
mpagenko8b07c1b2020-11-26 10:36:31 +0000962
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
964 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000965 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
966
967 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
968 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
969 meParams := me.ParamData{
970 EntityID: oFsm.tcont0ID,
971 Attributes: me.AttributeValueMap{
972 "AllocId": unusedTcontAllocID,
973 },
974 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000975 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300976 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000977 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300978 if err != nil {
979 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
980 log.Fields{"device-id": oFsm.deviceID})
981 pConfigAniStateAFsm := oFsm.pAdaptFsm
982 if pConfigAniStateAFsm != nil {
983 oFsm.mutexPLastTxMeInstance.Unlock()
984 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
985 go func(aPAFsm *AdapterFsm) {
986 if aPAFsm != nil && aPAFsm.pFsm != nil {
987 _ = aPAFsm.pFsm.Event(aniEvReset)
988 }
989 }(pConfigAniStateAFsm)
990 return
991 }
992 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000993 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300994 oFsm.mutexPLastTxMeInstance.Unlock()
995
mpagenko8b07c1b2020-11-26 10:36:31 +0000996}
997
dbainbri4d3a0dc2020-12-02 00:33:42 +0000998func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
999 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001000 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1001
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001002 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001003 meInstance, err := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001004 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001005 if err != nil {
1006 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting uniPonAniConfigFsm!",
1007 log.Fields{"device-id": oFsm.deviceID})
1008 pConfigAniStateAFsm := oFsm.pAdaptFsm
1009 if pConfigAniStateAFsm != nil {
1010 oFsm.mutexPLastTxMeInstance.Unlock()
1011 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1012 go func(aPAFsm *AdapterFsm) {
1013 if aPAFsm != nil && aPAFsm.pFsm != nil {
1014 _ = aPAFsm.pFsm.Event(aniEvReset)
1015 }
1016 }(pConfigAniStateAFsm)
1017 return
1018 }
1019 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001020 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001021 oFsm.mutexPLastTxMeInstance.Unlock()
1022
mpagenko8b07c1b2020-11-26 10:36:31 +00001023}
1024
dbainbri4d3a0dc2020-12-02 00:33:42 +00001025func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1026 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001027 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1028
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001029 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001030 meInstance, err := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001031 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001032 if err != nil {
1033 logger.Errorw(ctx, "MBPConfigData delete failed, aborting uniPonAniConfigFsm!",
1034 log.Fields{"device-id": oFsm.deviceID})
1035 pConfigAniStateAFsm := oFsm.pAdaptFsm
1036 if pConfigAniStateAFsm != nil {
1037 oFsm.mutexPLastTxMeInstance.Unlock()
1038 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1039 go func(aPAFsm *AdapterFsm) {
1040 if aPAFsm != nil && aPAFsm.pFsm != nil {
1041 _ = aPAFsm.pFsm.Event(aniEvReset)
1042 }
1043 }(pConfigAniStateAFsm)
1044 return
1045 }
1046 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001047 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001048 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001049}
1050
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1052 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001053 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1054 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001056 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001057 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001059 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1060 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001061 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001062 }
1063
1064 //let's reset the state machine in order to release all resources now
1065 pConfigAniStateAFsm := oFsm.pAdaptFsm
1066 if pConfigAniStateAFsm != nil {
1067 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1068 go func(aPAFsm *AdapterFsm) {
1069 if aPAFsm != nil && aPAFsm.pFsm != nil {
1070 _ = aPAFsm.pFsm.Event(aniEvReset)
1071 }
1072 }(pConfigAniStateAFsm)
1073 }
1074}
1075
dbainbri4d3a0dc2020-12-02 00:33:42 +00001076func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1077 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001078 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001079
mpagenko18eca9c2021-07-26 11:03:45 +00001080 if oFsm.isChanSet() {
1081 // indicate processing error to the caller (in case there was still some open request)
1082 logger.Debugw(ctx, "uniPonAniConfigFsm processingError on channel", log.Fields{
1083 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1084 //use non-blocking channel send to avoid blocking because of non-existing receiver
1085 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1086 select {
1087 case oFsm.chSuccess <- 0:
1088 default:
1089 logger.Debugw(ctx, "uniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
1090 "device-id": oFsm.deviceID})
1091 }
1092 oFsm.setChanSet(false) //reset the internal channel state
1093 }
1094
mpagenko3dbcdd22020-07-22 07:38:45 +00001095 pConfigAniStateAFsm := oFsm.pAdaptFsm
1096 if pConfigAniStateAFsm != nil {
1097 // abort running message processing
1098 fsmAbortMsg := Message{
1099 Type: TestMsg,
1100 Data: TestMessage{
1101 TestMessageVal: AbortMessageProcessing,
1102 },
1103 }
1104 pConfigAniStateAFsm.commChan <- fsmAbortMsg
1105
1106 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +05301107 go func(aPAFsm *AdapterFsm) {
1108 if aPAFsm != nil && aPAFsm.pFsm != nil {
1109 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001110 }
1111 }(pConfigAniStateAFsm)
1112 }
1113}
1114
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1116 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001117 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001118 oFsm.mutexPLastTxMeInstance.Lock()
1119 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001120 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001121}
1122
dbainbri4d3a0dc2020-12-02 00:33:42 +00001123func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1124 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001125loop:
1126 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001127 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001128 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001129 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301130 message, ok := <-oFsm.pAdaptFsm.commChan
1131 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301133 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1134 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1135 break loop
1136 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001137 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301138
1139 switch message.Type {
1140 case TestMsg:
1141 msg, _ := message.Data.(TestMessage)
1142 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001143 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001144 break loop
1145 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301147 case OMCI:
1148 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301150 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301152 "message.Type": message.Type})
1153 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001154
Himani Chawla4d908332020-08-31 12:30:20 +05301155 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301157}
1158
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301160 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1161 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001163 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301164 return
1165 }
1166 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1167 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001168 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001169 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301170 return
1171 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001173 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1174 //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 +00001175 oFsm.mutexPLastTxMeInstance.RLock()
1176 if oFsm.pLastTxMeInstance != nil {
1177 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1178 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1179 // maybe we can use just the same eventName for different state transitions like "forward"
1180 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1181 switch oFsm.pLastTxMeInstance.GetName() {
1182 case "Ieee8021PMapperServiceProfile":
1183 { // let the FSM proceed ...
1184 oFsm.mutexPLastTxMeInstance.RUnlock()
1185 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
1186 }
1187 case "MacBridgePortConfigurationData":
1188 { // let the FSM proceed ...
1189 oFsm.mutexPLastTxMeInstance.RUnlock()
1190 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
1191 }
1192 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1193 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1194 oFsm.mutexPLastTxMeInstance.RUnlock()
1195 oFsm.omciMIdsResponseReceived <- true
1196 }
1197 default:
1198 {
1199 oFsm.mutexPLastTxMeInstance.RUnlock()
1200 logger.Warnw(ctx, "Unsupported ME name received!",
1201 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1202 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001203 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001204 } else {
1205 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001206 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001207 } else {
1208 oFsm.mutexPLastTxMeInstance.RUnlock()
1209 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001210 }
1211 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001212 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1213 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301214 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1215 return
1216 }
Himani Chawla4d908332020-08-31 12:30:20 +05301217}
Mahir Gunyel01034b62021-06-29 11:25:09 -07001218func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
1219 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1220 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1221 oFsm.mutexPLastTxMeInstance.RLock()
1222 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1223 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1224 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1225 switch oFsm.pLastTxMeInstance.GetName() {
1226 case "TCont":
1227 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1228 //We should revert DB
1229 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1230 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1231 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
1232 if pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false); pDevEntry != nil {
1233 pDevEntry.freeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
1234 } else {
1235 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1236 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1237 }
1238 }
1239 default:
1240 logger.Warnw(ctx, "Unsupported ME name received with error!",
1241 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1242 }
1243 }
1244}
dbainbri4d3a0dc2020-12-02 00:33:42 +00001245func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301246 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1247 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001248 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001249 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301250 return
1251 }
1252 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1253 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001255 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301256 return
1257 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001258 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301259 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001261 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301262 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001263
Mahir Gunyel01034b62021-06-29 11:25:09 -07001264 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301265 return
1266 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001267 oFsm.mutexPLastTxMeInstance.RLock()
1268 if oFsm.pLastTxMeInstance != nil {
1269 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1270 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1271 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1272 // if, then something like:
1273 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301274
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001275 switch oFsm.pLastTxMeInstance.GetName() {
1276 case "TCont":
1277 { // let the FSM proceed ...
1278 oFsm.mutexPLastTxMeInstance.RUnlock()
1279 if oFsm.requestEventOffset == 0 { //from TCont config request
1280 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
1281 } else { // from T-Cont reset request
1282 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
1283 }
1284 }
1285 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1286 { // let the PrioQueue init proceed by stopping the wait function
1287 oFsm.mutexPLastTxMeInstance.RUnlock()
1288 oFsm.omciMIdsResponseReceived <- true
1289 }
1290 case "Ieee8021PMapperServiceProfile":
1291 { // let the FSM proceed ...
1292 oFsm.mutexPLastTxMeInstance.RUnlock()
1293 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
1294 }
1295 default:
1296 {
1297 oFsm.mutexPLastTxMeInstance.RUnlock()
1298 logger.Warnw(ctx, "Unsupported ME name received!",
1299 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001300 }
Himani Chawla4d908332020-08-31 12:30:20 +05301301 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001302 } else {
1303 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301304 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001305 } else {
1306 oFsm.mutexPLastTxMeInstance.RUnlock()
1307 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301308 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001309}
1310
dbainbri4d3a0dc2020-12-02 00:33:42 +00001311func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001312 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1313 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001315 log.Fields{"device-id": oFsm.deviceID})
1316 return
1317 }
1318 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1319 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001320 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001321 log.Fields{"device-id": oFsm.deviceID})
1322 return
1323 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001324 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001325 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001326 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001327 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1328 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1329 // store error for mgmt display?
1330 return
1331 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001332 oFsm.mutexPLastTxMeInstance.RLock()
1333 if oFsm.pLastTxMeInstance != nil {
1334 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1335 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1336 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1337 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001338
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001339 switch oFsm.pLastTxMeInstance.GetName() {
1340 case "GemInterworkingTerminationPoint":
1341 { // let the FSM proceed ...
1342 oFsm.mutexPLastTxMeInstance.RUnlock()
1343 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
1344 }
1345 case "GemPortNetworkCtp":
1346 { // let the FSM proceed ...
1347 oFsm.mutexPLastTxMeInstance.RUnlock()
1348 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
1349 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001350 case "TrafficDescriptor":
1351 { // let the FSM proceed ...
1352 oFsm.mutexPLastTxMeInstance.RUnlock()
1353 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemTdResp)
1354 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001355 case "Ieee8021PMapperServiceProfile":
1356 { // let the FSM proceed ...
1357 oFsm.mutexPLastTxMeInstance.RUnlock()
1358 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
1359 }
1360 case "MacBridgePortConfigurationData":
1361 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1362 oFsm.mutexPLastTxMeInstance.RUnlock()
1363 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
1364 }
1365 default:
1366 {
1367 oFsm.mutexPLastTxMeInstance.RUnlock()
1368 logger.Warnw(ctx, "Unsupported ME name received!",
1369 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1370 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001371 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001372 } else {
1373 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001374 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001375 } else {
1376 oFsm.mutexPLastTxMeInstance.RUnlock()
1377 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001378 }
1379}
1380
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
1382 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001383 "msgType": msg.OmciMsg.MessageType})
1384
1385 switch msg.OmciMsg.MessageType {
1386 case omci.CreateResponseType:
1387 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001388 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301389
mpagenko3dbcdd22020-07-22 07:38:45 +00001390 } //CreateResponseType
1391 case omci.SetResponseType:
1392 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001394
mpagenko3dbcdd22020-07-22 07:38:45 +00001395 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001396 case omci.DeleteResponseType:
1397 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001398 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001399
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001400 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001401 default:
1402 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001403 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001404 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001405 return
1406 }
1407 }
1408}
1409
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001411 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1412 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001414 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1415 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001416 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001417 meParams := me.ParamData{
1418 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1419 Attributes: me.AttributeValueMap{
1420 "PortId": gemPortAttribs.gemPortID,
1421 "TContPointer": oFsm.tcont0ID,
1422 "Direction": gemPortAttribs.direction,
1423 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1424 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1425 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1426 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1427 },
1428 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001429 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001430 meInstance, err := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001431 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001432 if err != nil {
1433 oFsm.mutexPLastTxMeInstance.Unlock()
1434 logger.Errorw(ctx, "GemNCTPVar create failed, aborting uniPonAniConfigFsm!",
1435 log.Fields{"device-id": oFsm.deviceID})
1436 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1437 return
1438 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001439 //accept also nil as (error) return value for writing to LastTx
1440 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001441 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001442 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001443 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001444 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001445 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001447 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301448 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001449 return
1450 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001451 // Mark the gem port to be added for Performance History monitoring
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001452 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -07001453 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001454 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001455 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001456
1457 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001458 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301459 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001460}
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001461func (oFsm *uniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
1462 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1463 if gemPortAttribs.isMulticast {
1464 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1465 return true
1466 }
1467 }
1468 return false
1469}
mpagenko3dbcdd22020-07-22 07:38:45 +00001470
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001472 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1473 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001474 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001475 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1476 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001477 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001478
ozgecanetsia4b232302020-11-11 10:58:10 +03001479 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1480 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001481
1482 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001483 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001484 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001485 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001486 "InterworkingOption": 0, // Don't Care
1487 "ServiceProfilePointer": 0, // Don't Care
1488 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001489 },
1490 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001491 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1492 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1493 continue
1494 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001495 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001496 meInstance, err := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsia4b232302020-11-11 10:58:10 +03001497 true, oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001498 if err != nil {
1499 oFsm.mutexPLastTxMeInstance.Unlock()
1500 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting uniPonAniConfigFsm!",
1501 log.Fields{"device-id": oFsm.deviceID})
1502 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1503 return
1504
1505 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001506 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001507 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001508 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001509 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001510 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001511 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001512 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1513 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1514 return
1515 }
1516 ipv4MulticastTable := make([]uint8, 12)
1517 //Gem Port ID
1518 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1519 //Secondary Key
1520 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1521 // Multicast IP range start This is the 224.0.0.1 address
1522 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1523 // MulticastIp range stop
1524 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1525
1526 meIPV4MCTableParams := me.ParamData{
1527 EntityID: gemPortAttribs.multicastGemID,
1528 Attributes: me.AttributeValueMap{
1529 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1530 },
1531 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001532 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001533 meIPV4MCTableInstance, err := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001534 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001535 if err != nil {
1536 oFsm.mutexPLastTxMeInstance.Unlock()
1537 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting uniPonAniConfigFsm!",
1538 log.Fields{"device-id": oFsm.deviceID})
1539 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1540 return
1541 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001542 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001543 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001544
1545 } else {
1546 meParams := me.ParamData{
1547 EntityID: gemPortAttribs.gemPortID,
1548 Attributes: me.AttributeValueMap{
1549 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1550 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1551 "ServiceProfilePointer": oFsm.mapperSP0ID,
1552 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1553 "GalProfilePointer": galEthernetEID,
1554 },
1555 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001556 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001557 meInstance, err := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsia4b232302020-11-11 10:58:10 +03001558 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001559 if err != nil {
1560 oFsm.mutexPLastTxMeInstance.Unlock()
1561 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting uniPonAniConfigFsm!",
1562 log.Fields{"device-id": oFsm.deviceID})
1563 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1564 return
1565 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001566 //accept also nil as (error) return value for writing to LastTx
1567 // - this avoids misinterpretation of new received OMCI messages
1568 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001569 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001570 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001571 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001573 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001574 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001575 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301576 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001577 return
1578 }
1579 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001580
1581 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301583 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001584}
1585
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001587 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1588 if oFsm.tcontSetBefore {
1589 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1590 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
1591 "uni-id": oFsm.pOnuUniPort.uniID,
1592 "techProfile-id": oFsm.techProfileID})
1593 go func(aPAFsm *AdapterFsm) {
1594 if aPAFsm != nil && aPAFsm.pFsm != nil {
1595 _ = aPAFsm.pFsm.Event(aniEvRxPrioqsResp)
1596 }
1597 }(oFsm.pAdaptFsm)
1598 return
1599 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001600 const cu16StrictPrioWeight uint16 = 0xFFFF
1601 //find all upstream PrioQueues related to this T-Cont
1602 loQueueMap := ordered_map.NewOrderedMap()
1603 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001604 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001606 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1607 "prioString": gemPortAttribs.pbitString})
1608 continue
1609 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001610 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301611 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001612 //key does not yet exist
1613 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1614 }
1615 } else {
1616 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1617 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001618 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001619
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001620 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1621 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1622 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1623 // or even be finished without correct SP/WRR setting
1624
1625 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1626 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1627 // even though its T-Cont seems to be wrong ...
1628 loTrafficSchedulerEID := 0x8000
1629 //for all found queues
1630 iter := loQueueMap.IterFunc()
1631 for kv, ok := iter(); ok; kv, ok = iter() {
1632 queueIndex := (kv.Key).(uint16)
1633 meParams := me.ParamData{
1634 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301635 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001636 }
1637 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1638 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001640 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001641 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001642 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1643 } else {
1644 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001646 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1647 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001648 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001649 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1650 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1651 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001652 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001653 meInstance, err := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001654 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001655 if err != nil {
1656 oFsm.mutexPLastTxMeInstance.Unlock()
1657 logger.Errorw(ctx, "PrioQueueVar set failed, aborting uniPonAniConfigFsm!",
1658 log.Fields{"device-id": oFsm.deviceID})
1659 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1660 return
1661 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001662 //accept also nil as (error) return value for writing to LastTx
1663 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001664 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001665 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001666
1667 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001668 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001669 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001671 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301672 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001673 return
1674 }
1675
1676 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1677 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1678 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1679 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1680
1681 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001682
1683 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301685 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001686}
1687
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001689 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001690 if oFsm.isCanceled {
1691 // FSM already canceled before entering wait
1692 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
1693 oFsm.mutexIsAwaitingResponse.Unlock()
1694 return fmt.Errorf(cErrWaitAborted)
1695 }
mpagenko7d6bb022021-03-11 15:07:55 +00001696 oFsm.isAwaitingResponse = true
1697 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001698 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301699 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001700 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001701 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001702 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 +00001703 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001704 oFsm.mutexIsAwaitingResponse.Lock()
1705 oFsm.isAwaitingResponse = false
1706 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001707 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001708 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301709 if success {
mpagenkocf48e452021-04-23 09:23:00 +00001710 logger.Debugw(ctx, "uniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001711 oFsm.mutexIsAwaitingResponse.Lock()
1712 oFsm.isAwaitingResponse = false
1713 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001714 return nil
1715 }
mpagenko7d6bb022021-03-11 15:07:55 +00001716 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00001717 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001718 oFsm.mutexIsAwaitingResponse.Lock()
1719 oFsm.isAwaitingResponse = false
1720 oFsm.mutexIsAwaitingResponse.Unlock()
1721 return fmt.Errorf(cErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001722 }
1723}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001724
1725func (oFsm *uniPonAniConfigFsm) setChanSet(flagValue bool) {
1726 oFsm.mutexChanSet.Lock()
1727 oFsm.chanSet = flagValue
1728 oFsm.mutexChanSet.Unlock()
1729}
1730
1731func (oFsm *uniPonAniConfigFsm) isChanSet() bool {
1732 oFsm.mutexChanSet.RLock()
1733 flagValue := oFsm.chanSet
1734 oFsm.mutexChanSet.RUnlock()
1735 return flagValue
1736}