blob: 33e323dc3a68e96c0bfd1d814fbe0ac5a36c21d5 [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"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/log"
34 //ic "github.com/opencord/voltha-protos/v5/go/inter_container"
35 //"github.com/opencord/voltha-protos/v5/go/openflow_13"
36 //"github.com/opencord/voltha-protos/v5/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"
Mahir Gunyel9545be22021-07-04 15:53:16 -070065 aniEvRemGemDone = "aniEvRemGemDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000066)
67const (
68 // states of config PON ANI port FSM
69 aniStDisabled = "aniStDisabled"
70 aniStStarting = "aniStStarting"
71 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
72 aniStCreatingMBPCD = "aniStCreatingMBPCD"
73 aniStSettingTconts = "aniStSettingTconts"
74 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
75 aniStCreatingGemIWs = "aniStCreatingGemIWs"
76 aniStSettingPQs = "aniStSettingPQs"
77 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
78 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000079 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080080 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000081 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030082 aniStRemovingTD = "aniStRemovingTD"
mpagenko8b07c1b2020-11-26 10:36:31 +000083 aniStResetTcont = "aniStResetTcont"
84 aniStRemDot1PMapper = "aniStRemDot1PMapper"
85 aniStRemAniBPCD = "aniStRemAniBPCD"
86 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000087 aniStResetting = "aniStResetting"
88)
Holger Hildebrandt10d98192021-01-27 15:29:31 +000089const cAniFsmIdleState = aniStConfigDone
mpagenko1cc3cb42020-07-27 15:24:38 +000090
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000091type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030092 gemPortID uint16
93 upQueueID uint16
94 downQueueID uint16
95 direction uint8
96 qosPolicy string
97 weight uint8
98 pbitString string
99 isMulticast bool
100 multicastGemID uint16
101 staticACL string
102 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000103}
104
Himani Chawla6d2ae152020-09-02 13:11:20 +0530105//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
106type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000107 pDeviceHandler *deviceHandler
108 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530109 pOmciCC *omciCC
110 pOnuUniPort *onuUniPort
111 pUniTechProf *onuUniTechProf
112 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800113 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000114 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000115 requestEvent OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000116 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000117 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000118 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530119 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000120 pAdaptFsm *AdapterFsm
121 chSuccess chan<- uint8
122 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000123 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000124 chanSet bool
125 mapperSP0ID uint16
126 macBPCD0ID uint16
127 tcont0ID uint16
128 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000129 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000130 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000131 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000132 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000133 isWaitingForFlowDelete bool
134 waitFlowDeleteChannel chan bool
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700135 tcontSetBefore bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000136}
137
Himani Chawla6d2ae152020-09-02 13:11:20 +0530138//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 +0000139func newUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800140 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000141 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530142 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000143 pDeviceHandler: apDeviceHandler,
144 deviceID: apDeviceHandler.deviceID,
145 pOmciCC: apDevOmciCC,
146 pOnuUniPort: apUniPort,
147 pUniTechProf: apUniTechProf,
148 pOnuDB: apOnuDB,
149 techProfileID: aTechProfileID,
150 requestEvent: aRequestEvent,
151 chanSet: false,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700152 tcontSetBefore: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000153 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000154 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
mpagenkobb47bc22021-04-20 13:29:09 +0000155 instFsm.waitFlowDeleteChannel = make(chan bool)
mpagenko8b07c1b2020-11-26 10:36:31 +0000156
mpagenko01e726e2020-10-23 09:45:29 +0000157 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000158 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000159 logger.Errorw(ctx, "uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000160 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000161 return nil
162 }
163
164 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000165 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000166 fsm.Events{
167
mpagenko1cc3cb42020-07-27 15:24:38 +0000168 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000169
170 //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 +0000171 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000172 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000173 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
174 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000175 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000176 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000177 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000178 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000179 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000180 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000181 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000182
mpagenko8b07c1b2020-11-26 10:36:31 +0000183 //for removing Gem related resources
184 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800185 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
186 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000187 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300188 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700189 {Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStRemDot1PMapper},
190 {Name: aniEvRemGemDone, Src: []string{aniStRemDot1PMapper}, Dst: aniStConfigDone},
191 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
192 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000193
194 //for removing TCONT related resources
195 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700196 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStConfigDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000197
198 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300199 aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000200 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000201 {Name: aniEvTimeoutMids, Src: []string{
202 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000203
mpagenko1cc3cb42020-07-27 15:24:38 +0000204 // exceptional treatment for all states except aniStResetting
205 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
206 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300207 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000208 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000209 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000210 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000211 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000212 },
213
214 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000215 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
216 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
217 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
218 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
219 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
220 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
221 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
222 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
223 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
224 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
225 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000226 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300228 ("enter_" + aniStRemovingTD): func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000229 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
230 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
231 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
232 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
233 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
234 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000235 },
236 )
237 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000238 logger.Errorw(ctx, "uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000239 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000240 return nil
241 }
242
dbainbri4d3a0dc2020-12-02 00:33:42 +0000243 logger.Debugw(ctx, "uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000244 return instFsm
245}
246
Himani Chawla6d2ae152020-09-02 13:11:20 +0530247//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
248func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000249 oFsm.chSuccess = aChSuccess
250 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000251 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000252}
253
mpagenko7d6bb022021-03-11 15:07:55 +0000254//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000255func (oFsm *uniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
256 //early indication about started reset processing
257 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000258 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000259 oFsm.mutexIsAwaitingResponse.Lock()
260 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000261 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000262 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
263 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
264 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000265 //use channel to indicate that the response waiting shall be aborted
266 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000267 } else {
268 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000269 }
mpagenkocf48e452021-04-23 09:23:00 +0000270
271 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000272 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000273 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000274 //use channel to indicate that the response waiting shall be aborted
275 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000276 } else {
277 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000278 }
mpagenkocf48e452021-04-23 09:23:00 +0000279
mpagenko7d6bb022021-03-11 15:07:55 +0000280 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
281 pAdaptFsm := oFsm.pAdaptFsm
282 if pAdaptFsm != nil {
283 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
284 go func(aPAFsm *AdapterFsm) {
285 if aPAFsm.pFsm != nil {
286 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
287 }
288 }(pAdaptFsm)
289 }
mpagenko73143992021-04-09 15:17:10 +0000290
mpagenko45cc6a32021-07-23 10:06:57 +0000291 // possible access conflicts on internal data by next needed data clearance
292 // are avoided by using mutexTPState also from within clearAniSideConfig
293 // do not try to lock TpProcMutex here as done in previous code version
294 // as it may result in deadlock situations (as observed at soft-reboot handling where
295 // TpProcMutex is already locked by some ongoing TechProfile config/removal processing
mpagenko73143992021-04-09 15:17:10 +0000296 //remove all TechProf related internal data to allow for new configuration
297 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000298}
299
Mahir Gunyel6781f962021-05-16 23:30:08 -0700300//nolint: gocyclo
301//TODO:visit here for refactoring for gocyclo
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530303 if aPAFsm != nil && aPAFsm.pFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700304 var err error
305 oFsm.mapperSP0ID, err = generateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
306 if err != nil {
307 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
308 "techProfileID": oFsm.techProfileID, "error": err})
309 return
310 }
311 oFsm.macBPCD0ID, err = generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
312 if err != nil {
313 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
314 "techProfileID": oFsm.techProfileID, "error": err})
315 return
316 }
317 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
318 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
319 "macBpNo": oFsm.pOnuUniPort.macBpNo, "techProfileID": oFsm.techProfileID})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700320 pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false)
321 if pDevEntry == nil {
322 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800323 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530324 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700325 tcontInstID, tcontAlreadyExist, err := pDevEntry.allocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
326 if err != nil {
327 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700328 //reset the state machine to enable usage on subsequent requests
329 _ = aPAFsm.pFsm.Event(aniEvReset)
330 return
331 }
332 oFsm.tcont0ID = tcontInstID
333 oFsm.tcontSetBefore = tcontAlreadyExist
334 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
335 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
336 "tcontAlreadyExist": tcontAlreadyExist,
337 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800338
339 // Access critical state with lock
mpagenko3ce9fa02021-07-28 13:26:54 +0000340 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000341 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
342 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko3ce9fa02021-07-28 13:26:54 +0000343 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800344
Himani Chawla26e555c2020-08-31 12:30:20 +0530345 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800346 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300347 loGemPortAttribs := ponAniGemPortAttribs{}
348
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
350
dbainbri4d3a0dc2020-12-02 00:33:42 +0000351 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530352
353 loGemPortAttribs.gemPortID = gemEntry.gemPortID
354 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
355 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
356 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
357 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
358
359 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
360 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
361 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
362 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
363 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
364 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
365
366 usQueueFound := false
367 dsQueueFound := false
368 for _, mgmtEntityID := range queueInstKeys {
369 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
370 returnVal := meAttributes["RelatedPort"]
371 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530372 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 if relatedPort == usQrelPortMask {
374 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000376 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 usQueueFound = true
378 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
379 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000380 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000381 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 dsQueueFound = true
383 }
384 if usQueueFound && dsQueueFound {
385 break
386 }
387 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 }
390 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 }
393 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000394 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000395 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
397 }
398 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000399 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 }
401 loGemPortAttribs.direction = gemEntry.direction
402 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
403 loGemPortAttribs.weight = gemEntry.queueWeight
404 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300405
ozgecanetsia4b232302020-11-11 10:58:10 +0300406 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300407 //TODO this might effectively ignore the for loop starting at line 316
408 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300409 loGemPortAttribs.isMulticast = true
410 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
411 loGemPortAttribs.staticACL = gemEntry.staticACL
412 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530413
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300415 "gemPortID": loGemPortAttribs.gemPortID,
416 "isMulticast": loGemPortAttribs.isMulticast,
417 "multicastGemID": loGemPortAttribs.multicastGemID,
418 "staticACL": loGemPortAttribs.staticACL,
419 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000420 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300421 })
422
423 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300425 "gemPortID": loGemPortAttribs.gemPortID,
426 "upQueueID": loGemPortAttribs.upQueueID,
427 "downQueueID": loGemPortAttribs.downQueueID,
428 "pbitString": loGemPortAttribs.pbitString,
429 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000430 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300431 })
432 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530433
434 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
435 }
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000436 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
437 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
438 } else {
439 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
440 _ = aPAFsm.pFsm.Event(aniEvSkipOmciConfig)
441 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530442 }
443}
444
dbainbri4d3a0dc2020-12-02 00:33:42 +0000445func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
446 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000447 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000448 // in case the used channel is not yet defined (can be re-used after restarts)
449 if oFsm.omciMIdsResponseReceived == nil {
450 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000451 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000452 } else {
453 // as we may 're-use' this instance of FSM and the connected channel
454 // make sure there is no 'lingering' request in the already existing channel:
455 // (simple loop sufficient as we are the only receiver)
456 for len(oFsm.omciMIdsResponseReceived) > 0 {
457 <-oFsm.omciMIdsResponseReceived
458 }
459 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000460 //ensure internal slices are empty (which might be set from previous run) - release memory
461 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000462 oFsm.mutexIsAwaitingResponse.Lock()
463 //reset the canceled state possibly existing from previous reset
464 oFsm.isCanceled = false
465 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000466
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000467 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000468 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000469
470 //let the state machine run forward from here directly
471 pConfigAniStateAFsm := oFsm.pAdaptFsm
472 if pConfigAniStateAFsm != nil {
473 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000475
mpagenko3dbcdd22020-07-22 07:38:45 +0000476 }
477}
478
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
480 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000481 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000482 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
483 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000484 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300485 meInstance, err := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000486 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300487 if err != nil {
488 logger.Errorw(ctx, "Dot1PMapper create failed, aborting uniPonAniConfigFsm!",
489 log.Fields{"device-id": oFsm.deviceID})
490 pConfigAniStateAFsm := oFsm.pAdaptFsm
491 if pConfigAniStateAFsm != nil {
492 oFsm.mutexPLastTxMeInstance.Unlock()
493 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
494 go func(aPAFsm *AdapterFsm) {
495 if aPAFsm != nil && aPAFsm.pFsm != nil {
496 _ = aPAFsm.pFsm.Event(aniEvReset)
497 }
498 }(pConfigAniStateAFsm)
499 return
500 }
501 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000502 //accept also nil as (error) return value for writing to LastTx
503 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000504 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300505 oFsm.mutexPLastTxMeInstance.Unlock()
506
mpagenko3dbcdd22020-07-22 07:38:45 +0000507}
508
dbainbri4d3a0dc2020-12-02 00:33:42 +0000509func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
510 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000511 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
512 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000513 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000514 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
515 meParams := me.ParamData{
516 EntityID: oFsm.macBPCD0ID,
517 Attributes: me.AttributeValueMap{
518 "BridgeIdPointer": bridgePtr,
519 "PortNum": 0xFF, //fixed unique ANI side indication
520 "TpType": 3, //for .1PMapper
521 "TpPointer": oFsm.mapperSP0ID,
522 },
523 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000524 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300525 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000526 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300527 if err != nil {
528 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting uniPonAniConfigFsm!",
529 log.Fields{"device-id": oFsm.deviceID})
530 pConfigAniStateAFsm := oFsm.pAdaptFsm
531 if pConfigAniStateAFsm != nil {
532 oFsm.mutexPLastTxMeInstance.Unlock()
533 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
534 go func(aPAFsm *AdapterFsm) {
535 if aPAFsm != nil && aPAFsm.pFsm != nil {
536 _ = aPAFsm.pFsm.Event(aniEvReset)
537 }
538 }(pConfigAniStateAFsm)
539 return
540 }
541 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000542 //accept also nil as (error) return value for writing to LastTx
543 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000544 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300545 oFsm.mutexPLastTxMeInstance.Unlock()
546
mpagenko3dbcdd22020-07-22 07:38:45 +0000547}
548
dbainbri4d3a0dc2020-12-02 00:33:42 +0000549func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
550 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000551 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
552 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700553 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
554 "tcontExist": oFsm.tcontSetBefore})
555 //If tcont was set before, then no need to set it again. Let state machine to proceed.
556 if oFsm.tcontSetBefore {
557 go func(aPAFsm *AdapterFsm) {
558 if aPAFsm != nil && aPAFsm.pFsm != nil {
559 _ = aPAFsm.pFsm.Event(aniEvRxTcontsResp)
560 }
561 }(oFsm.pAdaptFsm)
562 return
563 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000564 meParams := me.ParamData{
565 EntityID: oFsm.tcont0ID,
566 Attributes: me.AttributeValueMap{
567 "AllocId": oFsm.alloc0ID,
568 },
569 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000570 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300571 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000572 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300573 if err != nil {
574 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
575 log.Fields{"device-id": oFsm.deviceID})
576 pConfigAniStateAFsm := oFsm.pAdaptFsm
577 if pConfigAniStateAFsm != nil {
578 oFsm.mutexPLastTxMeInstance.Unlock()
579 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
580 go func(aPAFsm *AdapterFsm) {
581 if aPAFsm != nil && aPAFsm.pFsm != nil {
582 _ = aPAFsm.pFsm.Event(aniEvReset)
583 }
584 }(pConfigAniStateAFsm)
585 return
586 }
587 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000588 //accept also nil as (error) return value for writing to LastTx
589 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000590 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300591 oFsm.mutexPLastTxMeInstance.Unlock()
592
mpagenko3dbcdd22020-07-22 07:38:45 +0000593}
594
dbainbri4d3a0dc2020-12-02 00:33:42 +0000595func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
596 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000597 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000598 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000599}
600
dbainbri4d3a0dc2020-12-02 00:33:42 +0000601func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
602 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000603 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000605}
606
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
608 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000609 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000610 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000611}
612
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300614
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000616 "toGemIw": 1024, /* cmp above */
617 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000618
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000620 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000621 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000622
mpagenko3dbcdd22020-07-22 07:38:45 +0000623 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000624 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530625 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000626 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000627
628 //assign the GemPorts according to the configured Prio
629 var loPrioGemPortArray [8]uint16
630 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300631 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300633 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
634 "prioString": gemPortAttribs.pbitString})
635 continue
636 }
637 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000638 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300639 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
640 "prioString": gemPortAttribs.pbitString})
641 continue
642 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000643 for i := 0; i < 8; i++ {
644 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
645 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
646 if prio == 1 { // Check this p-bit is set
647 if loPrioGemPortArray[i] == 0 {
648 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
649 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000651 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000652 "SetGemPort": loPrioGemPortArray[i]})
653 }
654 }
655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000657 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000658 "prioString": gemPortAttribs.pbitString, "position": i})
659 }
660
661 }
662 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300663
ozgecanetsia4b232302020-11-11 10:58:10 +0300664 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530665 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300666 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530667 if value != 0 {
668 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530669 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000671 "for Prio": index,
672 "IwPtr": strconv.FormatInt(int64(value), 16),
673 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300674 } else {
675 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000676 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
677 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300678 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530679 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000680 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300681 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000682 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
683 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300684 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530685
686 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000688 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300689 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
690 // 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 +0000691 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300692 //pConfigAniStateAFsm := oFsm.pAdaptFsm
693 //if pConfigAniStateAFsm != nil {
694 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
695 // go func(aPAFsm *AdapterFsm) {
696 // if aPAFsm != nil && aPAFsm.pFsm != nil {
697 // _ = aPAFsm.pFsm.Event(aniEvReset)
698 // }
699 // }(pConfigAniStateAFsm)
700 //}
701 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000702 pConfigAniStateAFsm := oFsm.pAdaptFsm
703 if pConfigAniStateAFsm != nil {
704 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530705 go func(aPAFsm *AdapterFsm) {
706 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300707 _ = aPAFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000708 }
709 }(pConfigAniStateAFsm)
710 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300711 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000712 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300713 meInstance, err := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300714 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300715 if err != nil {
716 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting uniPonAniConfigFsm!",
717 log.Fields{"device-id": oFsm.deviceID})
718 pConfigAniStateAFsm := oFsm.pAdaptFsm
719 if pConfigAniStateAFsm != nil {
720 oFsm.mutexPLastTxMeInstance.Unlock()
721 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
722 go func(aPAFsm *AdapterFsm) {
723 if aPAFsm != nil && aPAFsm.pFsm != nil {
724 _ = aPAFsm.pFsm.Event(aniEvReset)
725 }
726 }(pConfigAniStateAFsm)
727 return
728 }
729 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300730 //accept also nil as (error) return value for writing to LastTx
731 // - this avoids misinterpretation of new received OMCI messages
732 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300733 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000734 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000735}
736
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
738 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000739 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000740 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800741 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000742 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
743 //use DeviceHandler event notification directly
744 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
745 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
746 // but only in case the techProfile was configured (not deleted)
747 if oFsm.requestEventOffset == 0 {
748 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
749 }
750 } else {
751 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000752 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000753 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000754 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000756 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
757 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000758 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000759 }
mpagenko01e726e2020-10-23 09:45:29 +0000760
761 //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 +0000762}
763
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000765 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
766 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000767 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
768 select {
769 case <-oFsm.waitFlowDeleteChannel:
770 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
771 default:
772 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000773
774 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID] != nil {
mpagenko3ce9fa02021-07-28 13:26:54 +0000775 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000776 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000777 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
778 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
779 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
780 pConfigAniStateAFsm := oFsm.pAdaptFsm
781 if pConfigAniStateAFsm != nil {
782 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
783 go func(aPAFsm *AdapterFsm) {
784 if aPAFsm != nil && aPAFsm.pFsm != nil {
785 _ = aPAFsm.pFsm.Event(aniEvWaitFlowRem)
786 }
787 }(pConfigAniStateAFsm)
788 } else {
789 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
790 }
791 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800792 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000793 } else {
794 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
795 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800796 }
797
mpagenko3ce9fa02021-07-28 13:26:54 +0000798 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000799 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000800 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000801 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000803 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
804 "GemIwTp-entity-id": loGemPortID})
805 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
806
807 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000808 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300809 meInstance, err := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000810 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300811 if err != nil {
812 logger.Errorw(ctx, "GemIWTP delete failed, aborting uniPonAniConfigFsm!",
813 log.Fields{"device-id": oFsm.deviceID})
814 pConfigAniStateAFsm := oFsm.pAdaptFsm
815 if pConfigAniStateAFsm != nil {
816 oFsm.mutexPLastTxMeInstance.Unlock()
817 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
818 go func(aPAFsm *AdapterFsm) {
819 if aPAFsm != nil && aPAFsm.pFsm != nil {
820 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
821 }
822 }(pConfigAniStateAFsm)
823 return
824 }
825 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000826 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300827 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000828}
829
mpagenkobb47bc22021-04-20 13:29:09 +0000830func (oFsm *uniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
831 oFsm.mutexIsAwaitingResponse.Lock()
832 oFsm.isWaitingForFlowDelete = true
833 oFsm.mutexIsAwaitingResponse.Unlock()
834 select {
835 // maybe be also some outside cancel (but no context modeled for the moment ...)
836 // case <-ctx.Done():
837 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000838 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 +0000839 logger.Warnw(ctx, "uniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
840 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
841 oFsm.mutexIsAwaitingResponse.Lock()
842 oFsm.isWaitingForFlowDelete = false
843 oFsm.mutexIsAwaitingResponse.Unlock()
844 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
845 pConfigAniStateAFsm := oFsm.pAdaptFsm
846 if pConfigAniStateAFsm != nil {
847 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
848 go func(aPAFsm *AdapterFsm) {
849 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300850 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000851 }
852 }(pConfigAniStateAFsm)
853 } else {
854 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
855 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
856 }
857 return
858
859 case success := <-oFsm.waitFlowDeleteChannel:
860 if success {
861 logger.Debugw(ctx, "uniPonAniConfigFsm flow removed info received", log.Fields{
862 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
863 oFsm.mutexIsAwaitingResponse.Lock()
864 oFsm.isWaitingForFlowDelete = false
865 oFsm.mutexIsAwaitingResponse.Unlock()
866 pConfigAniStateAFsm := oFsm.pAdaptFsm
867 if pConfigAniStateAFsm != nil {
868 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
869 go func(aPAFsm *AdapterFsm) {
870 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300871 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000872 }
873 }(pConfigAniStateAFsm)
874 } else {
875 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
876 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
877 }
878 return
879 }
880 // waiting was aborted (probably on external request)
881 logger.Debugw(ctx, "uniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
882 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
883 oFsm.mutexIsAwaitingResponse.Lock()
884 oFsm.isWaitingForFlowDelete = false
885 oFsm.mutexIsAwaitingResponse.Unlock()
886 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
887 pConfigAniStateAFsm := oFsm.pAdaptFsm
888 if pConfigAniStateAFsm != nil {
889 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
890 go func(aPAFsm *AdapterFsm) {
891 if aPAFsm != nil && aPAFsm.pFsm != nil {
892 _ = aPAFsm.pFsm.Event(aniEvReset)
893 }
894 }(pConfigAniStateAFsm)
895 }
896 return
897 }
898}
899
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000901 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000902 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000903 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000904 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000905 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
906 "GemNCTP-entity-id": loGemPortID})
907 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000908 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300909 meInstance, err := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000910 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300911 if err != nil {
912 logger.Errorw(ctx, "GemNCTP delete failed, aborting uniPonAniConfigFsm!",
913 log.Fields{"device-id": oFsm.deviceID})
914 pConfigAniStateAFsm := oFsm.pAdaptFsm
915 if pConfigAniStateAFsm != nil {
916 oFsm.mutexPLastTxMeInstance.Unlock()
917 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
918 go func(aPAFsm *AdapterFsm) {
919 if aPAFsm != nil && aPAFsm.pFsm != nil {
920 _ = aPAFsm.pFsm.Event(aniEvReset)
921 }
922 }(pConfigAniStateAFsm)
923 return
924 }
925 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000926 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000927 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300928
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800929 // Mark the gem port to be removed for Performance History monitoring
930 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -0700931 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800932 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000933}
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300934func (oFsm *uniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000935 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300936 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000937 oFsm.pUniTechProf.mutexTPState.RUnlock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300938 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
939 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
940 "TD-entity-id": loGemPortID})
941
942 oFsm.mutexPLastTxMeInstance.Lock()
943 meInstance, err := oFsm.pOmciCC.sendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
944 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, loGemPortID)
945
946 if err != nil {
947 logger.Errorw(ctx, "TD delete failed - proceed fsm",
948 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
949 pConfigAniStateAFsm := oFsm.pAdaptFsm
950 if pConfigAniStateAFsm != nil {
951 oFsm.mutexPLastTxMeInstance.Unlock()
952 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
953 go func(aPAFsm *AdapterFsm) {
954 if aPAFsm != nil && aPAFsm.pFsm != nil {
955 _ = aPAFsm.pFsm.Event(aniEvReset)
956 }
957 }(pConfigAniStateAFsm)
958 return
959 }
960 }
961 oFsm.pLastTxMeInstance = meInstance
962 oFsm.mutexPLastTxMeInstance.Unlock()
963}
mpagenko8b07c1b2020-11-26 10:36:31 +0000964
dbainbri4d3a0dc2020-12-02 00:33:42 +0000965func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
966 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000967 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
968
969 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
970 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
971 meParams := me.ParamData{
972 EntityID: oFsm.tcont0ID,
973 Attributes: me.AttributeValueMap{
974 "AllocId": unusedTcontAllocID,
975 },
976 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000977 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300978 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000979 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300980 if err != nil {
981 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
982 log.Fields{"device-id": oFsm.deviceID})
983 pConfigAniStateAFsm := oFsm.pAdaptFsm
984 if pConfigAniStateAFsm != nil {
985 oFsm.mutexPLastTxMeInstance.Unlock()
986 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
987 go func(aPAFsm *AdapterFsm) {
988 if aPAFsm != nil && aPAFsm.pFsm != nil {
989 _ = aPAFsm.pFsm.Event(aniEvReset)
990 }
991 }(pConfigAniStateAFsm)
992 return
993 }
994 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000995 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300996 oFsm.mutexPLastTxMeInstance.Unlock()
997
mpagenko8b07c1b2020-11-26 10:36:31 +0000998}
999
dbainbri4d3a0dc2020-12-02 00:33:42 +00001000func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
1001 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001002 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Mahir Gunyel9545be22021-07-04 15:53:16 -07001003 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1004 unicastGemCount := 0
1005 for _, gemEntry := range mapGemPortParams {
1006 if !gemEntry.isMulticast {
1007 unicastGemCount++
1008 }
1009 }
1010 if unicastGemCount > 1 {
1011 logger.Debugw(ctx, "uniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1012 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1013 pConfigAniStateAFsm := oFsm.pAdaptFsm
1014 if pConfigAniStateAFsm != nil {
1015 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1016 go func(aPAFsm *AdapterFsm) {
1017 if aPAFsm != nil && aPAFsm.pFsm != nil {
1018 _ = aPAFsm.pFsm.Event(aniEvRemGemDone)
1019 }
1020 }(pConfigAniStateAFsm)
1021 return
1022 }
1023 }
1024 logger.Debugw(ctx, "uniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1025 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001026
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001027 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001028 meInstance, err := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001029 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001030 if err != nil {
1031 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting uniPonAniConfigFsm!",
1032 log.Fields{"device-id": oFsm.deviceID})
1033 pConfigAniStateAFsm := oFsm.pAdaptFsm
1034 if pConfigAniStateAFsm != nil {
1035 oFsm.mutexPLastTxMeInstance.Unlock()
1036 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1037 go func(aPAFsm *AdapterFsm) {
1038 if aPAFsm != nil && aPAFsm.pFsm != nil {
1039 _ = aPAFsm.pFsm.Event(aniEvReset)
1040 }
1041 }(pConfigAniStateAFsm)
1042 return
1043 }
1044 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001045 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001046 oFsm.mutexPLastTxMeInstance.Unlock()
1047
mpagenko8b07c1b2020-11-26 10:36:31 +00001048}
1049
dbainbri4d3a0dc2020-12-02 00:33:42 +00001050func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1051 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001052 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1053
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001054 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001055 meInstance, err := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001056 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001057 if err != nil {
1058 logger.Errorw(ctx, "MBPConfigData delete failed, aborting uniPonAniConfigFsm!",
1059 log.Fields{"device-id": oFsm.deviceID})
1060 pConfigAniStateAFsm := oFsm.pAdaptFsm
1061 if pConfigAniStateAFsm != nil {
1062 oFsm.mutexPLastTxMeInstance.Unlock()
1063 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1064 go func(aPAFsm *AdapterFsm) {
1065 if aPAFsm != nil && aPAFsm.pFsm != nil {
1066 _ = aPAFsm.pFsm.Event(aniEvReset)
1067 }
1068 }(pConfigAniStateAFsm)
1069 return
1070 }
1071 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001072 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001073 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001074}
1075
dbainbri4d3a0dc2020-12-02 00:33:42 +00001076func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1077 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001078 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1079 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001080 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001081 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001082 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +00001083 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001084 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1085 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001086 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001087 }
1088
1089 //let's reset the state machine in order to release all resources now
1090 pConfigAniStateAFsm := oFsm.pAdaptFsm
1091 if pConfigAniStateAFsm != nil {
1092 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1093 go func(aPAFsm *AdapterFsm) {
1094 if aPAFsm != nil && aPAFsm.pFsm != nil {
1095 _ = aPAFsm.pFsm.Event(aniEvReset)
1096 }
1097 }(pConfigAniStateAFsm)
1098 }
1099}
1100
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1102 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001103 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001104
mpagenko45cc6a32021-07-23 10:06:57 +00001105 if oFsm.isChanSet() {
1106 // indicate processing error to the caller (in case there was still some open request)
1107 logger.Debugw(ctx, "uniPonAniConfigFsm processingError on channel", log.Fields{
1108 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1109 //use non-blocking channel send to avoid blocking because of non-existing receiver
1110 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1111 select {
1112 case oFsm.chSuccess <- 0:
1113 default:
1114 logger.Debugw(ctx, "uniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
1115 "device-id": oFsm.deviceID})
1116 }
1117 oFsm.setChanSet(false) //reset the internal channel state
1118 }
1119
mpagenko3dbcdd22020-07-22 07:38:45 +00001120 pConfigAniStateAFsm := oFsm.pAdaptFsm
1121 if pConfigAniStateAFsm != nil {
1122 // abort running message processing
1123 fsmAbortMsg := Message{
1124 Type: TestMsg,
1125 Data: TestMessage{
1126 TestMessageVal: AbortMessageProcessing,
1127 },
1128 }
1129 pConfigAniStateAFsm.commChan <- fsmAbortMsg
1130
1131 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +05301132 go func(aPAFsm *AdapterFsm) {
1133 if aPAFsm != nil && aPAFsm.pFsm != nil {
1134 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001135 }
1136 }(pConfigAniStateAFsm)
1137 }
1138}
1139
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1141 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001142 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001143 oFsm.mutexPLastTxMeInstance.Lock()
1144 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001145 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001146}
1147
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1149 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001150loop:
1151 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001152 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001153 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001154 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301155 message, ok := <-oFsm.pAdaptFsm.commChan
1156 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301158 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1159 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1160 break loop
1161 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301163
1164 switch message.Type {
1165 case TestMsg:
1166 msg, _ := message.Data.(TestMessage)
1167 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001168 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001169 break loop
1170 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001171 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301172 case OMCI:
1173 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001174 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301175 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001176 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301177 "message.Type": message.Type})
1178 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001179
Himani Chawla4d908332020-08-31 12:30:20 +05301180 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001181 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301182}
1183
dbainbri4d3a0dc2020-12-02 00:33:42 +00001184func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301185 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1186 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001187 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001188 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301189 return
1190 }
1191 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1192 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001194 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301195 return
1196 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001197 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001198 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1199 //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 +00001200 oFsm.mutexPLastTxMeInstance.RLock()
1201 if oFsm.pLastTxMeInstance != nil {
1202 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1203 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1204 // maybe we can use just the same eventName for different state transitions like "forward"
1205 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1206 switch oFsm.pLastTxMeInstance.GetName() {
1207 case "Ieee8021PMapperServiceProfile":
1208 { // let the FSM proceed ...
1209 oFsm.mutexPLastTxMeInstance.RUnlock()
1210 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
1211 }
1212 case "MacBridgePortConfigurationData":
1213 { // let the FSM proceed ...
1214 oFsm.mutexPLastTxMeInstance.RUnlock()
1215 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
1216 }
1217 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1218 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1219 oFsm.mutexPLastTxMeInstance.RUnlock()
1220 oFsm.omciMIdsResponseReceived <- true
1221 }
1222 default:
1223 {
1224 oFsm.mutexPLastTxMeInstance.RUnlock()
1225 logger.Warnw(ctx, "Unsupported ME name received!",
1226 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1227 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001228 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001229 } else {
1230 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001231 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001232 } else {
1233 oFsm.mutexPLastTxMeInstance.RUnlock()
1234 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001235 }
1236 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001237 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1238 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301239 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1240 return
1241 }
Himani Chawla4d908332020-08-31 12:30:20 +05301242}
Mahir Gunyel01034b62021-06-29 11:25:09 -07001243func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
1244 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1245 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1246 oFsm.mutexPLastTxMeInstance.RLock()
1247 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1248 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1249 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1250 switch oFsm.pLastTxMeInstance.GetName() {
1251 case "TCont":
1252 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1253 //We should revert DB
1254 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1255 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1256 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
1257 if pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false); pDevEntry != nil {
1258 pDevEntry.freeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
1259 } else {
1260 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1261 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1262 }
1263 }
1264 default:
1265 logger.Warnw(ctx, "Unsupported ME name received with error!",
1266 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1267 }
1268 }
1269}
dbainbri4d3a0dc2020-12-02 00:33:42 +00001270func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301271 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1272 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001274 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301275 return
1276 }
1277 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1278 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001280 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301281 return
1282 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301284 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001286 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301287 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001288
Mahir Gunyel01034b62021-06-29 11:25:09 -07001289 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301290 return
1291 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001292 oFsm.mutexPLastTxMeInstance.RLock()
1293 if oFsm.pLastTxMeInstance != nil {
1294 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1295 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1296 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1297 // if, then something like:
1298 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301299
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001300 switch oFsm.pLastTxMeInstance.GetName() {
1301 case "TCont":
1302 { // let the FSM proceed ...
1303 oFsm.mutexPLastTxMeInstance.RUnlock()
1304 if oFsm.requestEventOffset == 0 { //from TCont config request
1305 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
1306 } else { // from T-Cont reset request
1307 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
1308 }
1309 }
1310 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1311 { // let the PrioQueue init proceed by stopping the wait function
1312 oFsm.mutexPLastTxMeInstance.RUnlock()
1313 oFsm.omciMIdsResponseReceived <- true
1314 }
1315 case "Ieee8021PMapperServiceProfile":
1316 { // let the FSM proceed ...
1317 oFsm.mutexPLastTxMeInstance.RUnlock()
1318 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
1319 }
1320 default:
1321 {
1322 oFsm.mutexPLastTxMeInstance.RUnlock()
1323 logger.Warnw(ctx, "Unsupported ME name received!",
1324 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001325 }
Himani Chawla4d908332020-08-31 12:30:20 +05301326 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001327 } else {
1328 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301329 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001330 } else {
1331 oFsm.mutexPLastTxMeInstance.RUnlock()
1332 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301333 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001334}
1335
dbainbri4d3a0dc2020-12-02 00:33:42 +00001336func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001337 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1338 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001339 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001340 log.Fields{"device-id": oFsm.deviceID})
1341 return
1342 }
1343 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1344 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001345 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001346 log.Fields{"device-id": oFsm.deviceID})
1347 return
1348 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001349 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001350 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001352 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1353 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1354 // store error for mgmt display?
1355 return
1356 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001357 oFsm.mutexPLastTxMeInstance.RLock()
1358 if oFsm.pLastTxMeInstance != nil {
1359 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1360 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1361 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1362 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001363
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001364 switch oFsm.pLastTxMeInstance.GetName() {
1365 case "GemInterworkingTerminationPoint":
1366 { // let the FSM proceed ...
1367 oFsm.mutexPLastTxMeInstance.RUnlock()
1368 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
1369 }
1370 case "GemPortNetworkCtp":
1371 { // let the FSM proceed ...
1372 oFsm.mutexPLastTxMeInstance.RUnlock()
1373 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
1374 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001375 case "TrafficDescriptor":
1376 { // let the FSM proceed ...
1377 oFsm.mutexPLastTxMeInstance.RUnlock()
1378 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemTdResp)
1379 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001380 case "Ieee8021PMapperServiceProfile":
1381 { // let the FSM proceed ...
1382 oFsm.mutexPLastTxMeInstance.RUnlock()
1383 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
1384 }
1385 case "MacBridgePortConfigurationData":
1386 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1387 oFsm.mutexPLastTxMeInstance.RUnlock()
1388 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
1389 }
1390 default:
1391 {
1392 oFsm.mutexPLastTxMeInstance.RUnlock()
1393 logger.Warnw(ctx, "Unsupported ME name received!",
1394 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1395 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001396 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001397 } else {
1398 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001399 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001400 } else {
1401 oFsm.mutexPLastTxMeInstance.RUnlock()
1402 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001403 }
1404}
1405
dbainbri4d3a0dc2020-12-02 00:33:42 +00001406func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
1407 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001408 "msgType": msg.OmciMsg.MessageType})
1409
1410 switch msg.OmciMsg.MessageType {
1411 case omci.CreateResponseType:
1412 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301414
mpagenko3dbcdd22020-07-22 07:38:45 +00001415 } //CreateResponseType
1416 case omci.SetResponseType:
1417 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001419
mpagenko3dbcdd22020-07-22 07:38:45 +00001420 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001421 case omci.DeleteResponseType:
1422 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001423 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001424
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001425 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001426 default:
1427 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001429 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001430 return
1431 }
1432 }
1433}
1434
dbainbri4d3a0dc2020-12-02 00:33:42 +00001435func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001436 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1437 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001439 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1440 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001441 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001442 meParams := me.ParamData{
1443 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1444 Attributes: me.AttributeValueMap{
1445 "PortId": gemPortAttribs.gemPortID,
1446 "TContPointer": oFsm.tcont0ID,
1447 "Direction": gemPortAttribs.direction,
1448 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1449 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1450 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1451 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1452 },
1453 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001454 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001455 meInstance, err := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001456 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001457 if err != nil {
1458 oFsm.mutexPLastTxMeInstance.Unlock()
1459 logger.Errorw(ctx, "GemNCTPVar create failed, aborting uniPonAniConfigFsm!",
1460 log.Fields{"device-id": oFsm.deviceID})
1461 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1462 return
1463 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001464 //accept also nil as (error) return value for writing to LastTx
1465 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001466 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001467 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001468 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001469 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001470 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001472 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301473 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001474 return
1475 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001476 // Mark the gem port to be added for Performance History monitoring
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001477 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -07001478 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001479 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001480 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001481
1482 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301484 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001485}
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001486func (oFsm *uniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
1487 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1488 if gemPortAttribs.isMulticast {
1489 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1490 return true
1491 }
1492 }
1493 return false
1494}
mpagenko3dbcdd22020-07-22 07:38:45 +00001495
dbainbri4d3a0dc2020-12-02 00:33:42 +00001496func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001497 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1498 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001500 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1501 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001502 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001503
ozgecanetsia4b232302020-11-11 10:58:10 +03001504 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1505 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001506
1507 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001508 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001509 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001510 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001511 "InterworkingOption": 0, // Don't Care
1512 "ServiceProfilePointer": 0, // Don't Care
1513 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001514 },
1515 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001516 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1517 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1518 continue
1519 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001520 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001521 meInstance, err := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsia4b232302020-11-11 10:58:10 +03001522 true, oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001523 if err != nil {
1524 oFsm.mutexPLastTxMeInstance.Unlock()
1525 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting uniPonAniConfigFsm!",
1526 log.Fields{"device-id": oFsm.deviceID})
1527 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1528 return
1529
1530 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001531 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001532 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001533 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001534 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001535 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001536 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001537 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1538 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1539 return
1540 }
1541 ipv4MulticastTable := make([]uint8, 12)
1542 //Gem Port ID
1543 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1544 //Secondary Key
1545 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1546 // Multicast IP range start This is the 224.0.0.1 address
1547 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1548 // MulticastIp range stop
1549 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1550
1551 meIPV4MCTableParams := me.ParamData{
1552 EntityID: gemPortAttribs.multicastGemID,
1553 Attributes: me.AttributeValueMap{
1554 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1555 },
1556 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001557 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001558 meIPV4MCTableInstance, err := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001559 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001560 if err != nil {
1561 oFsm.mutexPLastTxMeInstance.Unlock()
1562 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting uniPonAniConfigFsm!",
1563 log.Fields{"device-id": oFsm.deviceID})
1564 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1565 return
1566 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001567 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001568 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001569
1570 } else {
1571 meParams := me.ParamData{
1572 EntityID: gemPortAttribs.gemPortID,
1573 Attributes: me.AttributeValueMap{
1574 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1575 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1576 "ServiceProfilePointer": oFsm.mapperSP0ID,
1577 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1578 "GalProfilePointer": galEthernetEID,
1579 },
1580 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001581 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001582 meInstance, err := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsia4b232302020-11-11 10:58:10 +03001583 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001584 if err != nil {
1585 oFsm.mutexPLastTxMeInstance.Unlock()
1586 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting uniPonAniConfigFsm!",
1587 log.Fields{"device-id": oFsm.deviceID})
1588 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1589 return
1590 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001591 //accept also nil as (error) return value for writing to LastTx
1592 // - this avoids misinterpretation of new received OMCI messages
1593 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001594 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001595 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001596 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001598 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001600 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301601 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001602 return
1603 }
1604 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001605
1606 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301608 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001609}
1610
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001612 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1613 if oFsm.tcontSetBefore {
1614 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1615 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
1616 "uni-id": oFsm.pOnuUniPort.uniID,
1617 "techProfile-id": oFsm.techProfileID})
1618 go func(aPAFsm *AdapterFsm) {
1619 if aPAFsm != nil && aPAFsm.pFsm != nil {
1620 _ = aPAFsm.pFsm.Event(aniEvRxPrioqsResp)
1621 }
1622 }(oFsm.pAdaptFsm)
1623 return
1624 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001625 const cu16StrictPrioWeight uint16 = 0xFFFF
1626 //find all upstream PrioQueues related to this T-Cont
1627 loQueueMap := ordered_map.NewOrderedMap()
1628 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001629 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001631 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1632 "prioString": gemPortAttribs.pbitString})
1633 continue
1634 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001635 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301636 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001637 //key does not yet exist
1638 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1639 }
1640 } else {
1641 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1642 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001643 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001644
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001645 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1646 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1647 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1648 // or even be finished without correct SP/WRR setting
1649
1650 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1651 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1652 // even though its T-Cont seems to be wrong ...
1653 loTrafficSchedulerEID := 0x8000
1654 //for all found queues
1655 iter := loQueueMap.IterFunc()
1656 for kv, ok := iter(); ok; kv, ok = iter() {
1657 queueIndex := (kv.Key).(uint16)
1658 meParams := me.ParamData{
1659 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301660 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001661 }
1662 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1663 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001665 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001666 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001667 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1668 } else {
1669 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001671 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1672 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001673 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001674 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1675 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1676 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001677 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001678 meInstance, err := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001679 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001680 if err != nil {
1681 oFsm.mutexPLastTxMeInstance.Unlock()
1682 logger.Errorw(ctx, "PrioQueueVar set failed, aborting uniPonAniConfigFsm!",
1683 log.Fields{"device-id": oFsm.deviceID})
1684 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1685 return
1686 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001687 //accept also nil as (error) return value for writing to LastTx
1688 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001689 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001690 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001691
1692 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001693 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001694 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001696 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301697 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001698 return
1699 }
1700
1701 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1702 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1703 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1704 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1705
1706 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001707
1708 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301710 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001711}
1712
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001714 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001715 if oFsm.isCanceled {
1716 // FSM already canceled before entering wait
1717 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
1718 oFsm.mutexIsAwaitingResponse.Unlock()
1719 return fmt.Errorf(cErrWaitAborted)
1720 }
mpagenko7d6bb022021-03-11 15:07:55 +00001721 oFsm.isAwaitingResponse = true
1722 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001723 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301724 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001725 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001726 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001727 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 +00001728 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001729 oFsm.mutexIsAwaitingResponse.Lock()
1730 oFsm.isAwaitingResponse = false
1731 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001732 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001733 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301734 if success {
mpagenkocf48e452021-04-23 09:23:00 +00001735 logger.Debugw(ctx, "uniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001736 oFsm.mutexIsAwaitingResponse.Lock()
1737 oFsm.isAwaitingResponse = false
1738 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001739 return nil
1740 }
mpagenko7d6bb022021-03-11 15:07:55 +00001741 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00001742 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001743 oFsm.mutexIsAwaitingResponse.Lock()
1744 oFsm.isAwaitingResponse = false
1745 oFsm.mutexIsAwaitingResponse.Unlock()
1746 return fmt.Errorf(cErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001747 }
1748}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001749
1750func (oFsm *uniPonAniConfigFsm) setChanSet(flagValue bool) {
1751 oFsm.mutexChanSet.Lock()
1752 oFsm.chanSet = flagValue
1753 oFsm.mutexChanSet.Unlock()
1754}
1755
1756func (oFsm *uniPonAniConfigFsm) isChanSet() bool {
1757 oFsm.mutexChanSet.RLock()
1758 flagValue := oFsm.chanSet
1759 oFsm.mutexChanSet.RUnlock()
1760 return flagValue
1761}