blob: 340dd1bc0a01965873175b667e58dcd1623aa641 [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
mpagenko7d6bb022021-03-11 15:07:55 +000026 "sync"
mpagenko3dbcdd22020-07-22 07:38:45 +000027 "time"
28
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000029 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000031 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070033 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000034 //ic "github.com/opencord/voltha-protos/v4/go/inter_container"
35 //"github.com/opencord/voltha-protos/v4/go/openflow_13"
36 //"github.com/opencord/voltha-protos/v4/go/voltha"
mpagenko3dbcdd22020-07-22 07:38:45 +000037)
38
mpagenko1cc3cb42020-07-27 15:24:38 +000039const (
40 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000041 aniEvStart = "aniEvStart"
42 aniEvStartConfig = "aniEvStartConfig"
43 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
44 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
45 aniEvRxTcontsResp = "aniEvRxTcontsResp"
46 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
47 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
48 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
49 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
50 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080051 aniEvWaitFlowRem = "aniEvWaitFlowRem"
52 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000053 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
54 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030055 aniEvRxRemTdResp = "aniEvRxRemTdResp"
mpagenko8b07c1b2020-11-26 10:36:31 +000056 aniEvRemTcontPath = "aniEvRemTcontPath"
57 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
58 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
59 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
60 aniEvTimeoutSimple = "aniEvTimeoutSimple"
61 aniEvTimeoutMids = "aniEvTimeoutMids"
62 aniEvReset = "aniEvReset"
63 aniEvRestart = "aniEvRestart"
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +000064 aniEvSkipOmciConfig = "aniEvSkipOmciConfig"
mpagenko1cc3cb42020-07-27 15:24:38 +000065)
66const (
67 // states of config PON ANI port FSM
68 aniStDisabled = "aniStDisabled"
69 aniStStarting = "aniStStarting"
70 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
71 aniStCreatingMBPCD = "aniStCreatingMBPCD"
72 aniStSettingTconts = "aniStSettingTconts"
73 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
74 aniStCreatingGemIWs = "aniStCreatingGemIWs"
75 aniStSettingPQs = "aniStSettingPQs"
76 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
77 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000078 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080079 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000080 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030081 aniStRemovingTD = "aniStRemovingTD"
mpagenko8b07c1b2020-11-26 10:36:31 +000082 aniStResetTcont = "aniStResetTcont"
83 aniStRemDot1PMapper = "aniStRemDot1PMapper"
84 aniStRemAniBPCD = "aniStRemAniBPCD"
85 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000086 aniStResetting = "aniStResetting"
87)
Holger Hildebrandt10d98192021-01-27 15:29:31 +000088const cAniFsmIdleState = aniStConfigDone
mpagenko1cc3cb42020-07-27 15:24:38 +000089
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000090type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030091 gemPortID uint16
92 upQueueID uint16
93 downQueueID uint16
94 direction uint8
95 qosPolicy string
96 weight uint8
97 pbitString string
98 isMulticast bool
99 multicastGemID uint16
100 staticACL string
101 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000102}
103
Himani Chawla6d2ae152020-09-02 13:11:20 +0530104//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
105type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000106 pDeviceHandler *deviceHandler
107 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530108 pOmciCC *omciCC
109 pOnuUniPort *onuUniPort
110 pUniTechProf *onuUniTechProf
111 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800112 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000113 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000114 requestEvent OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000115 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000116 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000117 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530118 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000119 pAdaptFsm *AdapterFsm
120 chSuccess chan<- uint8
121 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000122 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000123 chanSet bool
124 mapperSP0ID uint16
125 macBPCD0ID uint16
126 tcont0ID uint16
127 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000128 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000129 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000130 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000131 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000132 isWaitingForFlowDelete bool
133 waitFlowDeleteChannel chan bool
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700134 tcontSetBefore bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000135}
136
Himani Chawla6d2ae152020-09-02 13:11:20 +0530137//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000138func newUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800139 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000140 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530141 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000142 pDeviceHandler: apDeviceHandler,
143 deviceID: apDeviceHandler.deviceID,
144 pOmciCC: apDevOmciCC,
145 pOnuUniPort: apUniPort,
146 pUniTechProf: apUniTechProf,
147 pOnuDB: apOnuDB,
148 techProfileID: aTechProfileID,
149 requestEvent: aRequestEvent,
150 chanSet: false,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700151 tcontSetBefore: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000152 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000153 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
mpagenkobb47bc22021-04-20 13:29:09 +0000154 instFsm.waitFlowDeleteChannel = make(chan bool)
mpagenko8b07c1b2020-11-26 10:36:31 +0000155
mpagenko01e726e2020-10-23 09:45:29 +0000156 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000157 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000158 logger.Errorw(ctx, "uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000159 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000160 return nil
161 }
162
163 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000164 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000165 fsm.Events{
166
mpagenko1cc3cb42020-07-27 15:24:38 +0000167 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000168
169 //Note: .1p-Mapper and MBPCD might also have multi instances (per T-Cont) - by now only one 1 T-Cont considered!
mpagenko1cc3cb42020-07-27 15:24:38 +0000170 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000171 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000172 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
173 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000174 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000175 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000176 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000177 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000178 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000179 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000180 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000181
mpagenko8b07c1b2020-11-26 10:36:31 +0000182 //for removing Gem related resources
183 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800184 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
185 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000186 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300187 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
188 {Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStConfigDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000189
190 //for removing TCONT related resources
191 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
192 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStRemDot1PMapper},
193 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
194 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
195
196 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300197 aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000198 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000199 {Name: aniEvTimeoutMids, Src: []string{
200 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000201
mpagenko1cc3cb42020-07-27 15:24:38 +0000202 // exceptional treatment for all states except aniStResetting
203 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
204 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300205 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000206 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000207 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000208 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000209 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000210 },
211
212 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000213 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
214 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
215 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
216 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
217 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
218 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
219 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
220 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
221 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
222 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
223 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000224 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000225 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300226 ("enter_" + aniStRemovingTD): func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
228 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
229 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
230 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
231 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
232 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000233 },
234 )
235 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000236 logger.Errorw(ctx, "uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000237 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000238 return nil
239 }
240
dbainbri4d3a0dc2020-12-02 00:33:42 +0000241 logger.Debugw(ctx, "uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000242 return instFsm
243}
244
Himani Chawla6d2ae152020-09-02 13:11:20 +0530245//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
246func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000247 oFsm.chSuccess = aChSuccess
248 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000249 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000250}
251
mpagenko7d6bb022021-03-11 15:07:55 +0000252//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000253func (oFsm *uniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
254 //early indication about started reset processing
255 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000256 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000257 oFsm.mutexIsAwaitingResponse.Lock()
258 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000259 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000260 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
261 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
262 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000263 //use channel to indicate that the response waiting shall be aborted
264 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000265 } else {
266 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000267 }
mpagenkocf48e452021-04-23 09:23:00 +0000268
269 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000270 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000271 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000272 //use channel to indicate that the response waiting shall be aborted
273 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000274 } else {
275 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000276 }
mpagenkocf48e452021-04-23 09:23:00 +0000277
mpagenko7d6bb022021-03-11 15:07:55 +0000278 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
279 pAdaptFsm := oFsm.pAdaptFsm
280 if pAdaptFsm != nil {
281 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
282 go func(aPAFsm *AdapterFsm) {
283 if aPAFsm.pFsm != nil {
284 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
285 }
286 }(pAdaptFsm)
287 }
mpagenko73143992021-04-09 15:17:10 +0000288
289 //wait for completion of possibly ongoing techprofile config/remove requests to avoid
290 // access conflicts on internal data by next needed data clearance
291 //activity should be aborted in short time if running with FSM due to above FSM reset
292 // or finished without FSM dependency in short time
293 oFsm.pUniTechProf.lockTpProcMutex()
294 defer oFsm.pUniTechProf.unlockTpProcMutex()
295 //remove all TechProf related internal data to allow for new configuration
296 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000297}
298
Mahir Gunyel6781f962021-05-16 23:30:08 -0700299//nolint: gocyclo
300//TODO:visit here for refactoring for gocyclo
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530302 if aPAFsm != nil && aPAFsm.pFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700303 var err error
304 oFsm.mapperSP0ID, err = generateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
305 if err != nil {
306 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
307 "techProfileID": oFsm.techProfileID, "error": err})
308 return
309 }
310 oFsm.macBPCD0ID, err = generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
311 if err != nil {
312 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
313 "techProfileID": oFsm.techProfileID, "error": err})
314 return
315 }
316 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
317 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
318 "macBpNo": oFsm.pOnuUniPort.macBpNo, "techProfileID": oFsm.techProfileID})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700319 pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false)
320 if pDevEntry == nil {
321 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800322 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530323 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700324 tcontInstID, tcontAlreadyExist, err := pDevEntry.allocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
325 if err != nil {
326 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
327 if oFsm.chanSet {
328 // indicate processing error/abort to the caller
329 oFsm.chSuccess <- 0
330 oFsm.chanSet = false //reset the internal channel state
331 }
332 //reset the state machine to enable usage on subsequent requests
333 _ = aPAFsm.pFsm.Event(aniEvReset)
334 return
335 }
336 oFsm.tcont0ID = tcontInstID
337 oFsm.tcontSetBefore = tcontAlreadyExist
338 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
339 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
340 "tcontAlreadyExist": tcontAlreadyExist,
341 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800342
343 // Access critical state with lock
344 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000345 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
346 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
Girish Gowdra041dcb32020-11-16 16:54:30 -0800347 oFsm.pUniTechProf.mutexTPState.Unlock()
348
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800350 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300351 loGemPortAttribs := ponAniGemPortAttribs{}
352
Himani Chawla26e555c2020-08-31 12:30:20 +0530353 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
354
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530356
357 loGemPortAttribs.gemPortID = gemEntry.gemPortID
358 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
359 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
360 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
361 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
362
363 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
364 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
365 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
366 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
367 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
368 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
369
370 usQueueFound := false
371 dsQueueFound := false
372 for _, mgmtEntityID := range queueInstKeys {
373 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
374 returnVal := meAttributes["RelatedPort"]
375 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530376 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 if relatedPort == usQrelPortMask {
378 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000380 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 usQueueFound = true
382 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
383 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000385 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 dsQueueFound = true
387 }
388 if usQueueFound && dsQueueFound {
389 break
390 }
391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000392 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 }
394 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000395 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
397 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000399 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 }
401 }
402 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000403 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 }
405 loGemPortAttribs.direction = gemEntry.direction
406 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
407 loGemPortAttribs.weight = gemEntry.queueWeight
408 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300409
ozgecanetsia4b232302020-11-11 10:58:10 +0300410 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300411 //TODO this might effectively ignore the for loop starting at line 316
412 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300413 loGemPortAttribs.isMulticast = true
414 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
415 loGemPortAttribs.staticACL = gemEntry.staticACL
416 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530417
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300419 "gemPortID": loGemPortAttribs.gemPortID,
420 "isMulticast": loGemPortAttribs.isMulticast,
421 "multicastGemID": loGemPortAttribs.multicastGemID,
422 "staticACL": loGemPortAttribs.staticACL,
423 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000424 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300425 })
426
427 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300429 "gemPortID": loGemPortAttribs.gemPortID,
430 "upQueueID": loGemPortAttribs.upQueueID,
431 "downQueueID": loGemPortAttribs.downQueueID,
432 "pbitString": loGemPortAttribs.pbitString,
433 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000434 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300435 })
436 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530437
438 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
439 }
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000440 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
441 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
442 } else {
443 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
444 _ = aPAFsm.pFsm.Event(aniEvSkipOmciConfig)
445 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530446 }
447}
448
dbainbri4d3a0dc2020-12-02 00:33:42 +0000449func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
450 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000451 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000452 // in case the used channel is not yet defined (can be re-used after restarts)
453 if oFsm.omciMIdsResponseReceived == nil {
454 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000455 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000456 } else {
457 // as we may 're-use' this instance of FSM and the connected channel
458 // make sure there is no 'lingering' request in the already existing channel:
459 // (simple loop sufficient as we are the only receiver)
460 for len(oFsm.omciMIdsResponseReceived) > 0 {
461 <-oFsm.omciMIdsResponseReceived
462 }
463 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000464 //ensure internal slices are empty (which might be set from previous run) - release memory
465 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000466 oFsm.mutexIsAwaitingResponse.Lock()
467 //reset the canceled state possibly existing from previous reset
468 oFsm.isCanceled = false
469 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000470
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000471 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000473
474 //let the state machine run forward from here directly
475 pConfigAniStateAFsm := oFsm.pAdaptFsm
476 if pConfigAniStateAFsm != nil {
477 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000479
mpagenko3dbcdd22020-07-22 07:38:45 +0000480 }
481}
482
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
484 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000485 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000486 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
487 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000488 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300489 meInstance, err := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000490 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300491 if err != nil {
492 logger.Errorw(ctx, "Dot1PMapper create failed, aborting uniPonAniConfigFsm!",
493 log.Fields{"device-id": oFsm.deviceID})
494 pConfigAniStateAFsm := oFsm.pAdaptFsm
495 if pConfigAniStateAFsm != nil {
496 oFsm.mutexPLastTxMeInstance.Unlock()
497 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
498 go func(aPAFsm *AdapterFsm) {
499 if aPAFsm != nil && aPAFsm.pFsm != nil {
500 _ = aPAFsm.pFsm.Event(aniEvReset)
501 }
502 }(pConfigAniStateAFsm)
503 return
504 }
505 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000506 //accept also nil as (error) return value for writing to LastTx
507 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000508 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300509 oFsm.mutexPLastTxMeInstance.Unlock()
510
mpagenko3dbcdd22020-07-22 07:38:45 +0000511}
512
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
514 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000515 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
516 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000517 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000518 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
519 meParams := me.ParamData{
520 EntityID: oFsm.macBPCD0ID,
521 Attributes: me.AttributeValueMap{
522 "BridgeIdPointer": bridgePtr,
523 "PortNum": 0xFF, //fixed unique ANI side indication
524 "TpType": 3, //for .1PMapper
525 "TpPointer": oFsm.mapperSP0ID,
526 },
527 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000528 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300529 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000530 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300531 if err != nil {
532 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting uniPonAniConfigFsm!",
533 log.Fields{"device-id": oFsm.deviceID})
534 pConfigAniStateAFsm := oFsm.pAdaptFsm
535 if pConfigAniStateAFsm != nil {
536 oFsm.mutexPLastTxMeInstance.Unlock()
537 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
538 go func(aPAFsm *AdapterFsm) {
539 if aPAFsm != nil && aPAFsm.pFsm != nil {
540 _ = aPAFsm.pFsm.Event(aniEvReset)
541 }
542 }(pConfigAniStateAFsm)
543 return
544 }
545 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000546 //accept also nil as (error) return value for writing to LastTx
547 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000548 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300549 oFsm.mutexPLastTxMeInstance.Unlock()
550
mpagenko3dbcdd22020-07-22 07:38:45 +0000551}
552
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
554 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000555 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
556 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700557 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
558 "tcontExist": oFsm.tcontSetBefore})
559 //If tcont was set before, then no need to set it again. Let state machine to proceed.
560 if oFsm.tcontSetBefore {
561 go func(aPAFsm *AdapterFsm) {
562 if aPAFsm != nil && aPAFsm.pFsm != nil {
563 _ = aPAFsm.pFsm.Event(aniEvRxTcontsResp)
564 }
565 }(oFsm.pAdaptFsm)
566 return
567 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000568 meParams := me.ParamData{
569 EntityID: oFsm.tcont0ID,
570 Attributes: me.AttributeValueMap{
571 "AllocId": oFsm.alloc0ID,
572 },
573 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000574 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300575 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000576 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300577 if err != nil {
578 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
579 log.Fields{"device-id": oFsm.deviceID})
580 pConfigAniStateAFsm := oFsm.pAdaptFsm
581 if pConfigAniStateAFsm != nil {
582 oFsm.mutexPLastTxMeInstance.Unlock()
583 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
584 go func(aPAFsm *AdapterFsm) {
585 if aPAFsm != nil && aPAFsm.pFsm != nil {
586 _ = aPAFsm.pFsm.Event(aniEvReset)
587 }
588 }(pConfigAniStateAFsm)
589 return
590 }
591 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000592 //accept also nil as (error) return value for writing to LastTx
593 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000594 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300595 oFsm.mutexPLastTxMeInstance.Unlock()
596
mpagenko3dbcdd22020-07-22 07:38:45 +0000597}
598
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
600 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000601 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000602 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000603}
604
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
606 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000607 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000609}
610
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
612 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000613 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000615}
616
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300618
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000620 "toGemIw": 1024, /* cmp above */
621 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000622
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000624 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000625 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000626
mpagenko3dbcdd22020-07-22 07:38:45 +0000627 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000628 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530629 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000630 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000631
632 //assign the GemPorts according to the configured Prio
633 var loPrioGemPortArray [8]uint16
634 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300635 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300637 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
638 "prioString": gemPortAttribs.pbitString})
639 continue
640 }
641 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300643 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
644 "prioString": gemPortAttribs.pbitString})
645 continue
646 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000647 for i := 0; i < 8; i++ {
648 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
649 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
650 if prio == 1 { // Check this p-bit is set
651 if loPrioGemPortArray[i] == 0 {
652 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000655 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000656 "SetGemPort": loPrioGemPortArray[i]})
657 }
658 }
659 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000661 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000662 "prioString": gemPortAttribs.pbitString, "position": i})
663 }
664
665 }
666 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300667
ozgecanetsia4b232302020-11-11 10:58:10 +0300668 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530669 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300670 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530671 if value != 0 {
672 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530673 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000675 "for Prio": index,
676 "IwPtr": strconv.FormatInt(int64(value), 16),
677 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300678 } else {
679 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000680 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
681 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300682 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530683 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000684 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300685 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000686 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
687 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300688 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530689
690 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000692 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300693 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
694 // 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 +0000695 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300696 //pConfigAniStateAFsm := oFsm.pAdaptFsm
697 //if pConfigAniStateAFsm != nil {
698 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
699 // go func(aPAFsm *AdapterFsm) {
700 // if aPAFsm != nil && aPAFsm.pFsm != nil {
701 // _ = aPAFsm.pFsm.Event(aniEvReset)
702 // }
703 // }(pConfigAniStateAFsm)
704 //}
705 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000706 pConfigAniStateAFsm := oFsm.pAdaptFsm
707 if pConfigAniStateAFsm != nil {
708 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530709 go func(aPAFsm *AdapterFsm) {
710 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300711 _ = aPAFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000712 }
713 }(pConfigAniStateAFsm)
714 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300715 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000716 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300717 meInstance, err := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300718 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300719 if err != nil {
720 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting uniPonAniConfigFsm!",
721 log.Fields{"device-id": oFsm.deviceID})
722 pConfigAniStateAFsm := oFsm.pAdaptFsm
723 if pConfigAniStateAFsm != nil {
724 oFsm.mutexPLastTxMeInstance.Unlock()
725 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
726 go func(aPAFsm *AdapterFsm) {
727 if aPAFsm != nil && aPAFsm.pFsm != nil {
728 _ = aPAFsm.pFsm.Event(aniEvReset)
729 }
730 }(pConfigAniStateAFsm)
731 return
732 }
733 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300734 //accept also nil as (error) return value for writing to LastTx
735 // - this avoids misinterpretation of new received OMCI messages
736 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300737 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000738 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000739}
740
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
742 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000743 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000744 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800745 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000746 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
747 //use DeviceHandler event notification directly
748 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
749 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
750 // but only in case the techProfile was configured (not deleted)
751 if oFsm.requestEventOffset == 0 {
752 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
753 }
754 } else {
755 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000756 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000757 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000758 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000760 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
761 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000762 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000763 }
mpagenko01e726e2020-10-23 09:45:29 +0000764
765 //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 +0000766}
767
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenkoa23a6292021-02-23 10:40:10 +0000769 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000770 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
771 select {
772 case <-oFsm.waitFlowDeleteChannel:
773 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
774 default:
775 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000776
777 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID] != nil {
778 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
779 oFsm.pUniTechProf.mutexTPState.Unlock()
780 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
781 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
782 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
783 pConfigAniStateAFsm := oFsm.pAdaptFsm
784 if pConfigAniStateAFsm != nil {
785 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
786 go func(aPAFsm *AdapterFsm) {
787 if aPAFsm != nil && aPAFsm.pFsm != nil {
788 _ = aPAFsm.pFsm.Event(aniEvWaitFlowRem)
789 }
790 }(pConfigAniStateAFsm)
791 } else {
792 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
793 }
794 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800795 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000796 } else {
797 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
798 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800799 }
800
mpagenko8b07c1b2020-11-26 10:36:31 +0000801 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000802 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
803 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000805 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
806 "GemIwTp-entity-id": loGemPortID})
807 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
808
809 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000810 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300811 meInstance, err := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000812 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300813 if err != nil {
814 logger.Errorw(ctx, "GemIWTP delete failed, aborting uniPonAniConfigFsm!",
815 log.Fields{"device-id": oFsm.deviceID})
816 pConfigAniStateAFsm := oFsm.pAdaptFsm
817 if pConfigAniStateAFsm != nil {
818 oFsm.mutexPLastTxMeInstance.Unlock()
819 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
820 go func(aPAFsm *AdapterFsm) {
821 if aPAFsm != nil && aPAFsm.pFsm != nil {
822 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
823 }
824 }(pConfigAniStateAFsm)
825 return
826 }
827 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000828 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300829 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000830}
831
mpagenkobb47bc22021-04-20 13:29:09 +0000832func (oFsm *uniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
833 oFsm.mutexIsAwaitingResponse.Lock()
834 oFsm.isWaitingForFlowDelete = true
835 oFsm.mutexIsAwaitingResponse.Unlock()
836 select {
837 // maybe be also some outside cancel (but no context modeled for the moment ...)
838 // case <-ctx.Done():
839 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000840 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 +0000841 logger.Warnw(ctx, "uniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
842 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
843 oFsm.mutexIsAwaitingResponse.Lock()
844 oFsm.isWaitingForFlowDelete = false
845 oFsm.mutexIsAwaitingResponse.Unlock()
846 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
847 pConfigAniStateAFsm := oFsm.pAdaptFsm
848 if pConfigAniStateAFsm != nil {
849 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
850 go func(aPAFsm *AdapterFsm) {
851 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300852 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000853 }
854 }(pConfigAniStateAFsm)
855 } else {
856 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
857 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
858 }
859 return
860
861 case success := <-oFsm.waitFlowDeleteChannel:
862 if success {
863 logger.Debugw(ctx, "uniPonAniConfigFsm flow removed info received", log.Fields{
864 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
865 oFsm.mutexIsAwaitingResponse.Lock()
866 oFsm.isWaitingForFlowDelete = false
867 oFsm.mutexIsAwaitingResponse.Unlock()
868 pConfigAniStateAFsm := oFsm.pAdaptFsm
869 if pConfigAniStateAFsm != nil {
870 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
871 go func(aPAFsm *AdapterFsm) {
872 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300873 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000874 }
875 }(pConfigAniStateAFsm)
876 } else {
877 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
878 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
879 }
880 return
881 }
882 // waiting was aborted (probably on external request)
883 logger.Debugw(ctx, "uniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
884 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
885 oFsm.mutexIsAwaitingResponse.Lock()
886 oFsm.isWaitingForFlowDelete = false
887 oFsm.mutexIsAwaitingResponse.Unlock()
888 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
889 pConfigAniStateAFsm := oFsm.pAdaptFsm
890 if pConfigAniStateAFsm != nil {
891 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
892 go func(aPAFsm *AdapterFsm) {
893 if aPAFsm != nil && aPAFsm.pFsm != nil {
894 _ = aPAFsm.pFsm.Event(aniEvReset)
895 }
896 }(pConfigAniStateAFsm)
897 }
898 return
899 }
900}
901
dbainbri4d3a0dc2020-12-02 00:33:42 +0000902func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000903 oFsm.pUniTechProf.mutexTPState.Lock()
904 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
905 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000906 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000907 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
908 "GemNCTP-entity-id": loGemPortID})
909 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000910 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300911 meInstance, err := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000912 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300913 if err != nil {
914 logger.Errorw(ctx, "GemNCTP delete failed, aborting uniPonAniConfigFsm!",
915 log.Fields{"device-id": oFsm.deviceID})
916 pConfigAniStateAFsm := oFsm.pAdaptFsm
917 if pConfigAniStateAFsm != nil {
918 oFsm.mutexPLastTxMeInstance.Unlock()
919 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
920 go func(aPAFsm *AdapterFsm) {
921 if aPAFsm != nil && aPAFsm.pFsm != nil {
922 _ = aPAFsm.pFsm.Event(aniEvReset)
923 }
924 }(pConfigAniStateAFsm)
925 return
926 }
927 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000928 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000929 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300930
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800931 // Mark the gem port to be removed for Performance History monitoring
932 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -0700933 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800934 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000935}
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300936func (oFsm *uniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
937 oFsm.pUniTechProf.mutexTPState.Lock()
938 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
939 oFsm.pUniTechProf.mutexTPState.Unlock()
940 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
941 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
942 "TD-entity-id": loGemPortID})
943
944 oFsm.mutexPLastTxMeInstance.Lock()
945 meInstance, err := oFsm.pOmciCC.sendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
946 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, loGemPortID)
947
948 if err != nil {
949 logger.Errorw(ctx, "TD delete failed - proceed fsm",
950 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
951 pConfigAniStateAFsm := oFsm.pAdaptFsm
952 if pConfigAniStateAFsm != nil {
953 oFsm.mutexPLastTxMeInstance.Unlock()
954 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
955 go func(aPAFsm *AdapterFsm) {
956 if aPAFsm != nil && aPAFsm.pFsm != nil {
957 _ = aPAFsm.pFsm.Event(aniEvReset)
958 }
959 }(pConfigAniStateAFsm)
960 return
961 }
962 }
963 oFsm.pLastTxMeInstance = meInstance
964 oFsm.mutexPLastTxMeInstance.Unlock()
965}
mpagenko8b07c1b2020-11-26 10:36:31 +0000966
dbainbri4d3a0dc2020-12-02 00:33:42 +0000967func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
968 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000969 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
970
971 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
972 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
973 meParams := me.ParamData{
974 EntityID: oFsm.tcont0ID,
975 Attributes: me.AttributeValueMap{
976 "AllocId": unusedTcontAllocID,
977 },
978 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000979 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300980 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000981 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300982 if err != nil {
983 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
984 log.Fields{"device-id": oFsm.deviceID})
985 pConfigAniStateAFsm := oFsm.pAdaptFsm
986 if pConfigAniStateAFsm != nil {
987 oFsm.mutexPLastTxMeInstance.Unlock()
988 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
989 go func(aPAFsm *AdapterFsm) {
990 if aPAFsm != nil && aPAFsm.pFsm != nil {
991 _ = aPAFsm.pFsm.Event(aniEvReset)
992 }
993 }(pConfigAniStateAFsm)
994 return
995 }
996 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000997 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300998 oFsm.mutexPLastTxMeInstance.Unlock()
999
mpagenko8b07c1b2020-11-26 10:36:31 +00001000}
1001
dbainbri4d3a0dc2020-12-02 00:33:42 +00001002func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
1003 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001004 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1005
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001006 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001007 meInstance, err := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001008 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001009 if err != nil {
1010 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting uniPonAniConfigFsm!",
1011 log.Fields{"device-id": oFsm.deviceID})
1012 pConfigAniStateAFsm := oFsm.pAdaptFsm
1013 if pConfigAniStateAFsm != nil {
1014 oFsm.mutexPLastTxMeInstance.Unlock()
1015 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1016 go func(aPAFsm *AdapterFsm) {
1017 if aPAFsm != nil && aPAFsm.pFsm != nil {
1018 _ = aPAFsm.pFsm.Event(aniEvReset)
1019 }
1020 }(pConfigAniStateAFsm)
1021 return
1022 }
1023 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001024 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001025 oFsm.mutexPLastTxMeInstance.Unlock()
1026
mpagenko8b07c1b2020-11-26 10:36:31 +00001027}
1028
dbainbri4d3a0dc2020-12-02 00:33:42 +00001029func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1030 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001031 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1032
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001033 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001034 meInstance, err := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001035 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001036 if err != nil {
1037 logger.Errorw(ctx, "MBPConfigData delete failed, aborting uniPonAniConfigFsm!",
1038 log.Fields{"device-id": oFsm.deviceID})
1039 pConfigAniStateAFsm := oFsm.pAdaptFsm
1040 if pConfigAniStateAFsm != nil {
1041 oFsm.mutexPLastTxMeInstance.Unlock()
1042 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1043 go func(aPAFsm *AdapterFsm) {
1044 if aPAFsm != nil && aPAFsm.pFsm != nil {
1045 _ = aPAFsm.pFsm.Event(aniEvReset)
1046 }
1047 }(pConfigAniStateAFsm)
1048 return
1049 }
1050 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001051 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001052 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001053}
1054
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1056 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001057 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1058 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001059 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001060 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001061 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +00001062 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001063 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1064 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001065 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001066 }
1067
1068 //let's reset the state machine in order to release all resources now
1069 pConfigAniStateAFsm := oFsm.pAdaptFsm
1070 if pConfigAniStateAFsm != nil {
1071 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1072 go func(aPAFsm *AdapterFsm) {
1073 if aPAFsm != nil && aPAFsm.pFsm != nil {
1074 _ = aPAFsm.pFsm.Event(aniEvReset)
1075 }
1076 }(pConfigAniStateAFsm)
1077 }
1078}
1079
dbainbri4d3a0dc2020-12-02 00:33:42 +00001080func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1081 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001082 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001083
mpagenko3dbcdd22020-07-22 07:38:45 +00001084 pConfigAniStateAFsm := oFsm.pAdaptFsm
1085 if pConfigAniStateAFsm != nil {
1086 // abort running message processing
1087 fsmAbortMsg := Message{
1088 Type: TestMsg,
1089 Data: TestMessage{
1090 TestMessageVal: AbortMessageProcessing,
1091 },
1092 }
1093 pConfigAniStateAFsm.commChan <- fsmAbortMsg
1094
1095 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +05301096 go func(aPAFsm *AdapterFsm) {
1097 if aPAFsm != nil && aPAFsm.pFsm != nil {
1098 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001099 }
1100 }(pConfigAniStateAFsm)
1101 }
1102}
1103
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1105 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001106 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001107 oFsm.mutexPLastTxMeInstance.Lock()
1108 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001109 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001110}
1111
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1113 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001114loop:
1115 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001116 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001117 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001118 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301119 message, ok := <-oFsm.pAdaptFsm.commChan
1120 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301122 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1123 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1124 break loop
1125 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301127
1128 switch message.Type {
1129 case TestMsg:
1130 msg, _ := message.Data.(TestMessage)
1131 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001133 break loop
1134 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001135 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301136 case OMCI:
1137 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001138 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301139 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301141 "message.Type": message.Type})
1142 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001143
Himani Chawla4d908332020-08-31 12:30:20 +05301144 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301146}
1147
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301149 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1150 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001151 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001152 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301153 return
1154 }
1155 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1156 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001158 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301159 return
1160 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001161 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001162 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1163 //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 +00001164 oFsm.mutexPLastTxMeInstance.RLock()
1165 if oFsm.pLastTxMeInstance != nil {
1166 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1167 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1168 // maybe we can use just the same eventName for different state transitions like "forward"
1169 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1170 switch oFsm.pLastTxMeInstance.GetName() {
1171 case "Ieee8021PMapperServiceProfile":
1172 { // let the FSM proceed ...
1173 oFsm.mutexPLastTxMeInstance.RUnlock()
1174 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
1175 }
1176 case "MacBridgePortConfigurationData":
1177 { // let the FSM proceed ...
1178 oFsm.mutexPLastTxMeInstance.RUnlock()
1179 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
1180 }
1181 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1182 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1183 oFsm.mutexPLastTxMeInstance.RUnlock()
1184 oFsm.omciMIdsResponseReceived <- true
1185 }
1186 default:
1187 {
1188 oFsm.mutexPLastTxMeInstance.RUnlock()
1189 logger.Warnw(ctx, "Unsupported ME name received!",
1190 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1191 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001192 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001193 } else {
1194 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001195 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001196 } else {
1197 oFsm.mutexPLastTxMeInstance.RUnlock()
1198 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001199 }
1200 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001201 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1202 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301203 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1204 return
1205 }
Himani Chawla4d908332020-08-31 12:30:20 +05301206}
Mahir Gunyel01034b62021-06-29 11:25:09 -07001207func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
1208 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1209 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1210 oFsm.mutexPLastTxMeInstance.RLock()
1211 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1212 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1213 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1214 switch oFsm.pLastTxMeInstance.GetName() {
1215 case "TCont":
1216 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1217 //We should revert DB
1218 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1219 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1220 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
1221 if pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false); pDevEntry != nil {
1222 pDevEntry.freeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
1223 } else {
1224 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1225 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1226 }
1227 }
1228 default:
1229 logger.Warnw(ctx, "Unsupported ME name received with error!",
1230 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1231 }
1232 }
1233}
dbainbri4d3a0dc2020-12-02 00:33:42 +00001234func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301235 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1236 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001238 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301239 return
1240 }
1241 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1242 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001243 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001244 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301245 return
1246 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001247 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301248 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001249 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001250 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301251 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001252
Mahir Gunyel01034b62021-06-29 11:25:09 -07001253 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301254 return
1255 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001256 oFsm.mutexPLastTxMeInstance.RLock()
1257 if oFsm.pLastTxMeInstance != nil {
1258 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1259 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1260 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1261 // if, then something like:
1262 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301263
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001264 switch oFsm.pLastTxMeInstance.GetName() {
1265 case "TCont":
1266 { // let the FSM proceed ...
1267 oFsm.mutexPLastTxMeInstance.RUnlock()
1268 if oFsm.requestEventOffset == 0 { //from TCont config request
1269 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
1270 } else { // from T-Cont reset request
1271 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
1272 }
1273 }
1274 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1275 { // let the PrioQueue init proceed by stopping the wait function
1276 oFsm.mutexPLastTxMeInstance.RUnlock()
1277 oFsm.omciMIdsResponseReceived <- true
1278 }
1279 case "Ieee8021PMapperServiceProfile":
1280 { // let the FSM proceed ...
1281 oFsm.mutexPLastTxMeInstance.RUnlock()
1282 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
1283 }
1284 default:
1285 {
1286 oFsm.mutexPLastTxMeInstance.RUnlock()
1287 logger.Warnw(ctx, "Unsupported ME name received!",
1288 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001289 }
Himani Chawla4d908332020-08-31 12:30:20 +05301290 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001291 } else {
1292 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301293 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001294 } else {
1295 oFsm.mutexPLastTxMeInstance.RUnlock()
1296 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301297 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001298}
1299
dbainbri4d3a0dc2020-12-02 00:33:42 +00001300func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001301 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1302 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001303 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001304 log.Fields{"device-id": oFsm.deviceID})
1305 return
1306 }
1307 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1308 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001309 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001310 log.Fields{"device-id": oFsm.deviceID})
1311 return
1312 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001313 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001314 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001315 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001316 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1317 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1318 // store error for mgmt display?
1319 return
1320 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001321 oFsm.mutexPLastTxMeInstance.RLock()
1322 if oFsm.pLastTxMeInstance != nil {
1323 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1324 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1325 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1326 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001327
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001328 switch oFsm.pLastTxMeInstance.GetName() {
1329 case "GemInterworkingTerminationPoint":
1330 { // let the FSM proceed ...
1331 oFsm.mutexPLastTxMeInstance.RUnlock()
1332 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
1333 }
1334 case "GemPortNetworkCtp":
1335 { // let the FSM proceed ...
1336 oFsm.mutexPLastTxMeInstance.RUnlock()
1337 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
1338 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001339 case "TrafficDescriptor":
1340 { // let the FSM proceed ...
1341 oFsm.mutexPLastTxMeInstance.RUnlock()
1342 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemTdResp)
1343 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001344 case "Ieee8021PMapperServiceProfile":
1345 { // let the FSM proceed ...
1346 oFsm.mutexPLastTxMeInstance.RUnlock()
1347 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
1348 }
1349 case "MacBridgePortConfigurationData":
1350 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1351 oFsm.mutexPLastTxMeInstance.RUnlock()
1352 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
1353 }
1354 default:
1355 {
1356 oFsm.mutexPLastTxMeInstance.RUnlock()
1357 logger.Warnw(ctx, "Unsupported ME name received!",
1358 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1359 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001360 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001361 } else {
1362 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001363 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001364 } else {
1365 oFsm.mutexPLastTxMeInstance.RUnlock()
1366 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001367 }
1368}
1369
dbainbri4d3a0dc2020-12-02 00:33:42 +00001370func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
1371 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001372 "msgType": msg.OmciMsg.MessageType})
1373
1374 switch msg.OmciMsg.MessageType {
1375 case omci.CreateResponseType:
1376 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001377 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301378
mpagenko3dbcdd22020-07-22 07:38:45 +00001379 } //CreateResponseType
1380 case omci.SetResponseType:
1381 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001382 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001383
mpagenko3dbcdd22020-07-22 07:38:45 +00001384 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001385 case omci.DeleteResponseType:
1386 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001387 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001388
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001389 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001390 default:
1391 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001392 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001393 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001394 return
1395 }
1396 }
1397}
1398
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001400 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1401 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001402 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001403 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1404 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001405 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001406 meParams := me.ParamData{
1407 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1408 Attributes: me.AttributeValueMap{
1409 "PortId": gemPortAttribs.gemPortID,
1410 "TContPointer": oFsm.tcont0ID,
1411 "Direction": gemPortAttribs.direction,
1412 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1413 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1414 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1415 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1416 },
1417 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001418 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001419 meInstance, err := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001420 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001421 if err != nil {
1422 oFsm.mutexPLastTxMeInstance.Unlock()
1423 logger.Errorw(ctx, "GemNCTPVar create failed, aborting uniPonAniConfigFsm!",
1424 log.Fields{"device-id": oFsm.deviceID})
1425 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1426 return
1427 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001428 //accept also nil as (error) return value for writing to LastTx
1429 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001430 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001431 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001432 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001433 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001434 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001435 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001436 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301437 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001438 return
1439 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001440 // Mark the gem port to be added for Performance History monitoring
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001441 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -07001442 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001443 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001444 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001445
1446 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301448 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001449}
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001450func (oFsm *uniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
1451 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1452 if gemPortAttribs.isMulticast {
1453 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1454 return true
1455 }
1456 }
1457 return false
1458}
mpagenko3dbcdd22020-07-22 07:38:45 +00001459
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001461 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1462 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001463 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001464 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1465 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001466 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001467
ozgecanetsia4b232302020-11-11 10:58:10 +03001468 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1469 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001470
1471 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001472 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001473 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001474 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001475 "InterworkingOption": 0, // Don't Care
1476 "ServiceProfilePointer": 0, // Don't Care
1477 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001478 },
1479 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001480 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1481 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1482 continue
1483 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001484 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001485 meInstance, err := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsia4b232302020-11-11 10:58:10 +03001486 true, oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001487 if err != nil {
1488 oFsm.mutexPLastTxMeInstance.Unlock()
1489 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting uniPonAniConfigFsm!",
1490 log.Fields{"device-id": oFsm.deviceID})
1491 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1492 return
1493
1494 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001495 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001496 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001497 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001498 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001499 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001500 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001501 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1502 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1503 return
1504 }
1505 ipv4MulticastTable := make([]uint8, 12)
1506 //Gem Port ID
1507 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1508 //Secondary Key
1509 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1510 // Multicast IP range start This is the 224.0.0.1 address
1511 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1512 // MulticastIp range stop
1513 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1514
1515 meIPV4MCTableParams := me.ParamData{
1516 EntityID: gemPortAttribs.multicastGemID,
1517 Attributes: me.AttributeValueMap{
1518 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1519 },
1520 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001521 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001522 meIPV4MCTableInstance, err := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001523 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001524 if err != nil {
1525 oFsm.mutexPLastTxMeInstance.Unlock()
1526 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting uniPonAniConfigFsm!",
1527 log.Fields{"device-id": oFsm.deviceID})
1528 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1529 return
1530 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001531 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001532 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001533
1534 } else {
1535 meParams := me.ParamData{
1536 EntityID: gemPortAttribs.gemPortID,
1537 Attributes: me.AttributeValueMap{
1538 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1539 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1540 "ServiceProfilePointer": oFsm.mapperSP0ID,
1541 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1542 "GalProfilePointer": galEthernetEID,
1543 },
1544 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001545 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001546 meInstance, err := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsia4b232302020-11-11 10:58:10 +03001547 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001548 if err != nil {
1549 oFsm.mutexPLastTxMeInstance.Unlock()
1550 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting uniPonAniConfigFsm!",
1551 log.Fields{"device-id": oFsm.deviceID})
1552 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1553 return
1554 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001555 //accept also nil as (error) return value for writing to LastTx
1556 // - this avoids misinterpretation of new received OMCI messages
1557 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001558 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001559 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001560 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001561 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001562 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001564 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301565 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001566 return
1567 }
1568 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001569
1570 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301572 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001573}
1574
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001576 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1577 if oFsm.tcontSetBefore {
1578 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1579 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
1580 "uni-id": oFsm.pOnuUniPort.uniID,
1581 "techProfile-id": oFsm.techProfileID})
1582 go func(aPAFsm *AdapterFsm) {
1583 if aPAFsm != nil && aPAFsm.pFsm != nil {
1584 _ = aPAFsm.pFsm.Event(aniEvRxPrioqsResp)
1585 }
1586 }(oFsm.pAdaptFsm)
1587 return
1588 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001589 const cu16StrictPrioWeight uint16 = 0xFFFF
1590 //find all upstream PrioQueues related to this T-Cont
1591 loQueueMap := ordered_map.NewOrderedMap()
1592 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001593 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001595 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1596 "prioString": gemPortAttribs.pbitString})
1597 continue
1598 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001599 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301600 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001601 //key does not yet exist
1602 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1603 }
1604 } else {
1605 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1606 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001607 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001608
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001609 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1610 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1611 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1612 // or even be finished without correct SP/WRR setting
1613
1614 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1615 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1616 // even though its T-Cont seems to be wrong ...
1617 loTrafficSchedulerEID := 0x8000
1618 //for all found queues
1619 iter := loQueueMap.IterFunc()
1620 for kv, ok := iter(); ok; kv, ok = iter() {
1621 queueIndex := (kv.Key).(uint16)
1622 meParams := me.ParamData{
1623 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301624 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001625 }
1626 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1627 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001629 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001630 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001631 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1632 } else {
1633 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001635 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1636 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001637 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001638 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1639 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1640 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001641 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001642 meInstance, err := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001643 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001644 if err != nil {
1645 oFsm.mutexPLastTxMeInstance.Unlock()
1646 logger.Errorw(ctx, "PrioQueueVar set failed, aborting uniPonAniConfigFsm!",
1647 log.Fields{"device-id": oFsm.deviceID})
1648 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1649 return
1650 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001651 //accept also nil as (error) return value for writing to LastTx
1652 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001653 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001654 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001655
1656 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001657 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001658 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001660 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301661 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001662 return
1663 }
1664
1665 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1666 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1667 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1668 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1669
1670 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001671
1672 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001673 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301674 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001675}
1676
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001678 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001679 if oFsm.isCanceled {
1680 // FSM already canceled before entering wait
1681 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
1682 oFsm.mutexIsAwaitingResponse.Unlock()
1683 return fmt.Errorf(cErrWaitAborted)
1684 }
mpagenko7d6bb022021-03-11 15:07:55 +00001685 oFsm.isAwaitingResponse = true
1686 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001687 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301688 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001689 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001690 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001691 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 +00001692 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001693 oFsm.mutexIsAwaitingResponse.Lock()
1694 oFsm.isAwaitingResponse = false
1695 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001696 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001697 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301698 if success {
mpagenkocf48e452021-04-23 09:23:00 +00001699 logger.Debugw(ctx, "uniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001700 oFsm.mutexIsAwaitingResponse.Lock()
1701 oFsm.isAwaitingResponse = false
1702 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001703 return nil
1704 }
mpagenko7d6bb022021-03-11 15:07:55 +00001705 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00001706 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001707 oFsm.mutexIsAwaitingResponse.Lock()
1708 oFsm.isAwaitingResponse = false
1709 oFsm.mutexIsAwaitingResponse.Unlock()
1710 return fmt.Errorf(cErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001711 }
1712}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001713
1714func (oFsm *uniPonAniConfigFsm) setChanSet(flagValue bool) {
1715 oFsm.mutexChanSet.Lock()
1716 oFsm.chanSet = flagValue
1717 oFsm.mutexChanSet.Unlock()
1718}
1719
1720func (oFsm *uniPonAniConfigFsm) isChanSet() bool {
1721 oFsm.mutexChanSet.RLock()
1722 flagValue := oFsm.chanSet
1723 oFsm.mutexChanSet.RUnlock()
1724 return flagValue
1725}