blob: 4473c7e91f096f7928b53bfb72bf4b58668c08b2 [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
mpagenko45cc6a32021-07-23 10:06:57 +0000289 // possible access conflicts on internal data by next needed data clearance
290 // are avoided by using mutexTPState also from within clearAniSideConfig
291 // do not try to lock TpProcMutex here as done in previous code version
292 // as it may result in deadlock situations (as observed at soft-reboot handling where
293 // TpProcMutex is already locked by some ongoing TechProfile config/removal processing
mpagenko73143992021-04-09 15:17:10 +0000294 //remove all TechProf related internal data to allow for new configuration
295 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000296}
297
Mahir Gunyel6781f962021-05-16 23:30:08 -0700298//nolint: gocyclo
299//TODO:visit here for refactoring for gocyclo
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530301 if aPAFsm != nil && aPAFsm.pFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700302 var err error
303 oFsm.mapperSP0ID, err = generateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
304 if err != nil {
305 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
306 "techProfileID": oFsm.techProfileID, "error": err})
307 return
308 }
309 oFsm.macBPCD0ID, err = generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
310 if err != nil {
311 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
312 "techProfileID": oFsm.techProfileID, "error": err})
313 return
314 }
315 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
316 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
317 "macBpNo": oFsm.pOnuUniPort.macBpNo, "techProfileID": oFsm.techProfileID})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700318 pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false)
319 if pDevEntry == nil {
320 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800321 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530322 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700323 tcontInstID, tcontAlreadyExist, err := pDevEntry.allocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
324 if err != nil {
325 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700326 //reset the state machine to enable usage on subsequent requests
327 _ = aPAFsm.pFsm.Event(aniEvReset)
328 return
329 }
330 oFsm.tcont0ID = tcontInstID
331 oFsm.tcontSetBefore = tcontAlreadyExist
332 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
333 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
334 "tcontAlreadyExist": tcontAlreadyExist,
335 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800336
337 // Access critical state with lock
338 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000339 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
340 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
Girish Gowdra041dcb32020-11-16 16:54:30 -0800341 oFsm.pUniTechProf.mutexTPState.Unlock()
342
Himani Chawla26e555c2020-08-31 12:30:20 +0530343 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800344 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300345 loGemPortAttribs := ponAniGemPortAttribs{}
346
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
348
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530350
351 loGemPortAttribs.gemPortID = gemEntry.gemPortID
352 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
353 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
354 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
355 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
356
357 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
358 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
359 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
360 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
361 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
362 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
363
364 usQueueFound := false
365 dsQueueFound := false
366 for _, mgmtEntityID := range queueInstKeys {
367 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
368 returnVal := meAttributes["RelatedPort"]
369 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530370 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530371 if relatedPort == usQrelPortMask {
372 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000373 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000374 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 usQueueFound = true
376 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
377 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000379 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 dsQueueFound = true
381 }
382 if usQueueFound && dsQueueFound {
383 break
384 }
385 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 }
388 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 }
391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000392 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000393 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 }
395 }
396 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000397 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 }
399 loGemPortAttribs.direction = gemEntry.direction
400 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
401 loGemPortAttribs.weight = gemEntry.queueWeight
402 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300403
ozgecanetsia4b232302020-11-11 10:58:10 +0300404 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300405 //TODO this might effectively ignore the for loop starting at line 316
406 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300407 loGemPortAttribs.isMulticast = true
408 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
409 loGemPortAttribs.staticACL = gemEntry.staticACL
410 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530411
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300413 "gemPortID": loGemPortAttribs.gemPortID,
414 "isMulticast": loGemPortAttribs.isMulticast,
415 "multicastGemID": loGemPortAttribs.multicastGemID,
416 "staticACL": loGemPortAttribs.staticACL,
417 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000418 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300419 })
420
421 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000422 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300423 "gemPortID": loGemPortAttribs.gemPortID,
424 "upQueueID": loGemPortAttribs.upQueueID,
425 "downQueueID": loGemPortAttribs.downQueueID,
426 "pbitString": loGemPortAttribs.pbitString,
427 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000428 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300429 })
430 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530431
432 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
433 }
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000434 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
435 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
436 } else {
437 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
438 _ = aPAFsm.pFsm.Event(aniEvSkipOmciConfig)
439 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530440 }
441}
442
dbainbri4d3a0dc2020-12-02 00:33:42 +0000443func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
444 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000445 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000446 // in case the used channel is not yet defined (can be re-used after restarts)
447 if oFsm.omciMIdsResponseReceived == nil {
448 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000449 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000450 } else {
451 // as we may 're-use' this instance of FSM and the connected channel
452 // make sure there is no 'lingering' request in the already existing channel:
453 // (simple loop sufficient as we are the only receiver)
454 for len(oFsm.omciMIdsResponseReceived) > 0 {
455 <-oFsm.omciMIdsResponseReceived
456 }
457 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000458 //ensure internal slices are empty (which might be set from previous run) - release memory
459 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000460 oFsm.mutexIsAwaitingResponse.Lock()
461 //reset the canceled state possibly existing from previous reset
462 oFsm.isCanceled = false
463 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000464
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000465 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000466 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000467
468 //let the state machine run forward from here directly
469 pConfigAniStateAFsm := oFsm.pAdaptFsm
470 if pConfigAniStateAFsm != nil {
471 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000473
mpagenko3dbcdd22020-07-22 07:38:45 +0000474 }
475}
476
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
478 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000479 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000480 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
481 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000482 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300483 meInstance, err := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000484 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300485 if err != nil {
486 logger.Errorw(ctx, "Dot1PMapper create failed, aborting uniPonAniConfigFsm!",
487 log.Fields{"device-id": oFsm.deviceID})
488 pConfigAniStateAFsm := oFsm.pAdaptFsm
489 if pConfigAniStateAFsm != nil {
490 oFsm.mutexPLastTxMeInstance.Unlock()
491 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
492 go func(aPAFsm *AdapterFsm) {
493 if aPAFsm != nil && aPAFsm.pFsm != nil {
494 _ = aPAFsm.pFsm.Event(aniEvReset)
495 }
496 }(pConfigAniStateAFsm)
497 return
498 }
499 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000500 //accept also nil as (error) return value for writing to LastTx
501 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000502 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300503 oFsm.mutexPLastTxMeInstance.Unlock()
504
mpagenko3dbcdd22020-07-22 07:38:45 +0000505}
506
dbainbri4d3a0dc2020-12-02 00:33:42 +0000507func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
508 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000509 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
510 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000511 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000512 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
513 meParams := me.ParamData{
514 EntityID: oFsm.macBPCD0ID,
515 Attributes: me.AttributeValueMap{
516 "BridgeIdPointer": bridgePtr,
517 "PortNum": 0xFF, //fixed unique ANI side indication
518 "TpType": 3, //for .1PMapper
519 "TpPointer": oFsm.mapperSP0ID,
520 },
521 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000522 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300523 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000524 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300525 if err != nil {
526 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting uniPonAniConfigFsm!",
527 log.Fields{"device-id": oFsm.deviceID})
528 pConfigAniStateAFsm := oFsm.pAdaptFsm
529 if pConfigAniStateAFsm != nil {
530 oFsm.mutexPLastTxMeInstance.Unlock()
531 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
532 go func(aPAFsm *AdapterFsm) {
533 if aPAFsm != nil && aPAFsm.pFsm != nil {
534 _ = aPAFsm.pFsm.Event(aniEvReset)
535 }
536 }(pConfigAniStateAFsm)
537 return
538 }
539 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000540 //accept also nil as (error) return value for writing to LastTx
541 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000542 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300543 oFsm.mutexPLastTxMeInstance.Unlock()
544
mpagenko3dbcdd22020-07-22 07:38:45 +0000545}
546
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
548 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000549 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
550 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700551 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
552 "tcontExist": oFsm.tcontSetBefore})
553 //If tcont was set before, then no need to set it again. Let state machine to proceed.
554 if oFsm.tcontSetBefore {
555 go func(aPAFsm *AdapterFsm) {
556 if aPAFsm != nil && aPAFsm.pFsm != nil {
557 _ = aPAFsm.pFsm.Event(aniEvRxTcontsResp)
558 }
559 }(oFsm.pAdaptFsm)
560 return
561 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000562 meParams := me.ParamData{
563 EntityID: oFsm.tcont0ID,
564 Attributes: me.AttributeValueMap{
565 "AllocId": oFsm.alloc0ID,
566 },
567 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000568 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300569 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000570 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300571 if err != nil {
572 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
573 log.Fields{"device-id": oFsm.deviceID})
574 pConfigAniStateAFsm := oFsm.pAdaptFsm
575 if pConfigAniStateAFsm != nil {
576 oFsm.mutexPLastTxMeInstance.Unlock()
577 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
578 go func(aPAFsm *AdapterFsm) {
579 if aPAFsm != nil && aPAFsm.pFsm != nil {
580 _ = aPAFsm.pFsm.Event(aniEvReset)
581 }
582 }(pConfigAniStateAFsm)
583 return
584 }
585 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000586 //accept also nil as (error) return value for writing to LastTx
587 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000588 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300589 oFsm.mutexPLastTxMeInstance.Unlock()
590
mpagenko3dbcdd22020-07-22 07:38:45 +0000591}
592
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
594 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000595 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000596 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000597}
598
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
600 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000601 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000602 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000603}
604
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
606 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000607 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000609}
610
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300612
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000614 "toGemIw": 1024, /* cmp above */
615 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000616
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000618 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000619 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000620
mpagenko3dbcdd22020-07-22 07:38:45 +0000621 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000622 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530623 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000624 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000625
626 //assign the GemPorts according to the configured Prio
627 var loPrioGemPortArray [8]uint16
628 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300629 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300631 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
632 "prioString": gemPortAttribs.pbitString})
633 continue
634 }
635 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300637 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
638 "prioString": gemPortAttribs.pbitString})
639 continue
640 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000641 for i := 0; i < 8; i++ {
642 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
643 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
644 if prio == 1 { // Check this p-bit is set
645 if loPrioGemPortArray[i] == 0 {
646 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
647 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000649 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000650 "SetGemPort": loPrioGemPortArray[i]})
651 }
652 }
653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000655 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000656 "prioString": gemPortAttribs.pbitString, "position": i})
657 }
658
659 }
660 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300661
ozgecanetsia4b232302020-11-11 10:58:10 +0300662 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530663 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300664 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530665 if value != 0 {
666 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530667 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000669 "for Prio": index,
670 "IwPtr": strconv.FormatInt(int64(value), 16),
671 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300672 } else {
673 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000674 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
675 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300676 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530677 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000678 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300679 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000680 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
681 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300682 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530683
684 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000686 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300687 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
688 // this reset needs to be performed only if the tech profile provides upstream gem ports but no priority is set
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000689 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300690 //pConfigAniStateAFsm := oFsm.pAdaptFsm
691 //if pConfigAniStateAFsm != nil {
692 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
693 // go func(aPAFsm *AdapterFsm) {
694 // if aPAFsm != nil && aPAFsm.pFsm != nil {
695 // _ = aPAFsm.pFsm.Event(aniEvReset)
696 // }
697 // }(pConfigAniStateAFsm)
698 //}
699 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000700 pConfigAniStateAFsm := oFsm.pAdaptFsm
701 if pConfigAniStateAFsm != nil {
702 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530703 go func(aPAFsm *AdapterFsm) {
704 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300705 _ = aPAFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000706 }
707 }(pConfigAniStateAFsm)
708 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300709 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000710 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300711 meInstance, err := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300712 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300713 if err != nil {
714 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting uniPonAniConfigFsm!",
715 log.Fields{"device-id": oFsm.deviceID})
716 pConfigAniStateAFsm := oFsm.pAdaptFsm
717 if pConfigAniStateAFsm != nil {
718 oFsm.mutexPLastTxMeInstance.Unlock()
719 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
720 go func(aPAFsm *AdapterFsm) {
721 if aPAFsm != nil && aPAFsm.pFsm != nil {
722 _ = aPAFsm.pFsm.Event(aniEvReset)
723 }
724 }(pConfigAniStateAFsm)
725 return
726 }
727 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300728 //accept also nil as (error) return value for writing to LastTx
729 // - this avoids misinterpretation of new received OMCI messages
730 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300731 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000732 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000733}
734
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
736 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000737 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000738 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800739 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000740 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
741 //use DeviceHandler event notification directly
742 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
743 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
744 // but only in case the techProfile was configured (not deleted)
745 if oFsm.requestEventOffset == 0 {
746 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
747 }
748 } else {
749 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000750 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000751 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000752 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000753 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000754 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
755 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000756 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000757 }
mpagenko01e726e2020-10-23 09:45:29 +0000758
759 //the FSM is left active in this state as long as no specific reset or remove is requested from outside
mpagenko3dbcdd22020-07-22 07:38:45 +0000760}
761
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenkoa23a6292021-02-23 10:40:10 +0000763 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000764 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
765 select {
766 case <-oFsm.waitFlowDeleteChannel:
767 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
768 default:
769 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000770
771 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID] != nil {
772 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
773 oFsm.pUniTechProf.mutexTPState.Unlock()
774 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
775 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
776 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
777 pConfigAniStateAFsm := oFsm.pAdaptFsm
778 if pConfigAniStateAFsm != nil {
779 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
780 go func(aPAFsm *AdapterFsm) {
781 if aPAFsm != nil && aPAFsm.pFsm != nil {
782 _ = aPAFsm.pFsm.Event(aniEvWaitFlowRem)
783 }
784 }(pConfigAniStateAFsm)
785 } else {
786 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
787 }
788 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800789 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000790 } else {
791 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
792 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800793 }
794
mpagenko8b07c1b2020-11-26 10:36:31 +0000795 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000796 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
797 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000799 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
800 "GemIwTp-entity-id": loGemPortID})
801 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
802
803 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000804 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300805 meInstance, err := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000806 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300807 if err != nil {
808 logger.Errorw(ctx, "GemIWTP delete failed, aborting uniPonAniConfigFsm!",
809 log.Fields{"device-id": oFsm.deviceID})
810 pConfigAniStateAFsm := oFsm.pAdaptFsm
811 if pConfigAniStateAFsm != nil {
812 oFsm.mutexPLastTxMeInstance.Unlock()
813 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
814 go func(aPAFsm *AdapterFsm) {
815 if aPAFsm != nil && aPAFsm.pFsm != nil {
816 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
817 }
818 }(pConfigAniStateAFsm)
819 return
820 }
821 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000822 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300823 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000824}
825
mpagenkobb47bc22021-04-20 13:29:09 +0000826func (oFsm *uniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
827 oFsm.mutexIsAwaitingResponse.Lock()
828 oFsm.isWaitingForFlowDelete = true
829 oFsm.mutexIsAwaitingResponse.Unlock()
830 select {
831 // maybe be also some outside cancel (but no context modeled for the moment ...)
832 // case <-ctx.Done():
833 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000834 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 +0000835 logger.Warnw(ctx, "uniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
836 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
837 oFsm.mutexIsAwaitingResponse.Lock()
838 oFsm.isWaitingForFlowDelete = false
839 oFsm.mutexIsAwaitingResponse.Unlock()
840 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
841 pConfigAniStateAFsm := oFsm.pAdaptFsm
842 if pConfigAniStateAFsm != nil {
843 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
844 go func(aPAFsm *AdapterFsm) {
845 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300846 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000847 }
848 }(pConfigAniStateAFsm)
849 } else {
850 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
851 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
852 }
853 return
854
855 case success := <-oFsm.waitFlowDeleteChannel:
856 if success {
857 logger.Debugw(ctx, "uniPonAniConfigFsm flow removed info received", log.Fields{
858 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
859 oFsm.mutexIsAwaitingResponse.Lock()
860 oFsm.isWaitingForFlowDelete = false
861 oFsm.mutexIsAwaitingResponse.Unlock()
862 pConfigAniStateAFsm := oFsm.pAdaptFsm
863 if pConfigAniStateAFsm != nil {
864 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
865 go func(aPAFsm *AdapterFsm) {
866 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300867 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000868 }
869 }(pConfigAniStateAFsm)
870 } else {
871 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
872 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
873 }
874 return
875 }
876 // waiting was aborted (probably on external request)
877 logger.Debugw(ctx, "uniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
878 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
879 oFsm.mutexIsAwaitingResponse.Lock()
880 oFsm.isWaitingForFlowDelete = false
881 oFsm.mutexIsAwaitingResponse.Unlock()
882 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
883 pConfigAniStateAFsm := oFsm.pAdaptFsm
884 if pConfigAniStateAFsm != nil {
885 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
886 go func(aPAFsm *AdapterFsm) {
887 if aPAFsm != nil && aPAFsm.pFsm != nil {
888 _ = aPAFsm.pFsm.Event(aniEvReset)
889 }
890 }(pConfigAniStateAFsm)
891 }
892 return
893 }
894}
895
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000897 oFsm.pUniTechProf.mutexTPState.Lock()
898 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
899 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000901 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
902 "GemNCTP-entity-id": loGemPortID})
903 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000904 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300905 meInstance, err := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000906 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300907 if err != nil {
908 logger.Errorw(ctx, "GemNCTP delete failed, aborting uniPonAniConfigFsm!",
909 log.Fields{"device-id": oFsm.deviceID})
910 pConfigAniStateAFsm := oFsm.pAdaptFsm
911 if pConfigAniStateAFsm != nil {
912 oFsm.mutexPLastTxMeInstance.Unlock()
913 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
914 go func(aPAFsm *AdapterFsm) {
915 if aPAFsm != nil && aPAFsm.pFsm != nil {
916 _ = aPAFsm.pFsm.Event(aniEvReset)
917 }
918 }(pConfigAniStateAFsm)
919 return
920 }
921 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000922 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000923 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300924
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800925 // Mark the gem port to be removed for Performance History monitoring
926 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -0700927 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800928 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000929}
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300930func (oFsm *uniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
931 oFsm.pUniTechProf.mutexTPState.Lock()
932 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
933 oFsm.pUniTechProf.mutexTPState.Unlock()
934 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
935 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
936 "TD-entity-id": loGemPortID})
937
938 oFsm.mutexPLastTxMeInstance.Lock()
939 meInstance, err := oFsm.pOmciCC.sendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
940 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, loGemPortID)
941
942 if err != nil {
943 logger.Errorw(ctx, "TD delete failed - proceed fsm",
944 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
945 pConfigAniStateAFsm := oFsm.pAdaptFsm
946 if pConfigAniStateAFsm != nil {
947 oFsm.mutexPLastTxMeInstance.Unlock()
948 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
949 go func(aPAFsm *AdapterFsm) {
950 if aPAFsm != nil && aPAFsm.pFsm != nil {
951 _ = aPAFsm.pFsm.Event(aniEvReset)
952 }
953 }(pConfigAniStateAFsm)
954 return
955 }
956 }
957 oFsm.pLastTxMeInstance = meInstance
958 oFsm.mutexPLastTxMeInstance.Unlock()
959}
mpagenko8b07c1b2020-11-26 10:36:31 +0000960
dbainbri4d3a0dc2020-12-02 00:33:42 +0000961func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
962 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000963 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
964
965 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
966 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
967 meParams := me.ParamData{
968 EntityID: oFsm.tcont0ID,
969 Attributes: me.AttributeValueMap{
970 "AllocId": unusedTcontAllocID,
971 },
972 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000973 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300974 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000975 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300976 if err != nil {
977 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
978 log.Fields{"device-id": oFsm.deviceID})
979 pConfigAniStateAFsm := oFsm.pAdaptFsm
980 if pConfigAniStateAFsm != nil {
981 oFsm.mutexPLastTxMeInstance.Unlock()
982 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
983 go func(aPAFsm *AdapterFsm) {
984 if aPAFsm != nil && aPAFsm.pFsm != nil {
985 _ = aPAFsm.pFsm.Event(aniEvReset)
986 }
987 }(pConfigAniStateAFsm)
988 return
989 }
990 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000991 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300992 oFsm.mutexPLastTxMeInstance.Unlock()
993
mpagenko8b07c1b2020-11-26 10:36:31 +0000994}
995
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
997 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000998 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
999
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001000 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001001 meInstance, err := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001002 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001003 if err != nil {
1004 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting uniPonAniConfigFsm!",
1005 log.Fields{"device-id": oFsm.deviceID})
1006 pConfigAniStateAFsm := oFsm.pAdaptFsm
1007 if pConfigAniStateAFsm != nil {
1008 oFsm.mutexPLastTxMeInstance.Unlock()
1009 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1010 go func(aPAFsm *AdapterFsm) {
1011 if aPAFsm != nil && aPAFsm.pFsm != nil {
1012 _ = aPAFsm.pFsm.Event(aniEvReset)
1013 }
1014 }(pConfigAniStateAFsm)
1015 return
1016 }
1017 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001018 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001019 oFsm.mutexPLastTxMeInstance.Unlock()
1020
mpagenko8b07c1b2020-11-26 10:36:31 +00001021}
1022
dbainbri4d3a0dc2020-12-02 00:33:42 +00001023func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1024 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001025 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1026
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001027 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001028 meInstance, err := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001029 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001030 if err != nil {
1031 logger.Errorw(ctx, "MBPConfigData delete failed, aborting uniPonAniConfigFsm!",
1032 log.Fields{"device-id": oFsm.deviceID})
1033 pConfigAniStateAFsm := oFsm.pAdaptFsm
1034 if pConfigAniStateAFsm != nil {
1035 oFsm.mutexPLastTxMeInstance.Unlock()
1036 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1037 go func(aPAFsm *AdapterFsm) {
1038 if aPAFsm != nil && aPAFsm.pFsm != nil {
1039 _ = aPAFsm.pFsm.Event(aniEvReset)
1040 }
1041 }(pConfigAniStateAFsm)
1042 return
1043 }
1044 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001045 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001046 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001047}
1048
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1050 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001051 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1052 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001053 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001054 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001055 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +00001056 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001057 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1058 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001059 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001060 }
1061
1062 //let's reset the state machine in order to release all resources now
1063 pConfigAniStateAFsm := oFsm.pAdaptFsm
1064 if pConfigAniStateAFsm != nil {
1065 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1066 go func(aPAFsm *AdapterFsm) {
1067 if aPAFsm != nil && aPAFsm.pFsm != nil {
1068 _ = aPAFsm.pFsm.Event(aniEvReset)
1069 }
1070 }(pConfigAniStateAFsm)
1071 }
1072}
1073
dbainbri4d3a0dc2020-12-02 00:33:42 +00001074func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1075 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001076 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001077
mpagenko45cc6a32021-07-23 10:06:57 +00001078 if oFsm.isChanSet() {
1079 // indicate processing error to the caller (in case there was still some open request)
1080 logger.Debugw(ctx, "uniPonAniConfigFsm processingError on channel", log.Fields{
1081 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1082 //use non-blocking channel send to avoid blocking because of non-existing receiver
1083 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1084 select {
1085 case oFsm.chSuccess <- 0:
1086 default:
1087 logger.Debugw(ctx, "uniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
1088 "device-id": oFsm.deviceID})
1089 }
1090 oFsm.setChanSet(false) //reset the internal channel state
1091 }
1092
mpagenko3dbcdd22020-07-22 07:38:45 +00001093 pConfigAniStateAFsm := oFsm.pAdaptFsm
1094 if pConfigAniStateAFsm != nil {
1095 // abort running message processing
1096 fsmAbortMsg := Message{
1097 Type: TestMsg,
1098 Data: TestMessage{
1099 TestMessageVal: AbortMessageProcessing,
1100 },
1101 }
1102 pConfigAniStateAFsm.commChan <- fsmAbortMsg
1103
1104 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +05301105 go func(aPAFsm *AdapterFsm) {
1106 if aPAFsm != nil && aPAFsm.pFsm != nil {
1107 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001108 }
1109 }(pConfigAniStateAFsm)
1110 }
1111}
1112
dbainbri4d3a0dc2020-12-02 00:33:42 +00001113func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1114 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001115 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001116 oFsm.mutexPLastTxMeInstance.Lock()
1117 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001118 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001119}
1120
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1122 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001123loop:
1124 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001125 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001126 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001127 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301128 message, ok := <-oFsm.pAdaptFsm.commChan
1129 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301131 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1132 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1133 break loop
1134 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001135 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301136
1137 switch message.Type {
1138 case TestMsg:
1139 msg, _ := message.Data.(TestMessage)
1140 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001141 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001142 break loop
1143 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301145 case OMCI:
1146 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301148 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301150 "message.Type": message.Type})
1151 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001152
Himani Chawla4d908332020-08-31 12:30:20 +05301153 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301155}
1156
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301158 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1159 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001160 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001161 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301162 return
1163 }
1164 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1165 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001166 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001167 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301168 return
1169 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001170 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001171 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1172 //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 +00001173 oFsm.mutexPLastTxMeInstance.RLock()
1174 if oFsm.pLastTxMeInstance != nil {
1175 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1176 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1177 // maybe we can use just the same eventName for different state transitions like "forward"
1178 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1179 switch oFsm.pLastTxMeInstance.GetName() {
1180 case "Ieee8021PMapperServiceProfile":
1181 { // let the FSM proceed ...
1182 oFsm.mutexPLastTxMeInstance.RUnlock()
1183 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
1184 }
1185 case "MacBridgePortConfigurationData":
1186 { // let the FSM proceed ...
1187 oFsm.mutexPLastTxMeInstance.RUnlock()
1188 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
1189 }
1190 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1191 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1192 oFsm.mutexPLastTxMeInstance.RUnlock()
1193 oFsm.omciMIdsResponseReceived <- true
1194 }
1195 default:
1196 {
1197 oFsm.mutexPLastTxMeInstance.RUnlock()
1198 logger.Warnw(ctx, "Unsupported ME name received!",
1199 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1200 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001201 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001202 } else {
1203 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001204 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001205 } else {
1206 oFsm.mutexPLastTxMeInstance.RUnlock()
1207 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001208 }
1209 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001210 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1211 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301212 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1213 return
1214 }
Himani Chawla4d908332020-08-31 12:30:20 +05301215}
Mahir Gunyel01034b62021-06-29 11:25:09 -07001216func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
1217 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1218 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1219 oFsm.mutexPLastTxMeInstance.RLock()
1220 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1221 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1222 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1223 switch oFsm.pLastTxMeInstance.GetName() {
1224 case "TCont":
1225 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1226 //We should revert DB
1227 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1228 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1229 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
1230 if pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false); pDevEntry != nil {
1231 pDevEntry.freeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
1232 } else {
1233 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1234 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1235 }
1236 }
1237 default:
1238 logger.Warnw(ctx, "Unsupported ME name received with error!",
1239 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1240 }
1241 }
1242}
dbainbri4d3a0dc2020-12-02 00:33:42 +00001243func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301244 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1245 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001246 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001247 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301248 return
1249 }
1250 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1251 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001253 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301254 return
1255 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301257 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001258 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001259 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301260 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001261
Mahir Gunyel01034b62021-06-29 11:25:09 -07001262 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301263 return
1264 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001265 oFsm.mutexPLastTxMeInstance.RLock()
1266 if oFsm.pLastTxMeInstance != nil {
1267 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1268 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1269 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1270 // if, then something like:
1271 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301272
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001273 switch oFsm.pLastTxMeInstance.GetName() {
1274 case "TCont":
1275 { // let the FSM proceed ...
1276 oFsm.mutexPLastTxMeInstance.RUnlock()
1277 if oFsm.requestEventOffset == 0 { //from TCont config request
1278 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
1279 } else { // from T-Cont reset request
1280 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
1281 }
1282 }
1283 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1284 { // let the PrioQueue init proceed by stopping the wait function
1285 oFsm.mutexPLastTxMeInstance.RUnlock()
1286 oFsm.omciMIdsResponseReceived <- true
1287 }
1288 case "Ieee8021PMapperServiceProfile":
1289 { // let the FSM proceed ...
1290 oFsm.mutexPLastTxMeInstance.RUnlock()
1291 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
1292 }
1293 default:
1294 {
1295 oFsm.mutexPLastTxMeInstance.RUnlock()
1296 logger.Warnw(ctx, "Unsupported ME name received!",
1297 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001298 }
Himani Chawla4d908332020-08-31 12:30:20 +05301299 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001300 } else {
1301 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301302 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001303 } else {
1304 oFsm.mutexPLastTxMeInstance.RUnlock()
1305 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301306 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001307}
1308
dbainbri4d3a0dc2020-12-02 00:33:42 +00001309func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001310 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1311 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001312 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001313 log.Fields{"device-id": oFsm.deviceID})
1314 return
1315 }
1316 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1317 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001318 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001319 log.Fields{"device-id": oFsm.deviceID})
1320 return
1321 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001322 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001323 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001324 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001325 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1326 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1327 // store error for mgmt display?
1328 return
1329 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001330 oFsm.mutexPLastTxMeInstance.RLock()
1331 if oFsm.pLastTxMeInstance != nil {
1332 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1333 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1334 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1335 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001336
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001337 switch oFsm.pLastTxMeInstance.GetName() {
1338 case "GemInterworkingTerminationPoint":
1339 { // let the FSM proceed ...
1340 oFsm.mutexPLastTxMeInstance.RUnlock()
1341 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
1342 }
1343 case "GemPortNetworkCtp":
1344 { // let the FSM proceed ...
1345 oFsm.mutexPLastTxMeInstance.RUnlock()
1346 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
1347 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001348 case "TrafficDescriptor":
1349 { // let the FSM proceed ...
1350 oFsm.mutexPLastTxMeInstance.RUnlock()
1351 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemTdResp)
1352 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001353 case "Ieee8021PMapperServiceProfile":
1354 { // let the FSM proceed ...
1355 oFsm.mutexPLastTxMeInstance.RUnlock()
1356 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
1357 }
1358 case "MacBridgePortConfigurationData":
1359 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1360 oFsm.mutexPLastTxMeInstance.RUnlock()
1361 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
1362 }
1363 default:
1364 {
1365 oFsm.mutexPLastTxMeInstance.RUnlock()
1366 logger.Warnw(ctx, "Unsupported ME name received!",
1367 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1368 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001369 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001370 } else {
1371 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001372 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001373 } else {
1374 oFsm.mutexPLastTxMeInstance.RUnlock()
1375 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001376 }
1377}
1378
dbainbri4d3a0dc2020-12-02 00:33:42 +00001379func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
1380 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001381 "msgType": msg.OmciMsg.MessageType})
1382
1383 switch msg.OmciMsg.MessageType {
1384 case omci.CreateResponseType:
1385 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001386 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301387
mpagenko3dbcdd22020-07-22 07:38:45 +00001388 } //CreateResponseType
1389 case omci.SetResponseType:
1390 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001391 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001392
mpagenko3dbcdd22020-07-22 07:38:45 +00001393 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001394 case omci.DeleteResponseType:
1395 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001396 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001397
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001398 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001399 default:
1400 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001401 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001402 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001403 return
1404 }
1405 }
1406}
1407
dbainbri4d3a0dc2020-12-02 00:33:42 +00001408func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001409 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1410 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001411 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001412 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1413 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001414 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001415 meParams := me.ParamData{
1416 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1417 Attributes: me.AttributeValueMap{
1418 "PortId": gemPortAttribs.gemPortID,
1419 "TContPointer": oFsm.tcont0ID,
1420 "Direction": gemPortAttribs.direction,
1421 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1422 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1423 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1424 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1425 },
1426 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001427 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001428 meInstance, err := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001429 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001430 if err != nil {
1431 oFsm.mutexPLastTxMeInstance.Unlock()
1432 logger.Errorw(ctx, "GemNCTPVar create failed, aborting uniPonAniConfigFsm!",
1433 log.Fields{"device-id": oFsm.deviceID})
1434 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1435 return
1436 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001437 //accept also nil as (error) return value for writing to LastTx
1438 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001439 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001440 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001441 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001442 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001443 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001445 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301446 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001447 return
1448 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001449 // Mark the gem port to be added for Performance History monitoring
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001450 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -07001451 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001452 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001453 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001454
1455 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301457 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001458}
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001459func (oFsm *uniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
1460 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1461 if gemPortAttribs.isMulticast {
1462 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1463 return true
1464 }
1465 }
1466 return false
1467}
mpagenko3dbcdd22020-07-22 07:38:45 +00001468
dbainbri4d3a0dc2020-12-02 00:33:42 +00001469func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001470 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1471 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001472 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001473 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1474 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001475 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001476
ozgecanetsia4b232302020-11-11 10:58:10 +03001477 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1478 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001479
1480 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001481 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001482 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001483 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001484 "InterworkingOption": 0, // Don't Care
1485 "ServiceProfilePointer": 0, // Don't Care
1486 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001487 },
1488 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001489 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1490 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1491 continue
1492 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001493 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001494 meInstance, err := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsia4b232302020-11-11 10:58:10 +03001495 true, oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001496 if err != nil {
1497 oFsm.mutexPLastTxMeInstance.Unlock()
1498 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting uniPonAniConfigFsm!",
1499 log.Fields{"device-id": oFsm.deviceID})
1500 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1501 return
1502
1503 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001504 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001505 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001506 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001507 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001508 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001509 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001510 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1511 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1512 return
1513 }
1514 ipv4MulticastTable := make([]uint8, 12)
1515 //Gem Port ID
1516 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1517 //Secondary Key
1518 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1519 // Multicast IP range start This is the 224.0.0.1 address
1520 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1521 // MulticastIp range stop
1522 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1523
1524 meIPV4MCTableParams := me.ParamData{
1525 EntityID: gemPortAttribs.multicastGemID,
1526 Attributes: me.AttributeValueMap{
1527 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1528 },
1529 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001530 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001531 meIPV4MCTableInstance, err := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001532 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001533 if err != nil {
1534 oFsm.mutexPLastTxMeInstance.Unlock()
1535 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting uniPonAniConfigFsm!",
1536 log.Fields{"device-id": oFsm.deviceID})
1537 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1538 return
1539 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001540 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001541 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001542
1543 } else {
1544 meParams := me.ParamData{
1545 EntityID: gemPortAttribs.gemPortID,
1546 Attributes: me.AttributeValueMap{
1547 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1548 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1549 "ServiceProfilePointer": oFsm.mapperSP0ID,
1550 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1551 "GalProfilePointer": galEthernetEID,
1552 },
1553 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001554 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001555 meInstance, err := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsia4b232302020-11-11 10:58:10 +03001556 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001557 if err != nil {
1558 oFsm.mutexPLastTxMeInstance.Unlock()
1559 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting uniPonAniConfigFsm!",
1560 log.Fields{"device-id": oFsm.deviceID})
1561 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1562 return
1563 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001564 //accept also nil as (error) return value for writing to LastTx
1565 // - this avoids misinterpretation of new received OMCI messages
1566 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001567 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001568 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001569 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001571 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001573 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301574 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001575 return
1576 }
1577 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001578
1579 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001580 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301581 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001582}
1583
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001585 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1586 if oFsm.tcontSetBefore {
1587 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1588 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
1589 "uni-id": oFsm.pOnuUniPort.uniID,
1590 "techProfile-id": oFsm.techProfileID})
1591 go func(aPAFsm *AdapterFsm) {
1592 if aPAFsm != nil && aPAFsm.pFsm != nil {
1593 _ = aPAFsm.pFsm.Event(aniEvRxPrioqsResp)
1594 }
1595 }(oFsm.pAdaptFsm)
1596 return
1597 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001598 const cu16StrictPrioWeight uint16 = 0xFFFF
1599 //find all upstream PrioQueues related to this T-Cont
1600 loQueueMap := ordered_map.NewOrderedMap()
1601 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001602 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001604 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1605 "prioString": gemPortAttribs.pbitString})
1606 continue
1607 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001608 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301609 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001610 //key does not yet exist
1611 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1612 }
1613 } else {
1614 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1615 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001616 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001617
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001618 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1619 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1620 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1621 // or even be finished without correct SP/WRR setting
1622
1623 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1624 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1625 // even though its T-Cont seems to be wrong ...
1626 loTrafficSchedulerEID := 0x8000
1627 //for all found queues
1628 iter := loQueueMap.IterFunc()
1629 for kv, ok := iter(); ok; kv, ok = iter() {
1630 queueIndex := (kv.Key).(uint16)
1631 meParams := me.ParamData{
1632 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301633 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001634 }
1635 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1636 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001638 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001639 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001640 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1641 } else {
1642 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001644 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1645 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001646 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001647 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1648 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1649 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001650 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001651 meInstance, err := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001652 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001653 if err != nil {
1654 oFsm.mutexPLastTxMeInstance.Unlock()
1655 logger.Errorw(ctx, "PrioQueueVar set failed, aborting uniPonAniConfigFsm!",
1656 log.Fields{"device-id": oFsm.deviceID})
1657 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1658 return
1659 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001660 //accept also nil as (error) return value for writing to LastTx
1661 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001662 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001663 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001664
1665 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001666 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001667 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001669 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301670 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001671 return
1672 }
1673
1674 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1675 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1676 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1677 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1678
1679 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001680
1681 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301683 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001684}
1685
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001687 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001688 if oFsm.isCanceled {
1689 // FSM already canceled before entering wait
1690 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
1691 oFsm.mutexIsAwaitingResponse.Unlock()
1692 return fmt.Errorf(cErrWaitAborted)
1693 }
mpagenko7d6bb022021-03-11 15:07:55 +00001694 oFsm.isAwaitingResponse = true
1695 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001696 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301697 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001698 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001699 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001700 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 +00001701 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001702 oFsm.mutexIsAwaitingResponse.Lock()
1703 oFsm.isAwaitingResponse = false
1704 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001705 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001706 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301707 if success {
mpagenkocf48e452021-04-23 09:23:00 +00001708 logger.Debugw(ctx, "uniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001709 oFsm.mutexIsAwaitingResponse.Lock()
1710 oFsm.isAwaitingResponse = false
1711 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001712 return nil
1713 }
mpagenko7d6bb022021-03-11 15:07:55 +00001714 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00001715 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001716 oFsm.mutexIsAwaitingResponse.Lock()
1717 oFsm.isAwaitingResponse = false
1718 oFsm.mutexIsAwaitingResponse.Unlock()
1719 return fmt.Errorf(cErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001720 }
1721}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001722
1723func (oFsm *uniPonAniConfigFsm) setChanSet(flagValue bool) {
1724 oFsm.mutexChanSet.Lock()
1725 oFsm.chanSet = flagValue
1726 oFsm.mutexChanSet.Unlock()
1727}
1728
1729func (oFsm *uniPonAniConfigFsm) isChanSet() bool {
1730 oFsm.mutexChanSet.RLock()
1731 flagValue := oFsm.chanSet
1732 oFsm.mutexChanSet.RUnlock()
1733 return flagValue
1734}