blob: e6f8680b121b74483404d4facff422114f494db0 [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
mpagenko7d6bb022021-03-11 15:07:55 +000026 "sync"
mpagenko3dbcdd22020-07-22 07:38:45 +000027 "time"
28
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000029 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000031 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070033 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000034 //ic "github.com/opencord/voltha-protos/v4/go/inter_container"
35 //"github.com/opencord/voltha-protos/v4/go/openflow_13"
36 //"github.com/opencord/voltha-protos/v4/go/voltha"
mpagenko3dbcdd22020-07-22 07:38:45 +000037)
38
mpagenko1cc3cb42020-07-27 15:24:38 +000039const (
40 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000041 aniEvStart = "aniEvStart"
42 aniEvStartConfig = "aniEvStartConfig"
43 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
44 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
45 aniEvRxTcontsResp = "aniEvRxTcontsResp"
46 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
47 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
48 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
49 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
50 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080051 aniEvWaitFlowRem = "aniEvWaitFlowRem"
52 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000053 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
54 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030055 aniEvRxRemTdResp = "aniEvRxRemTdResp"
mpagenko8b07c1b2020-11-26 10:36:31 +000056 aniEvRemTcontPath = "aniEvRemTcontPath"
57 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
58 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
59 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
60 aniEvTimeoutSimple = "aniEvTimeoutSimple"
61 aniEvTimeoutMids = "aniEvTimeoutMids"
62 aniEvReset = "aniEvReset"
63 aniEvRestart = "aniEvRestart"
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +000064 aniEvSkipOmciConfig = "aniEvSkipOmciConfig"
Mahir Gunyel82b7f872021-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 Gunyel82b7f872021-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 Gunyel82b7f872021-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
mpagenko18eca9c2021-07-26 11:03:45 +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
mpagenko7a592192021-07-28 13:32:00 +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
mpagenko7a592192021-07-28 13:32:00 +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) {
mpagenko7a592192021-07-28 13:32:00 +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
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000774 uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.uniID)
775 if uniVlanConfigFsm != nil {
mpagenko7a592192021-07-28 13:32:00 +0000776 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000777 if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000778 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
779 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
780 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
781 pConfigAniStateAFsm := oFsm.pAdaptFsm
782 if pConfigAniStateAFsm != nil {
783 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
784 go func(aPAFsm *AdapterFsm) {
785 if aPAFsm != nil && aPAFsm.pFsm != nil {
786 _ = aPAFsm.pFsm.Event(aniEvWaitFlowRem)
787 }
788 }(pConfigAniStateAFsm)
789 } else {
790 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
791 }
792 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800793 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000794 } else {
795 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
796 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800797 }
798
mpagenko7a592192021-07-28 13:32:00 +0000799 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000800 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000801 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko7a592192021-07-28 13:32:00 +0000802 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000803 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000804 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
805 "GemIwTp-entity-id": loGemPortID})
806 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
807
808 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000809 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300810 meInstance, err := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000811 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300812 if err != nil {
813 logger.Errorw(ctx, "GemIWTP delete failed, aborting uniPonAniConfigFsm!",
814 log.Fields{"device-id": oFsm.deviceID})
815 pConfigAniStateAFsm := oFsm.pAdaptFsm
816 if pConfigAniStateAFsm != nil {
817 oFsm.mutexPLastTxMeInstance.Unlock()
818 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
819 go func(aPAFsm *AdapterFsm) {
820 if aPAFsm != nil && aPAFsm.pFsm != nil {
821 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
822 }
823 }(pConfigAniStateAFsm)
824 return
825 }
826 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000827 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300828 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000829}
830
mpagenkobb47bc22021-04-20 13:29:09 +0000831func (oFsm *uniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
832 oFsm.mutexIsAwaitingResponse.Lock()
833 oFsm.isWaitingForFlowDelete = true
834 oFsm.mutexIsAwaitingResponse.Unlock()
835 select {
836 // maybe be also some outside cancel (but no context modeled for the moment ...)
837 // case <-ctx.Done():
838 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000839 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 +0000840 logger.Warnw(ctx, "uniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
841 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
842 oFsm.mutexIsAwaitingResponse.Lock()
843 oFsm.isWaitingForFlowDelete = false
844 oFsm.mutexIsAwaitingResponse.Unlock()
845 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
846 pConfigAniStateAFsm := oFsm.pAdaptFsm
847 if pConfigAniStateAFsm != nil {
848 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
849 go func(aPAFsm *AdapterFsm) {
850 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300851 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000852 }
853 }(pConfigAniStateAFsm)
854 } else {
855 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
856 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
857 }
858 return
859
860 case success := <-oFsm.waitFlowDeleteChannel:
861 if success {
862 logger.Debugw(ctx, "uniPonAniConfigFsm flow removed info received", log.Fields{
863 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
864 oFsm.mutexIsAwaitingResponse.Lock()
865 oFsm.isWaitingForFlowDelete = false
866 oFsm.mutexIsAwaitingResponse.Unlock()
867 pConfigAniStateAFsm := oFsm.pAdaptFsm
868 if pConfigAniStateAFsm != nil {
869 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
870 go func(aPAFsm *AdapterFsm) {
871 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300872 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000873 }
874 }(pConfigAniStateAFsm)
875 } else {
876 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
877 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
878 }
879 return
880 }
881 // waiting was aborted (probably on external request)
882 logger.Debugw(ctx, "uniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
883 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
884 oFsm.mutexIsAwaitingResponse.Lock()
885 oFsm.isWaitingForFlowDelete = false
886 oFsm.mutexIsAwaitingResponse.Unlock()
887 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
888 pConfigAniStateAFsm := oFsm.pAdaptFsm
889 if pConfigAniStateAFsm != nil {
890 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
891 go func(aPAFsm *AdapterFsm) {
892 if aPAFsm != nil && aPAFsm.pFsm != nil {
893 _ = aPAFsm.pFsm.Event(aniEvReset)
894 }
895 }(pConfigAniStateAFsm)
896 }
897 return
898 }
899}
900
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko7a592192021-07-28 13:32:00 +0000902 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000903 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko7a592192021-07-28 13:32:00 +0000904 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000906 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
907 "GemNCTP-entity-id": loGemPortID})
908 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000909 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300910 meInstance, err := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000911 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300912 if err != nil {
913 logger.Errorw(ctx, "GemNCTP delete failed, aborting uniPonAniConfigFsm!",
914 log.Fields{"device-id": oFsm.deviceID})
915 pConfigAniStateAFsm := oFsm.pAdaptFsm
916 if pConfigAniStateAFsm != nil {
917 oFsm.mutexPLastTxMeInstance.Unlock()
918 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
919 go func(aPAFsm *AdapterFsm) {
920 if aPAFsm != nil && aPAFsm.pFsm != nil {
921 _ = aPAFsm.pFsm.Event(aniEvReset)
922 }
923 }(pConfigAniStateAFsm)
924 return
925 }
926 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000927 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000928 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300929
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800930 // Mark the gem port to be removed for Performance History monitoring
931 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -0700932 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800933 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000934}
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300935func (oFsm *uniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko7a592192021-07-28 13:32:00 +0000936 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300937 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko7a592192021-07-28 13:32:00 +0000938 oFsm.pUniTechProf.mutexTPState.RUnlock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300939 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
940 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
941 "TD-entity-id": loGemPortID})
942
943 oFsm.mutexPLastTxMeInstance.Lock()
944 meInstance, err := oFsm.pOmciCC.sendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
945 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, loGemPortID)
946
947 if err != nil {
948 logger.Errorw(ctx, "TD delete failed - proceed fsm",
949 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
950 pConfigAniStateAFsm := oFsm.pAdaptFsm
951 if pConfigAniStateAFsm != nil {
952 oFsm.mutexPLastTxMeInstance.Unlock()
953 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
954 go func(aPAFsm *AdapterFsm) {
955 if aPAFsm != nil && aPAFsm.pFsm != nil {
956 _ = aPAFsm.pFsm.Event(aniEvReset)
957 }
958 }(pConfigAniStateAFsm)
959 return
960 }
961 }
962 oFsm.pLastTxMeInstance = meInstance
963 oFsm.mutexPLastTxMeInstance.Unlock()
964}
mpagenko8b07c1b2020-11-26 10:36:31 +0000965
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
967 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000968 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
969
970 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
971 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
972 meParams := me.ParamData{
973 EntityID: oFsm.tcont0ID,
974 Attributes: me.AttributeValueMap{
975 "AllocId": unusedTcontAllocID,
976 },
977 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000978 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300979 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000980 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300981 if err != nil {
982 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
983 log.Fields{"device-id": oFsm.deviceID})
984 pConfigAniStateAFsm := oFsm.pAdaptFsm
985 if pConfigAniStateAFsm != nil {
986 oFsm.mutexPLastTxMeInstance.Unlock()
987 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
988 go func(aPAFsm *AdapterFsm) {
989 if aPAFsm != nil && aPAFsm.pFsm != nil {
990 _ = aPAFsm.pFsm.Event(aniEvReset)
991 }
992 }(pConfigAniStateAFsm)
993 return
994 }
995 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000996 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300997 oFsm.mutexPLastTxMeInstance.Unlock()
998
mpagenko8b07c1b2020-11-26 10:36:31 +0000999}
1000
dbainbri4d3a0dc2020-12-02 00:33:42 +00001001func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
1002 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001003 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Mahir Gunyel82b7f872021-07-04 15:53:16 -07001004 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1005 unicastGemCount := 0
1006 for _, gemEntry := range mapGemPortParams {
1007 if !gemEntry.isMulticast {
1008 unicastGemCount++
1009 }
1010 }
1011 if unicastGemCount > 1 {
1012 logger.Debugw(ctx, "uniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1013 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1014 pConfigAniStateAFsm := oFsm.pAdaptFsm
1015 if pConfigAniStateAFsm != nil {
1016 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1017 go func(aPAFsm *AdapterFsm) {
1018 if aPAFsm != nil && aPAFsm.pFsm != nil {
1019 _ = aPAFsm.pFsm.Event(aniEvRemGemDone)
1020 }
1021 }(pConfigAniStateAFsm)
1022 return
1023 }
1024 }
1025 logger.Debugw(ctx, "uniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1026 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001027
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001028 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001029 meInstance, err := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001030 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001031 if err != nil {
1032 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting uniPonAniConfigFsm!",
1033 log.Fields{"device-id": oFsm.deviceID})
1034 pConfigAniStateAFsm := oFsm.pAdaptFsm
1035 if pConfigAniStateAFsm != nil {
1036 oFsm.mutexPLastTxMeInstance.Unlock()
1037 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1038 go func(aPAFsm *AdapterFsm) {
1039 if aPAFsm != nil && aPAFsm.pFsm != nil {
1040 _ = aPAFsm.pFsm.Event(aniEvReset)
1041 }
1042 }(pConfigAniStateAFsm)
1043 return
1044 }
1045 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001046 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001047 oFsm.mutexPLastTxMeInstance.Unlock()
1048
mpagenko8b07c1b2020-11-26 10:36:31 +00001049}
1050
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1052 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001053 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1054
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001055 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001056 meInstance, err := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001057 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001058 if err != nil {
1059 logger.Errorw(ctx, "MBPConfigData delete failed, aborting uniPonAniConfigFsm!",
1060 log.Fields{"device-id": oFsm.deviceID})
1061 pConfigAniStateAFsm := oFsm.pAdaptFsm
1062 if pConfigAniStateAFsm != nil {
1063 oFsm.mutexPLastTxMeInstance.Unlock()
1064 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1065 go func(aPAFsm *AdapterFsm) {
1066 if aPAFsm != nil && aPAFsm.pFsm != nil {
1067 _ = aPAFsm.pFsm.Event(aniEvReset)
1068 }
1069 }(pConfigAniStateAFsm)
1070 return
1071 }
1072 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001073 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001074 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001075}
1076
dbainbri4d3a0dc2020-12-02 00:33:42 +00001077func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1078 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001079 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1080 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001081 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001082 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001083 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +00001084 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001085 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1086 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001087 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001088 }
1089
1090 //let's reset the state machine in order to release all resources now
1091 pConfigAniStateAFsm := oFsm.pAdaptFsm
1092 if pConfigAniStateAFsm != nil {
1093 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1094 go func(aPAFsm *AdapterFsm) {
1095 if aPAFsm != nil && aPAFsm.pFsm != nil {
1096 _ = aPAFsm.pFsm.Event(aniEvReset)
1097 }
1098 }(pConfigAniStateAFsm)
1099 }
1100}
1101
dbainbri4d3a0dc2020-12-02 00:33:42 +00001102func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1103 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001104 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001105
mpagenko18eca9c2021-07-26 11:03:45 +00001106 if oFsm.isChanSet() {
1107 // indicate processing error to the caller (in case there was still some open request)
1108 logger.Debugw(ctx, "uniPonAniConfigFsm processingError on channel", log.Fields{
1109 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1110 //use non-blocking channel send to avoid blocking because of non-existing receiver
1111 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1112 select {
1113 case oFsm.chSuccess <- 0:
1114 default:
1115 logger.Debugw(ctx, "uniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
1116 "device-id": oFsm.deviceID})
1117 }
1118 oFsm.setChanSet(false) //reset the internal channel state
1119 }
1120
mpagenko3dbcdd22020-07-22 07:38:45 +00001121 pConfigAniStateAFsm := oFsm.pAdaptFsm
1122 if pConfigAniStateAFsm != nil {
1123 // abort running message processing
1124 fsmAbortMsg := Message{
1125 Type: TestMsg,
1126 Data: TestMessage{
1127 TestMessageVal: AbortMessageProcessing,
1128 },
1129 }
1130 pConfigAniStateAFsm.commChan <- fsmAbortMsg
1131
1132 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +05301133 go func(aPAFsm *AdapterFsm) {
1134 if aPAFsm != nil && aPAFsm.pFsm != nil {
1135 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001136 }
1137 }(pConfigAniStateAFsm)
1138 }
1139}
1140
dbainbri4d3a0dc2020-12-02 00:33:42 +00001141func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1142 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001143 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001144 oFsm.mutexPLastTxMeInstance.Lock()
1145 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001146 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001147}
1148
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1150 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001151loop:
1152 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001153 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001154 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001155 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301156 message, ok := <-oFsm.pAdaptFsm.commChan
1157 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001158 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301159 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1160 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1161 break loop
1162 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001163 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301164
1165 switch message.Type {
1166 case TestMsg:
1167 msg, _ := message.Data.(TestMessage)
1168 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001170 break loop
1171 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301173 case OMCI:
1174 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301176 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001177 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301178 "message.Type": message.Type})
1179 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001180
Himani Chawla4d908332020-08-31 12:30:20 +05301181 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001182 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301183}
1184
dbainbri4d3a0dc2020-12-02 00:33:42 +00001185func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301186 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1187 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001189 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301190 return
1191 }
1192 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1193 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001194 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001195 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301196 return
1197 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001199 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1200 //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 +00001201 oFsm.mutexPLastTxMeInstance.RLock()
1202 if oFsm.pLastTxMeInstance != nil {
1203 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1204 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1205 // maybe we can use just the same eventName for different state transitions like "forward"
1206 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1207 switch oFsm.pLastTxMeInstance.GetName() {
1208 case "Ieee8021PMapperServiceProfile":
1209 { // let the FSM proceed ...
1210 oFsm.mutexPLastTxMeInstance.RUnlock()
1211 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
1212 }
1213 case "MacBridgePortConfigurationData":
1214 { // let the FSM proceed ...
1215 oFsm.mutexPLastTxMeInstance.RUnlock()
1216 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
1217 }
1218 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1219 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1220 oFsm.mutexPLastTxMeInstance.RUnlock()
1221 oFsm.omciMIdsResponseReceived <- true
1222 }
1223 default:
1224 {
1225 oFsm.mutexPLastTxMeInstance.RUnlock()
1226 logger.Warnw(ctx, "Unsupported ME name received!",
1227 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1228 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001229 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001230 } else {
1231 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001232 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001233 } else {
1234 oFsm.mutexPLastTxMeInstance.RUnlock()
1235 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001236 }
1237 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001238 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1239 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301240 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1241 return
1242 }
Himani Chawla4d908332020-08-31 12:30:20 +05301243}
Mahir Gunyel01034b62021-06-29 11:25:09 -07001244func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
1245 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1246 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1247 oFsm.mutexPLastTxMeInstance.RLock()
1248 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1249 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1250 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1251 switch oFsm.pLastTxMeInstance.GetName() {
1252 case "TCont":
1253 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1254 //We should revert DB
1255 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1256 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1257 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
1258 if pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false); pDevEntry != nil {
1259 pDevEntry.freeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
1260 } else {
1261 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1262 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1263 }
1264 }
1265 default:
1266 logger.Warnw(ctx, "Unsupported ME name received with error!",
1267 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1268 }
1269 }
1270}
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301272 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1273 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001274 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001275 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301276 return
1277 }
1278 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1279 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001280 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001281 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301282 return
1283 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001284 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301285 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001287 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301288 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001289
Mahir Gunyel01034b62021-06-29 11:25:09 -07001290 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301291 return
1292 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001293 oFsm.mutexPLastTxMeInstance.RLock()
1294 if oFsm.pLastTxMeInstance != nil {
1295 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1296 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1297 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1298 // if, then something like:
1299 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301300
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001301 switch oFsm.pLastTxMeInstance.GetName() {
1302 case "TCont":
1303 { // let the FSM proceed ...
1304 oFsm.mutexPLastTxMeInstance.RUnlock()
1305 if oFsm.requestEventOffset == 0 { //from TCont config request
1306 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
1307 } else { // from T-Cont reset request
1308 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
1309 }
1310 }
1311 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1312 { // let the PrioQueue init proceed by stopping the wait function
1313 oFsm.mutexPLastTxMeInstance.RUnlock()
1314 oFsm.omciMIdsResponseReceived <- true
1315 }
1316 case "Ieee8021PMapperServiceProfile":
1317 { // let the FSM proceed ...
1318 oFsm.mutexPLastTxMeInstance.RUnlock()
1319 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
1320 }
1321 default:
1322 {
1323 oFsm.mutexPLastTxMeInstance.RUnlock()
1324 logger.Warnw(ctx, "Unsupported ME name received!",
1325 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001326 }
Himani Chawla4d908332020-08-31 12:30:20 +05301327 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001328 } else {
1329 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301330 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001331 } else {
1332 oFsm.mutexPLastTxMeInstance.RUnlock()
1333 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301334 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001335}
1336
dbainbri4d3a0dc2020-12-02 00:33:42 +00001337func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001338 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1339 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001341 log.Fields{"device-id": oFsm.deviceID})
1342 return
1343 }
1344 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1345 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001346 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001347 log.Fields{"device-id": oFsm.deviceID})
1348 return
1349 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001350 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001351 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001352 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001353 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1354 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1355 // store error for mgmt display?
1356 return
1357 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001358 oFsm.mutexPLastTxMeInstance.RLock()
1359 if oFsm.pLastTxMeInstance != nil {
1360 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1361 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1362 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1363 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001364
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001365 switch oFsm.pLastTxMeInstance.GetName() {
1366 case "GemInterworkingTerminationPoint":
1367 { // let the FSM proceed ...
1368 oFsm.mutexPLastTxMeInstance.RUnlock()
1369 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
1370 }
1371 case "GemPortNetworkCtp":
1372 { // let the FSM proceed ...
1373 oFsm.mutexPLastTxMeInstance.RUnlock()
1374 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
1375 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001376 case "TrafficDescriptor":
1377 { // let the FSM proceed ...
1378 oFsm.mutexPLastTxMeInstance.RUnlock()
1379 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemTdResp)
1380 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001381 case "Ieee8021PMapperServiceProfile":
1382 { // let the FSM proceed ...
1383 oFsm.mutexPLastTxMeInstance.RUnlock()
1384 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
1385 }
1386 case "MacBridgePortConfigurationData":
1387 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1388 oFsm.mutexPLastTxMeInstance.RUnlock()
1389 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
1390 }
1391 default:
1392 {
1393 oFsm.mutexPLastTxMeInstance.RUnlock()
1394 logger.Warnw(ctx, "Unsupported ME name received!",
1395 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1396 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001397 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001398 } else {
1399 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001400 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001401 } else {
1402 oFsm.mutexPLastTxMeInstance.RUnlock()
1403 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001404 }
1405}
1406
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
1408 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001409 "msgType": msg.OmciMsg.MessageType})
1410
1411 switch msg.OmciMsg.MessageType {
1412 case omci.CreateResponseType:
1413 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001414 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301415
mpagenko3dbcdd22020-07-22 07:38:45 +00001416 } //CreateResponseType
1417 case omci.SetResponseType:
1418 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001420
mpagenko3dbcdd22020-07-22 07:38:45 +00001421 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001422 case omci.DeleteResponseType:
1423 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001424 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001425
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001426 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001427 default:
1428 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001430 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001431 return
1432 }
1433 }
1434}
1435
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001437 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1438 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001440 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1441 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001442 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001443 meParams := me.ParamData{
1444 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1445 Attributes: me.AttributeValueMap{
1446 "PortId": gemPortAttribs.gemPortID,
1447 "TContPointer": oFsm.tcont0ID,
1448 "Direction": gemPortAttribs.direction,
1449 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1450 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1451 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1452 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1453 },
1454 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001455 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001456 meInstance, err := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001457 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001458 if err != nil {
1459 oFsm.mutexPLastTxMeInstance.Unlock()
1460 logger.Errorw(ctx, "GemNCTPVar create failed, aborting uniPonAniConfigFsm!",
1461 log.Fields{"device-id": oFsm.deviceID})
1462 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1463 return
1464 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001465 //accept also nil as (error) return value for writing to LastTx
1466 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001467 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001468 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001469 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001470 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001471 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001472 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001473 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301474 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001475 return
1476 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001477 // Mark the gem port to be added for Performance History monitoring
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001478 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -07001479 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001480 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001481 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001482
1483 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301485 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001486}
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001487func (oFsm *uniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
1488 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1489 if gemPortAttribs.isMulticast {
1490 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1491 return true
1492 }
1493 }
1494 return false
1495}
mpagenko3dbcdd22020-07-22 07:38:45 +00001496
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001498 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1499 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001501 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1502 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001503 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001504
ozgecanetsia4b232302020-11-11 10:58:10 +03001505 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1506 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001507
1508 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001509 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001510 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001511 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001512 "InterworkingOption": 0, // Don't Care
1513 "ServiceProfilePointer": 0, // Don't Care
1514 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001515 },
1516 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001517 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1518 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1519 continue
1520 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001521 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001522 meInstance, err := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsia4b232302020-11-11 10:58:10 +03001523 true, oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001524 if err != nil {
1525 oFsm.mutexPLastTxMeInstance.Unlock()
1526 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting uniPonAniConfigFsm!",
1527 log.Fields{"device-id": oFsm.deviceID})
1528 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1529 return
1530
1531 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001532 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001533 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001534 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001535 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001536 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001537 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001538 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1539 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1540 return
1541 }
1542 ipv4MulticastTable := make([]uint8, 12)
1543 //Gem Port ID
1544 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1545 //Secondary Key
1546 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1547 // Multicast IP range start This is the 224.0.0.1 address
1548 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1549 // MulticastIp range stop
1550 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1551
1552 meIPV4MCTableParams := me.ParamData{
1553 EntityID: gemPortAttribs.multicastGemID,
1554 Attributes: me.AttributeValueMap{
1555 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1556 },
1557 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001558 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001559 meIPV4MCTableInstance, err := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001560 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001561 if err != nil {
1562 oFsm.mutexPLastTxMeInstance.Unlock()
1563 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting uniPonAniConfigFsm!",
1564 log.Fields{"device-id": oFsm.deviceID})
1565 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1566 return
1567 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001568 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001569 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001570
1571 } else {
1572 meParams := me.ParamData{
1573 EntityID: gemPortAttribs.gemPortID,
1574 Attributes: me.AttributeValueMap{
1575 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1576 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1577 "ServiceProfilePointer": oFsm.mapperSP0ID,
1578 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1579 "GalProfilePointer": galEthernetEID,
1580 },
1581 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001582 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001583 meInstance, err := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsia4b232302020-11-11 10:58:10 +03001584 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001585 if err != nil {
1586 oFsm.mutexPLastTxMeInstance.Unlock()
1587 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting uniPonAniConfigFsm!",
1588 log.Fields{"device-id": oFsm.deviceID})
1589 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1590 return
1591 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001592 //accept also nil as (error) return value for writing to LastTx
1593 // - this avoids misinterpretation of new received OMCI messages
1594 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001595 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001596 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001597 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001599 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001601 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301602 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001603 return
1604 }
1605 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001606
1607 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301609 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001610}
1611
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001613 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1614 if oFsm.tcontSetBefore {
1615 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1616 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
1617 "uni-id": oFsm.pOnuUniPort.uniID,
1618 "techProfile-id": oFsm.techProfileID})
1619 go func(aPAFsm *AdapterFsm) {
1620 if aPAFsm != nil && aPAFsm.pFsm != nil {
1621 _ = aPAFsm.pFsm.Event(aniEvRxPrioqsResp)
1622 }
1623 }(oFsm.pAdaptFsm)
1624 return
1625 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001626 const cu16StrictPrioWeight uint16 = 0xFFFF
1627 //find all upstream PrioQueues related to this T-Cont
1628 loQueueMap := ordered_map.NewOrderedMap()
1629 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001630 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001632 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1633 "prioString": gemPortAttribs.pbitString})
1634 continue
1635 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001636 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301637 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001638 //key does not yet exist
1639 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1640 }
1641 } else {
1642 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1643 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001644 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001645
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001646 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1647 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1648 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1649 // or even be finished without correct SP/WRR setting
1650
1651 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1652 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1653 // even though its T-Cont seems to be wrong ...
1654 loTrafficSchedulerEID := 0x8000
1655 //for all found queues
1656 iter := loQueueMap.IterFunc()
1657 for kv, ok := iter(); ok; kv, ok = iter() {
1658 queueIndex := (kv.Key).(uint16)
1659 meParams := me.ParamData{
1660 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301661 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001662 }
1663 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1664 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001666 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001667 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001668 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1669 } else {
1670 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001671 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001672 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1673 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001674 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001675 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1676 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1677 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001678 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001679 meInstance, err := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001680 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001681 if err != nil {
1682 oFsm.mutexPLastTxMeInstance.Unlock()
1683 logger.Errorw(ctx, "PrioQueueVar set failed, aborting uniPonAniConfigFsm!",
1684 log.Fields{"device-id": oFsm.deviceID})
1685 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1686 return
1687 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001688 //accept also nil as (error) return value for writing to LastTx
1689 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001690 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001691 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001692
1693 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001694 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001695 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001697 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301698 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001699 return
1700 }
1701
1702 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1703 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1704 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1705 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1706
1707 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001708
1709 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301711 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001712}
1713
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001715 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001716 if oFsm.isCanceled {
1717 // FSM already canceled before entering wait
1718 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
1719 oFsm.mutexIsAwaitingResponse.Unlock()
1720 return fmt.Errorf(cErrWaitAborted)
1721 }
mpagenko7d6bb022021-03-11 15:07:55 +00001722 oFsm.isAwaitingResponse = true
1723 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001724 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301725 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001726 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001727 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001728 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 +00001729 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001730 oFsm.mutexIsAwaitingResponse.Lock()
1731 oFsm.isAwaitingResponse = false
1732 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001733 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001734 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301735 if success {
mpagenkocf48e452021-04-23 09:23:00 +00001736 logger.Debugw(ctx, "uniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001737 oFsm.mutexIsAwaitingResponse.Lock()
1738 oFsm.isAwaitingResponse = false
1739 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001740 return nil
1741 }
mpagenko7d6bb022021-03-11 15:07:55 +00001742 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00001743 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001744 oFsm.mutexIsAwaitingResponse.Lock()
1745 oFsm.isAwaitingResponse = false
1746 oFsm.mutexIsAwaitingResponse.Unlock()
1747 return fmt.Errorf(cErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001748 }
1749}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001750
1751func (oFsm *uniPonAniConfigFsm) setChanSet(flagValue bool) {
1752 oFsm.mutexChanSet.Lock()
1753 oFsm.chanSet = flagValue
1754 oFsm.mutexChanSet.Unlock()
1755}
1756
1757func (oFsm *uniPonAniConfigFsm) isChanSet() bool {
1758 oFsm.mutexChanSet.RLock()
1759 flagValue := oFsm.chanSet
1760 oFsm.mutexChanSet.RUnlock()
1761 return flagValue
1762}