blob: a3df66167b38507456127af0b70a442fccecc474 [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"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/log"
34 //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"
55 aniEvRemTcontPath = "aniEvRemTcontPath"
56 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
57 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
58 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
59 aniEvTimeoutSimple = "aniEvTimeoutSimple"
60 aniEvTimeoutMids = "aniEvTimeoutMids"
61 aniEvReset = "aniEvReset"
62 aniEvRestart = "aniEvRestart"
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +000063 aniEvSkipOmciConfig = "aniEvSkipOmciConfig"
mpagenko1cc3cb42020-07-27 15:24:38 +000064)
65const (
66 // states of config PON ANI port FSM
67 aniStDisabled = "aniStDisabled"
68 aniStStarting = "aniStStarting"
69 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
70 aniStCreatingMBPCD = "aniStCreatingMBPCD"
71 aniStSettingTconts = "aniStSettingTconts"
72 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
73 aniStCreatingGemIWs = "aniStCreatingGemIWs"
74 aniStSettingPQs = "aniStSettingPQs"
75 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
76 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000077 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080078 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000079 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
80 aniStResetTcont = "aniStResetTcont"
81 aniStRemDot1PMapper = "aniStRemDot1PMapper"
82 aniStRemAniBPCD = "aniStRemAniBPCD"
83 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000084 aniStResetting = "aniStResetting"
85)
Holger Hildebrandt10d98192021-01-27 15:29:31 +000086const cAniFsmIdleState = aniStConfigDone
mpagenko1cc3cb42020-07-27 15:24:38 +000087
Girish Gowdra041dcb32020-11-16 16:54:30 -080088const (
89 tpIDOffset = 64
90)
91
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000092type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030093 gemPortID uint16
94 upQueueID uint16
95 downQueueID uint16
96 direction uint8
97 qosPolicy string
98 weight uint8
99 pbitString string
100 isMulticast bool
101 multicastGemID uint16
102 staticACL string
103 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000104}
105
Himani Chawla6d2ae152020-09-02 13:11:20 +0530106//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
107type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000108 pDeviceHandler *deviceHandler
109 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530110 pOmciCC *omciCC
111 pOnuUniPort *onuUniPort
112 pUniTechProf *onuUniTechProf
113 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800114 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000115 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000116 requestEvent OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000117 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000118 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000119 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530120 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000121 pAdaptFsm *AdapterFsm
122 chSuccess chan<- uint8
123 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000124 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000125 chanSet bool
126 mapperSP0ID uint16
127 macBPCD0ID uint16
128 tcont0ID uint16
129 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000130 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000131 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000132 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000133 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000134 isWaitingForFlowDelete bool
135 waitFlowDeleteChannel chan bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000136}
137
Himani Chawla6d2ae152020-09-02 13:11:20 +0530138//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000139func newUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800140 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000141 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530142 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000143 pDeviceHandler: apDeviceHandler,
144 deviceID: apDeviceHandler.deviceID,
145 pOmciCC: apDevOmciCC,
146 pOnuUniPort: apUniPort,
147 pUniTechProf: apUniTechProf,
148 pOnuDB: apOnuDB,
149 techProfileID: aTechProfileID,
150 requestEvent: aRequestEvent,
151 chanSet: false,
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},
187 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStConfigDone},
188
189 //for removing TCONT related resources
190 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
191 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStRemDot1PMapper},
192 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
193 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
194
195 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
196 aniStRemovingGemIW, aniStRemovingGemNCTP,
197 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000198 {Name: aniEvTimeoutMids, Src: []string{
199 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000200
mpagenko1cc3cb42020-07-27 15:24:38 +0000201 // exceptional treatment for all states except aniStResetting
202 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
203 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
mpagenkobb47bc22021-04-20 13:29:09 +0000204 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP,
mpagenko8b07c1b2020-11-26 10:36:31 +0000205 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000206 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000207 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000208 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000209 },
210
211 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000212 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
213 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
214 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
215 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
216 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
217 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
218 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
219 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
220 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
221 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
222 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000223 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000224 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
225 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
226 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
227 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
228 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
229 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
230 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000231 },
232 )
233 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000234 logger.Errorw(ctx, "uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000235 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000236 return nil
237 }
238
dbainbri4d3a0dc2020-12-02 00:33:42 +0000239 logger.Debugw(ctx, "uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000240 return instFsm
241}
242
Himani Chawla6d2ae152020-09-02 13:11:20 +0530243//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
244func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000245 oFsm.chSuccess = aChSuccess
246 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000247 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000248}
249
mpagenko7d6bb022021-03-11 15:07:55 +0000250//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000251func (oFsm *uniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
252 //early indication about started reset processing
253 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000254 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000255 oFsm.mutexIsAwaitingResponse.Lock()
256 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000257 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000258 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
259 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
260 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000261 //use channel to indicate that the response waiting shall be aborted
262 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000263 } else {
264 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000265 }
mpagenkocf48e452021-04-23 09:23:00 +0000266
267 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000268 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000269 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000270 //use channel to indicate that the response waiting shall be aborted
271 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000272 } else {
273 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000274 }
mpagenkocf48e452021-04-23 09:23:00 +0000275
mpagenko7d6bb022021-03-11 15:07:55 +0000276 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
277 pAdaptFsm := oFsm.pAdaptFsm
278 if pAdaptFsm != nil {
279 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
280 go func(aPAFsm *AdapterFsm) {
281 if aPAFsm.pFsm != nil {
282 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
283 }
284 }(pAdaptFsm)
285 }
mpagenko73143992021-04-09 15:17:10 +0000286
287 //wait for completion of possibly ongoing techprofile config/remove requests to avoid
288 // access conflicts on internal data by next needed data clearance
289 //activity should be aborted in short time if running with FSM due to above FSM reset
290 // or finished without FSM dependency in short time
291 oFsm.pUniTechProf.lockTpProcMutex()
292 defer oFsm.pUniTechProf.unlockTpProcMutex()
293 //remove all TechProf related internal data to allow for new configuration
294 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000295}
296
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530298 if aPAFsm != nil && aPAFsm.pFsm != nil {
299 //stick to pythonAdapter numbering scheme
300 //index 0 in naming refers to possible usage of multiple instances (later)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800301 oFsm.mapperSP0ID = ieeeMapperServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) + uint16(oFsm.techProfileID)
302 oFsm.macBPCD0ID = macBridgePortAniEID + uint16(oFsm.pOnuUniPort.entityID) + uint16(oFsm.techProfileID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530303
Girish Gowdra041dcb32020-11-16 16:54:30 -0800304 /*
305 // Find a free TCONT Instance ID and use it
306 foundFreeTcontInstID := false
307 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.TContClassID); len(tcontInstKeys) > 0 {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800309
310 // FIXME: Ideally the ME configurations on the ONU should constantly be MIB Synced back to the ONU DB
311 // So, as soon as we use up a TCONT Entity on the ONU, the DB at ONU adapter should know that the TCONT
312 // entity is used up via MIB Sync procedure and it will not use it for subsequent TCONT on that ONU.
313 // But, it seems, due to the absence of the constant mib-sync procedure, the TCONT Entities show up as
314 // free even though they are already reserved on the ONU. It seems the mib is synced only once, initially
315 // when the ONU is discovered.
316 /*
317 for _, tcontInstID := range tcontInstKeys {
318 tconInst := oFsm.pOnuDB.GetMe(me.TContClassID, tcontInstID)
319 returnVal := tconInst["AllocId"]
320 if returnVal != nil {
321 if allocID, err := oFsm.pOnuDB.getUint16Attrib(returnVal); err == nil {
322 // If the TCONT Instance ID is set to 0xff or 0xffff, it means it is free to use.
323 if allocID == 0xff || allocID == 0xffff {
324 foundFreeTcontInstID = true
325 oFsm.tcont0ID = uint16(tcontInstID)
326 logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
327 "device-id": oFsm.deviceID})
328 break
329 }
330 } else {
331 logger.Errorw("error-converting-alloc-id-to-uint16", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
332 }
333 } else {
334 logger.Errorw("error-extracting-alloc-id-attribute", log.Fields{"device-id": oFsm.deviceID, "tcont-inst": tcontInstID})
335 }
336 }
337 */
338
339 // Ensure that the techProfileID is in a valid range so that we can allocate a free Tcont for it.
340 if oFsm.techProfileID >= tpIDOffset && oFsm.techProfileID < uint8(tpIDOffset+len(tcontInstKeys)) {
341 // For now, as a dirty workaround, use the tpIDOffset to index the TcontEntityID to be used.
342 // The first TP ID for the ONU will get the first TcontEntityID, the next will get second and so on.
343 // Here the assumption is TP ID will always start from 64 (this is also true to Technology Profile Specification) and the
344 // TP ID will increment in single digit
345 oFsm.tcont0ID = tcontInstKeys[oFsm.techProfileID-tpIDOffset]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Debugw(ctx, "Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800347 "device-id": oFsm.deviceID})
348 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Errorw(ctx, "tech profile id not in valid range", log.Fields{"device-id": oFsm.deviceID, "tp-id": oFsm.techProfileID, "num-tcont": len(tcontInstKeys)})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000350 if oFsm.isChanSet() {
Girish Gowdra041dcb32020-11-16 16:54:30 -0800351 // indicate processing error/abort to the caller
352 oFsm.chSuccess <- 0
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000353 oFsm.setChanSet(false) //reset the internal channel state
Girish Gowdra041dcb32020-11-16 16:54:30 -0800354 }
355 //reset the state machine to enable usage on subsequent requests
356 _ = aPAFsm.pFsm.Event(aniEvReset)
357 return
358 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000360 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800361 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800363 /*
364 if !foundFreeTcontInstID {
365 // This should never happen. If it does, the behavior is unpredictable.
366 logger.Warnw("No free TCONT instances found", log.Fields{"device-id": oFsm.deviceID})
367 }*/
368
369 // Access critical state with lock
370 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000371 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
372 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
Girish Gowdra041dcb32020-11-16 16:54:30 -0800373 oFsm.pUniTechProf.mutexTPState.Unlock()
374
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800376 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300377 loGemPortAttribs := ponAniGemPortAttribs{}
378
Himani Chawla26e555c2020-08-31 12:30:20 +0530379 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
380
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530382
383 loGemPortAttribs.gemPortID = gemEntry.gemPortID
384 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
385 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
386 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
387 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
388
389 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
390 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
391 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
392 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
393 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
394 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
395
396 usQueueFound := false
397 dsQueueFound := false
398 for _, mgmtEntityID := range queueInstKeys {
399 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
400 returnVal := meAttributes["RelatedPort"]
401 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530402 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530403 if relatedPort == usQrelPortMask {
404 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000405 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000406 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530407 usQueueFound = true
408 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
409 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000410 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000411 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 dsQueueFound = true
413 }
414 if usQueueFound && dsQueueFound {
415 break
416 }
417 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 }
420 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 }
423 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000425 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530426 }
427 }
428 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530430 }
431 loGemPortAttribs.direction = gemEntry.direction
432 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
433 loGemPortAttribs.weight = gemEntry.queueWeight
434 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia4b232302020-11-11 10:58:10 +0300435 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300436 //TODO this might effectively ignore the for loop starting at line 316
437 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300438 loGemPortAttribs.isMulticast = true
439 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
440 loGemPortAttribs.staticACL = gemEntry.staticACL
441 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530442
dbainbri4d3a0dc2020-12-02 00:33:42 +0000443 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300444 "gemPortID": loGemPortAttribs.gemPortID,
445 "isMulticast": loGemPortAttribs.isMulticast,
446 "multicastGemID": loGemPortAttribs.multicastGemID,
447 "staticACL": loGemPortAttribs.staticACL,
448 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000449 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300450 })
451
452 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000453 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300454 "gemPortID": loGemPortAttribs.gemPortID,
455 "upQueueID": loGemPortAttribs.upQueueID,
456 "downQueueID": loGemPortAttribs.downQueueID,
457 "pbitString": loGemPortAttribs.pbitString,
458 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000459 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300460 })
461 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530462
463 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
464 }
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000465 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
466 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
467 } else {
468 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
469 _ = aPAFsm.pFsm.Event(aniEvSkipOmciConfig)
470 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530471 }
472}
473
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
475 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000476 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000477 // in case the used channel is not yet defined (can be re-used after restarts)
478 if oFsm.omciMIdsResponseReceived == nil {
479 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000481 } else {
482 // as we may 're-use' this instance of FSM and the connected channel
483 // make sure there is no 'lingering' request in the already existing channel:
484 // (simple loop sufficient as we are the only receiver)
485 for len(oFsm.omciMIdsResponseReceived) > 0 {
486 <-oFsm.omciMIdsResponseReceived
487 }
488 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000489 //ensure internal slices are empty (which might be set from previous run) - release memory
490 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000491 oFsm.mutexIsAwaitingResponse.Lock()
492 //reset the canceled state possibly existing from previous reset
493 oFsm.isCanceled = false
494 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000495
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000496 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000497 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000498
499 //let the state machine run forward from here directly
500 pConfigAniStateAFsm := oFsm.pAdaptFsm
501 if pConfigAniStateAFsm != nil {
502 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000503 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000504
mpagenko3dbcdd22020-07-22 07:38:45 +0000505 }
506}
507
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
509 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000510 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000511 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
512 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000513 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300514 meInstance, err := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000515 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300516 if err != nil {
517 logger.Errorw(ctx, "Dot1PMapper create failed, aborting uniPonAniConfigFsm!",
518 log.Fields{"device-id": oFsm.deviceID})
519 pConfigAniStateAFsm := oFsm.pAdaptFsm
520 if pConfigAniStateAFsm != nil {
521 oFsm.mutexPLastTxMeInstance.Unlock()
522 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
523 go func(aPAFsm *AdapterFsm) {
524 if aPAFsm != nil && aPAFsm.pFsm != nil {
525 _ = aPAFsm.pFsm.Event(aniEvReset)
526 }
527 }(pConfigAniStateAFsm)
528 return
529 }
530 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000531 //accept also nil as (error) return value for writing to LastTx
532 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000533 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300534 oFsm.mutexPLastTxMeInstance.Unlock()
535
mpagenko3dbcdd22020-07-22 07:38:45 +0000536}
537
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
539 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000540 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
541 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000542 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000543 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
544 meParams := me.ParamData{
545 EntityID: oFsm.macBPCD0ID,
546 Attributes: me.AttributeValueMap{
547 "BridgeIdPointer": bridgePtr,
548 "PortNum": 0xFF, //fixed unique ANI side indication
549 "TpType": 3, //for .1PMapper
550 "TpPointer": oFsm.mapperSP0ID,
551 },
552 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000553 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300554 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000555 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300556 if err != nil {
557 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting uniPonAniConfigFsm!",
558 log.Fields{"device-id": oFsm.deviceID})
559 pConfigAniStateAFsm := oFsm.pAdaptFsm
560 if pConfigAniStateAFsm != nil {
561 oFsm.mutexPLastTxMeInstance.Unlock()
562 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
563 go func(aPAFsm *AdapterFsm) {
564 if aPAFsm != nil && aPAFsm.pFsm != nil {
565 _ = aPAFsm.pFsm.Event(aniEvReset)
566 }
567 }(pConfigAniStateAFsm)
568 return
569 }
570 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000571 //accept also nil as (error) return value for writing to LastTx
572 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000573 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300574 oFsm.mutexPLastTxMeInstance.Unlock()
575
mpagenko3dbcdd22020-07-22 07:38:45 +0000576}
577
dbainbri4d3a0dc2020-12-02 00:33:42 +0000578func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
579 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000580 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
581 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000582 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000583 meParams := me.ParamData{
584 EntityID: oFsm.tcont0ID,
585 Attributes: me.AttributeValueMap{
586 "AllocId": oFsm.alloc0ID,
587 },
588 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000589 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300590 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000591 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300592 if err != nil {
593 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
594 log.Fields{"device-id": oFsm.deviceID})
595 pConfigAniStateAFsm := oFsm.pAdaptFsm
596 if pConfigAniStateAFsm != nil {
597 oFsm.mutexPLastTxMeInstance.Unlock()
598 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
599 go func(aPAFsm *AdapterFsm) {
600 if aPAFsm != nil && aPAFsm.pFsm != nil {
601 _ = aPAFsm.pFsm.Event(aniEvReset)
602 }
603 }(pConfigAniStateAFsm)
604 return
605 }
606 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000607 //accept also nil as (error) return value for writing to LastTx
608 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000609 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300610 oFsm.mutexPLastTxMeInstance.Unlock()
611
mpagenko3dbcdd22020-07-22 07:38:45 +0000612}
613
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
615 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000616 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000618}
619
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
621 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000622 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000624}
625
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
627 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000628 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000630}
631
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300633
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000635 "toGemIw": 1024, /* cmp above */
636 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000637
dbainbri4d3a0dc2020-12-02 00:33:42 +0000638 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000639 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000640 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000641
mpagenko3dbcdd22020-07-22 07:38:45 +0000642 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000643 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530644 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000645 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000646
647 //assign the GemPorts according to the configured Prio
648 var loPrioGemPortArray [8]uint16
649 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300650 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000651 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300652 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
653 "prioString": gemPortAttribs.pbitString})
654 continue
655 }
656 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300658 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
659 "prioString": gemPortAttribs.pbitString})
660 continue
661 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000662 for i := 0; i < 8; i++ {
663 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
664 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
665 if prio == 1 { // Check this p-bit is set
666 if loPrioGemPortArray[i] == 0 {
667 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
668 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000669 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000670 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000671 "SetGemPort": loPrioGemPortArray[i]})
672 }
673 }
674 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000676 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000677 "prioString": gemPortAttribs.pbitString, "position": i})
678 }
679
680 }
681 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300682
ozgecanetsia4b232302020-11-11 10:58:10 +0300683 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530684 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300685 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530686 if value != 0 {
687 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530688 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000689 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000690 "for Prio": index,
691 "IwPtr": strconv.FormatInt(int64(value), 16),
692 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300693 } else {
694 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000695 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
696 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300697 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530698 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000699 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300700 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000701 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
702 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300703 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530704
705 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000707 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300708 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
709 // 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 +0000710 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300711 //pConfigAniStateAFsm := oFsm.pAdaptFsm
712 //if pConfigAniStateAFsm != nil {
713 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
714 // go func(aPAFsm *AdapterFsm) {
715 // if aPAFsm != nil && aPAFsm.pFsm != nil {
716 // _ = aPAFsm.pFsm.Event(aniEvReset)
717 // }
718 // }(pConfigAniStateAFsm)
719 //}
720 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000721 pConfigAniStateAFsm := oFsm.pAdaptFsm
722 if pConfigAniStateAFsm != nil {
723 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530724 go func(aPAFsm *AdapterFsm) {
725 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300726 _ = aPAFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000727 }
728 }(pConfigAniStateAFsm)
729 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300730 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000731 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300732 meInstance, err := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300733 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300734 if err != nil {
735 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting uniPonAniConfigFsm!",
736 log.Fields{"device-id": oFsm.deviceID})
737 pConfigAniStateAFsm := oFsm.pAdaptFsm
738 if pConfigAniStateAFsm != nil {
739 oFsm.mutexPLastTxMeInstance.Unlock()
740 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
741 go func(aPAFsm *AdapterFsm) {
742 if aPAFsm != nil && aPAFsm.pFsm != nil {
743 _ = aPAFsm.pFsm.Event(aniEvReset)
744 }
745 }(pConfigAniStateAFsm)
746 return
747 }
748 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300749 //accept also nil as (error) return value for writing to LastTx
750 // - this avoids misinterpretation of new received OMCI messages
751 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300752 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000753 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000754}
755
dbainbri4d3a0dc2020-12-02 00:33:42 +0000756func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
757 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000758 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000759 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800760 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000761 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
762 //use DeviceHandler event notification directly
763 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
764 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
765 // but only in case the techProfile was configured (not deleted)
766 if oFsm.requestEventOffset == 0 {
767 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
768 }
769 } else {
770 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000771 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000772 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000773 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000774 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000775 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
776 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000777 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000778 }
mpagenko01e726e2020-10-23 09:45:29 +0000779
780 //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 +0000781}
782
dbainbri4d3a0dc2020-12-02 00:33:42 +0000783func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenkoa23a6292021-02-23 10:40:10 +0000784 oFsm.pUniTechProf.mutexTPState.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000785 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
786 select {
787 case <-oFsm.waitFlowDeleteChannel:
788 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
789 default:
790 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000791
792 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID] != nil {
793 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
794 oFsm.pUniTechProf.mutexTPState.Unlock()
795 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
796 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
797 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
798 pConfigAniStateAFsm := oFsm.pAdaptFsm
799 if pConfigAniStateAFsm != nil {
800 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
801 go func(aPAFsm *AdapterFsm) {
802 if aPAFsm != nil && aPAFsm.pFsm != nil {
803 _ = aPAFsm.pFsm.Event(aniEvWaitFlowRem)
804 }
805 }(pConfigAniStateAFsm)
806 } else {
807 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
808 }
809 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800810 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000811 } else {
812 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
813 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800814 }
815
mpagenko8b07c1b2020-11-26 10:36:31 +0000816 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000817 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
818 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000820 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
821 "GemIwTp-entity-id": loGemPortID})
822 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
823
824 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000825 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300826 meInstance, err := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000827 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300828 if err != nil {
829 logger.Errorw(ctx, "GemIWTP delete failed, aborting uniPonAniConfigFsm!",
830 log.Fields{"device-id": oFsm.deviceID})
831 pConfigAniStateAFsm := oFsm.pAdaptFsm
832 if pConfigAniStateAFsm != nil {
833 oFsm.mutexPLastTxMeInstance.Unlock()
834 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
835 go func(aPAFsm *AdapterFsm) {
836 if aPAFsm != nil && aPAFsm.pFsm != nil {
837 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
838 }
839 }(pConfigAniStateAFsm)
840 return
841 }
842 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000843 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300844 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000845}
846
mpagenkobb47bc22021-04-20 13:29:09 +0000847func (oFsm *uniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
848 oFsm.mutexIsAwaitingResponse.Lock()
849 oFsm.isWaitingForFlowDelete = true
850 oFsm.mutexIsAwaitingResponse.Unlock()
851 select {
852 // maybe be also some outside cancel (but no context modeled for the moment ...)
853 // case <-ctx.Done():
854 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000855 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 +0000856 logger.Warnw(ctx, "uniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
857 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
858 oFsm.mutexIsAwaitingResponse.Lock()
859 oFsm.isWaitingForFlowDelete = false
860 oFsm.mutexIsAwaitingResponse.Unlock()
861 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
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 case success := <-oFsm.waitFlowDeleteChannel:
877 if success {
878 logger.Debugw(ctx, "uniPonAniConfigFsm flow removed info received", log.Fields{
879 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
880 oFsm.mutexIsAwaitingResponse.Lock()
881 oFsm.isWaitingForFlowDelete = false
882 oFsm.mutexIsAwaitingResponse.Unlock()
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 {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300888 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000889 }
890 }(pConfigAniStateAFsm)
891 } else {
892 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
893 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
894 }
895 return
896 }
897 // waiting was aborted (probably on external request)
898 logger.Debugw(ctx, "uniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
899 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
900 oFsm.mutexIsAwaitingResponse.Lock()
901 oFsm.isWaitingForFlowDelete = false
902 oFsm.mutexIsAwaitingResponse.Unlock()
903 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
904 pConfigAniStateAFsm := oFsm.pAdaptFsm
905 if pConfigAniStateAFsm != nil {
906 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
907 go func(aPAFsm *AdapterFsm) {
908 if aPAFsm != nil && aPAFsm.pFsm != nil {
909 _ = aPAFsm.pFsm.Event(aniEvReset)
910 }
911 }(pConfigAniStateAFsm)
912 }
913 return
914 }
915}
916
dbainbri4d3a0dc2020-12-02 00:33:42 +0000917func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko8b07c1b2020-11-26 10:36:31 +0000918 oFsm.pUniTechProf.mutexTPState.Lock()
919 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
920 oFsm.pUniTechProf.mutexTPState.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000921 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000922 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
923 "GemNCTP-entity-id": loGemPortID})
924 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000925 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300926 meInstance, err := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000927 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300928 if err != nil {
929 logger.Errorw(ctx, "GemNCTP delete failed, aborting uniPonAniConfigFsm!",
930 log.Fields{"device-id": oFsm.deviceID})
931 pConfigAniStateAFsm := oFsm.pAdaptFsm
932 if pConfigAniStateAFsm != nil {
933 oFsm.mutexPLastTxMeInstance.Unlock()
934 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
935 go func(aPAFsm *AdapterFsm) {
936 if aPAFsm != nil && aPAFsm.pFsm != nil {
937 _ = aPAFsm.pFsm.Event(aniEvReset)
938 }
939 }(pConfigAniStateAFsm)
940 return
941 }
942 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000943 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000944 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300945
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800946 // Mark the gem port to be removed for Performance History monitoring
947 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -0700948 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800949 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000950}
951
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
953 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000954 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
955
956 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
957 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
958 meParams := me.ParamData{
959 EntityID: oFsm.tcont0ID,
960 Attributes: me.AttributeValueMap{
961 "AllocId": unusedTcontAllocID,
962 },
963 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000964 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300965 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000966 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300967 if err != nil {
968 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
969 log.Fields{"device-id": oFsm.deviceID})
970 pConfigAniStateAFsm := oFsm.pAdaptFsm
971 if pConfigAniStateAFsm != nil {
972 oFsm.mutexPLastTxMeInstance.Unlock()
973 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
974 go func(aPAFsm *AdapterFsm) {
975 if aPAFsm != nil && aPAFsm.pFsm != nil {
976 _ = aPAFsm.pFsm.Event(aniEvReset)
977 }
978 }(pConfigAniStateAFsm)
979 return
980 }
981 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000982 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300983 oFsm.mutexPLastTxMeInstance.Unlock()
984
mpagenko8b07c1b2020-11-26 10:36:31 +0000985}
986
dbainbri4d3a0dc2020-12-02 00:33:42 +0000987func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
988 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000989 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
990
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000991 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300992 meInstance, err := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000993 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300994 if err != nil {
995 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting uniPonAniConfigFsm!",
996 log.Fields{"device-id": oFsm.deviceID})
997 pConfigAniStateAFsm := oFsm.pAdaptFsm
998 if pConfigAniStateAFsm != nil {
999 oFsm.mutexPLastTxMeInstance.Unlock()
1000 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1001 go func(aPAFsm *AdapterFsm) {
1002 if aPAFsm != nil && aPAFsm.pFsm != nil {
1003 _ = aPAFsm.pFsm.Event(aniEvReset)
1004 }
1005 }(pConfigAniStateAFsm)
1006 return
1007 }
1008 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001009 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001010 oFsm.mutexPLastTxMeInstance.Unlock()
1011
mpagenko8b07c1b2020-11-26 10:36:31 +00001012}
1013
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1015 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001016 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1017
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001018 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001019 meInstance, err := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001020 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001021 if err != nil {
1022 logger.Errorw(ctx, "MBPConfigData delete failed, aborting uniPonAniConfigFsm!",
1023 log.Fields{"device-id": oFsm.deviceID})
1024 pConfigAniStateAFsm := oFsm.pAdaptFsm
1025 if pConfigAniStateAFsm != nil {
1026 oFsm.mutexPLastTxMeInstance.Unlock()
1027 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1028 go func(aPAFsm *AdapterFsm) {
1029 if aPAFsm != nil && aPAFsm.pFsm != nil {
1030 _ = aPAFsm.pFsm.Event(aniEvReset)
1031 }
1032 }(pConfigAniStateAFsm)
1033 return
1034 }
1035 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001036 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001037 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001038}
1039
dbainbri4d3a0dc2020-12-02 00:33:42 +00001040func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1041 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001042 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1043 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001045 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001046 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +00001047 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001048 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1049 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001050 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001051 }
1052
1053 //let's reset the state machine in order to release all resources now
1054 pConfigAniStateAFsm := oFsm.pAdaptFsm
1055 if pConfigAniStateAFsm != nil {
1056 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1057 go func(aPAFsm *AdapterFsm) {
1058 if aPAFsm != nil && aPAFsm.pFsm != nil {
1059 _ = aPAFsm.pFsm.Event(aniEvReset)
1060 }
1061 }(pConfigAniStateAFsm)
1062 }
1063}
1064
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1066 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001067 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001068
mpagenko3dbcdd22020-07-22 07:38:45 +00001069 pConfigAniStateAFsm := oFsm.pAdaptFsm
1070 if pConfigAniStateAFsm != nil {
1071 // abort running message processing
1072 fsmAbortMsg := Message{
1073 Type: TestMsg,
1074 Data: TestMessage{
1075 TestMessageVal: AbortMessageProcessing,
1076 },
1077 }
1078 pConfigAniStateAFsm.commChan <- fsmAbortMsg
1079
1080 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +05301081 go func(aPAFsm *AdapterFsm) {
1082 if aPAFsm != nil && aPAFsm.pFsm != nil {
1083 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001084 }
1085 }(pConfigAniStateAFsm)
1086 }
1087}
1088
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1090 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001091 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001092 oFsm.mutexPLastTxMeInstance.Lock()
1093 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001094 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001095}
1096
dbainbri4d3a0dc2020-12-02 00:33:42 +00001097func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1098 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001099loop:
1100 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001101 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001102 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001103 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301104 message, ok := <-oFsm.pAdaptFsm.commChan
1105 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001106 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301107 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1108 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1109 break loop
1110 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301112
1113 switch message.Type {
1114 case TestMsg:
1115 msg, _ := message.Data.(TestMessage)
1116 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001117 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001118 break loop
1119 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301121 case OMCI:
1122 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001123 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301124 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301126 "message.Type": message.Type})
1127 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001128
Himani Chawla4d908332020-08-31 12:30:20 +05301129 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301131}
1132
dbainbri4d3a0dc2020-12-02 00:33:42 +00001133func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301134 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1135 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001136 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001137 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301138 return
1139 }
1140 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1141 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001142 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001143 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301144 return
1145 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001147 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1148 //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 +00001149 oFsm.mutexPLastTxMeInstance.RLock()
1150 if oFsm.pLastTxMeInstance != nil {
1151 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1152 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1153 // maybe we can use just the same eventName for different state transitions like "forward"
1154 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1155 switch oFsm.pLastTxMeInstance.GetName() {
1156 case "Ieee8021PMapperServiceProfile":
1157 { // let the FSM proceed ...
1158 oFsm.mutexPLastTxMeInstance.RUnlock()
1159 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
1160 }
1161 case "MacBridgePortConfigurationData":
1162 { // let the FSM proceed ...
1163 oFsm.mutexPLastTxMeInstance.RUnlock()
1164 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
1165 }
1166 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1167 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1168 oFsm.mutexPLastTxMeInstance.RUnlock()
1169 oFsm.omciMIdsResponseReceived <- true
1170 }
1171 default:
1172 {
1173 oFsm.mutexPLastTxMeInstance.RUnlock()
1174 logger.Warnw(ctx, "Unsupported ME name received!",
1175 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1176 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001177 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001178 } else {
1179 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001180 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001181 } else {
1182 oFsm.mutexPLastTxMeInstance.RUnlock()
1183 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001184 }
1185 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001186 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1187 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301188 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1189 return
1190 }
Himani Chawla4d908332020-08-31 12:30:20 +05301191}
1192
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301194 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1195 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001196 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001197 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301198 return
1199 }
1200 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1201 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001203 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301204 return
1205 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301207 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001208 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001209 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301210 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1211 return
1212 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001213 oFsm.mutexPLastTxMeInstance.RLock()
1214 if oFsm.pLastTxMeInstance != nil {
1215 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1216 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1217 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1218 // if, then something like:
1219 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301220
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001221 switch oFsm.pLastTxMeInstance.GetName() {
1222 case "TCont":
1223 { // let the FSM proceed ...
1224 oFsm.mutexPLastTxMeInstance.RUnlock()
1225 if oFsm.requestEventOffset == 0 { //from TCont config request
1226 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
1227 } else { // from T-Cont reset request
1228 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
1229 }
1230 }
1231 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1232 { // let the PrioQueue init proceed by stopping the wait function
1233 oFsm.mutexPLastTxMeInstance.RUnlock()
1234 oFsm.omciMIdsResponseReceived <- true
1235 }
1236 case "Ieee8021PMapperServiceProfile":
1237 { // let the FSM proceed ...
1238 oFsm.mutexPLastTxMeInstance.RUnlock()
1239 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
1240 }
1241 default:
1242 {
1243 oFsm.mutexPLastTxMeInstance.RUnlock()
1244 logger.Warnw(ctx, "Unsupported ME name received!",
1245 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001246 }
Himani Chawla4d908332020-08-31 12:30:20 +05301247 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001248 } else {
1249 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301250 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001251 } else {
1252 oFsm.mutexPLastTxMeInstance.RUnlock()
1253 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301254 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001255}
1256
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001258 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1259 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001261 log.Fields{"device-id": oFsm.deviceID})
1262 return
1263 }
1264 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1265 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001267 log.Fields{"device-id": oFsm.deviceID})
1268 return
1269 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001270 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001271 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001273 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1274 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1275 // store error for mgmt display?
1276 return
1277 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001278 oFsm.mutexPLastTxMeInstance.RLock()
1279 if oFsm.pLastTxMeInstance != nil {
1280 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1281 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1282 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1283 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001284
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001285 switch oFsm.pLastTxMeInstance.GetName() {
1286 case "GemInterworkingTerminationPoint":
1287 { // let the FSM proceed ...
1288 oFsm.mutexPLastTxMeInstance.RUnlock()
1289 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
1290 }
1291 case "GemPortNetworkCtp":
1292 { // let the FSM proceed ...
1293 oFsm.mutexPLastTxMeInstance.RUnlock()
1294 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
1295 }
1296 case "Ieee8021PMapperServiceProfile":
1297 { // let the FSM proceed ...
1298 oFsm.mutexPLastTxMeInstance.RUnlock()
1299 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
1300 }
1301 case "MacBridgePortConfigurationData":
1302 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1303 oFsm.mutexPLastTxMeInstance.RUnlock()
1304 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
1305 }
1306 default:
1307 {
1308 oFsm.mutexPLastTxMeInstance.RUnlock()
1309 logger.Warnw(ctx, "Unsupported ME name received!",
1310 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1311 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001312 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001313 } else {
1314 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001315 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001316 } else {
1317 oFsm.mutexPLastTxMeInstance.RUnlock()
1318 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001319 }
1320}
1321
dbainbri4d3a0dc2020-12-02 00:33:42 +00001322func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
1323 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001324 "msgType": msg.OmciMsg.MessageType})
1325
1326 switch msg.OmciMsg.MessageType {
1327 case omci.CreateResponseType:
1328 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001329 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301330
mpagenko3dbcdd22020-07-22 07:38:45 +00001331 } //CreateResponseType
1332 case omci.SetResponseType:
1333 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001334 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001335
mpagenko3dbcdd22020-07-22 07:38:45 +00001336 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001337 case omci.DeleteResponseType:
1338 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001339 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001340
1341 } //SetResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001342 default:
1343 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001344 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001345 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001346 return
1347 }
1348 }
1349}
1350
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001352 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1353 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001354 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001355 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1356 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001357 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001358 meParams := me.ParamData{
1359 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1360 Attributes: me.AttributeValueMap{
1361 "PortId": gemPortAttribs.gemPortID,
1362 "TContPointer": oFsm.tcont0ID,
1363 "Direction": gemPortAttribs.direction,
1364 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1365 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1366 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1367 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1368 },
1369 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001370 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001371 meInstance, err := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001372 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001373 if err != nil {
1374 oFsm.mutexPLastTxMeInstance.Unlock()
1375 logger.Errorw(ctx, "GemNCTPVar create failed, aborting uniPonAniConfigFsm!",
1376 log.Fields{"device-id": oFsm.deviceID})
1377 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1378 return
1379 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001380 //accept also nil as (error) return value for writing to LastTx
1381 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001382 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001383 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001384 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001385 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001386 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001387 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001388 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301389 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001390 return
1391 }
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001392 // Mark the gem port to be removed for Performance History monitoring
1393 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -07001394 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001395 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001396 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001397
1398 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301400 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001401}
1402
dbainbri4d3a0dc2020-12-02 00:33:42 +00001403func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001404 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1405 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001406 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001407 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1408 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001409 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001410
ozgecanetsia4b232302020-11-11 10:58:10 +03001411 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1412 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001413
1414 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001415 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001416 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001417 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001418 "InterworkingOption": 0, // Don't Care
1419 "ServiceProfilePointer": 0, // Don't Care
1420 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001421 },
1422 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001423 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001424 meInstance, err := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsia4b232302020-11-11 10:58:10 +03001425 true, oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001426 if err != nil {
1427 oFsm.mutexPLastTxMeInstance.Unlock()
1428 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting uniPonAniConfigFsm!",
1429 log.Fields{"device-id": oFsm.deviceID})
1430 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1431 return
1432
1433 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001434 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001435 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001436 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001437 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001438 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001439 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001440 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1441 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1442 return
1443 }
1444 ipv4MulticastTable := make([]uint8, 12)
1445 //Gem Port ID
1446 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1447 //Secondary Key
1448 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1449 // Multicast IP range start This is the 224.0.0.1 address
1450 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1451 // MulticastIp range stop
1452 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1453
1454 meIPV4MCTableParams := me.ParamData{
1455 EntityID: gemPortAttribs.multicastGemID,
1456 Attributes: me.AttributeValueMap{
1457 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1458 },
1459 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001460 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001461 meIPV4MCTableInstance, err := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001462 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001463 if err != nil {
1464 oFsm.mutexPLastTxMeInstance.Unlock()
1465 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting uniPonAniConfigFsm!",
1466 log.Fields{"device-id": oFsm.deviceID})
1467 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1468 return
1469 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001470 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001471 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001472
1473 } else {
1474 meParams := me.ParamData{
1475 EntityID: gemPortAttribs.gemPortID,
1476 Attributes: me.AttributeValueMap{
1477 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1478 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1479 "ServiceProfilePointer": oFsm.mapperSP0ID,
1480 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1481 "GalProfilePointer": galEthernetEID,
1482 },
1483 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001484 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001485 meInstance, err := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsia4b232302020-11-11 10:58:10 +03001486 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001487 if err != nil {
1488 oFsm.mutexPLastTxMeInstance.Unlock()
1489 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting uniPonAniConfigFsm!",
1490 log.Fields{"device-id": oFsm.deviceID})
1491 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1492 return
1493 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001494 //accept also nil as (error) return value for writing to LastTx
1495 // - this avoids misinterpretation of new received OMCI messages
1496 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001497 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001498 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001499 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001501 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001503 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301504 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001505 return
1506 }
1507 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001508
1509 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001510 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301511 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001512}
1513
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001515 const cu16StrictPrioWeight uint16 = 0xFFFF
1516 //find all upstream PrioQueues related to this T-Cont
1517 loQueueMap := ordered_map.NewOrderedMap()
1518 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001519 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001520 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001521 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1522 "prioString": gemPortAttribs.pbitString})
1523 continue
1524 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001525 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301526 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001527 //key does not yet exist
1528 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1529 }
1530 } else {
1531 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1532 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001533 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001534
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001535 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1536 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1537 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1538 // or even be finished without correct SP/WRR setting
1539
1540 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1541 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1542 // even though its T-Cont seems to be wrong ...
1543 loTrafficSchedulerEID := 0x8000
1544 //for all found queues
1545 iter := loQueueMap.IterFunc()
1546 for kv, ok := iter(); ok; kv, ok = iter() {
1547 queueIndex := (kv.Key).(uint16)
1548 meParams := me.ParamData{
1549 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301550 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001551 }
1552 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1553 //StrictPrio indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001555 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001556 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001557 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1558 } else {
1559 //WRR indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001561 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1562 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001563 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001564 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1565 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1566 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001567 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001568 meInstance, err := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001569 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001570 if err != nil {
1571 oFsm.mutexPLastTxMeInstance.Unlock()
1572 logger.Errorw(ctx, "PrioQueueVar set failed, aborting uniPonAniConfigFsm!",
1573 log.Fields{"device-id": oFsm.deviceID})
1574 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1575 return
1576 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001577 //accept also nil as (error) return value for writing to LastTx
1578 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001579 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001580 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001581
1582 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001583 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001584 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001586 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301587 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001588 return
1589 }
1590
1591 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1592 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1593 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1594 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1595
1596 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001597
1598 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301600 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001601}
1602
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001604 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001605 if oFsm.isCanceled {
1606 // FSM already canceled before entering wait
1607 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
1608 oFsm.mutexIsAwaitingResponse.Unlock()
1609 return fmt.Errorf(cErrWaitAborted)
1610 }
mpagenko7d6bb022021-03-11 15:07:55 +00001611 oFsm.isAwaitingResponse = true
1612 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001613 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301614 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001615 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001616 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001617 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 +00001618 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001619 oFsm.mutexIsAwaitingResponse.Lock()
1620 oFsm.isAwaitingResponse = false
1621 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001622 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001623 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301624 if success {
mpagenkocf48e452021-04-23 09:23:00 +00001625 logger.Debugw(ctx, "uniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001626 oFsm.mutexIsAwaitingResponse.Lock()
1627 oFsm.isAwaitingResponse = false
1628 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001629 return nil
1630 }
mpagenko7d6bb022021-03-11 15:07:55 +00001631 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00001632 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001633 oFsm.mutexIsAwaitingResponse.Lock()
1634 oFsm.isAwaitingResponse = false
1635 oFsm.mutexIsAwaitingResponse.Unlock()
1636 return fmt.Errorf(cErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001637 }
1638}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001639
1640func (oFsm *uniPonAniConfigFsm) setChanSet(flagValue bool) {
1641 oFsm.mutexChanSet.Lock()
1642 oFsm.chanSet = flagValue
1643 oFsm.mutexChanSet.Unlock()
1644}
1645
1646func (oFsm *uniPonAniConfigFsm) isChanSet() bool {
1647 oFsm.mutexChanSet.RLock()
1648 flagValue := oFsm.chanSet
1649 oFsm.mutexChanSet.RUnlock()
1650 return flagValue
1651}