blob: a236950b21c11032475126fa44aff25f75b17262 [file] [log] [blame]
mpagenko3dbcdd22020-07-22 07:38:45 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
ozgecanetsia4b232302020-11-11 10:58:10 +030022 "encoding/binary"
Himani Chawla4d908332020-08-31 12:30:20 +053023 "fmt"
ozgecanetsia4b232302020-11-11 10:58:10 +030024 "net"
mpagenko3dbcdd22020-07-22 07:38:45 +000025 "strconv"
mpagenko7d6bb022021-03-11 15:07:55 +000026 "sync"
mpagenko3dbcdd22020-07-22 07:38:45 +000027 "time"
28
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000029 "github.com/cevaris/ordered_map"
mpagenko3dbcdd22020-07-22 07:38:45 +000030 "github.com/looplab/fsm"
mpagenko3dbcdd22020-07-22 07:38:45 +000031 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/log"
34 //ic "github.com/opencord/voltha-protos/v5/go/inter_container"
35 //"github.com/opencord/voltha-protos/v5/go/openflow_13"
36 //"github.com/opencord/voltha-protos/v5/go/voltha"
mpagenko3dbcdd22020-07-22 07:38:45 +000037)
38
mpagenko1cc3cb42020-07-27 15:24:38 +000039const (
40 // events of config PON ANI port FSM
mpagenko8b07c1b2020-11-26 10:36:31 +000041 aniEvStart = "aniEvStart"
42 aniEvStartConfig = "aniEvStartConfig"
43 aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
44 aniEvRxMbpcdResp = "aniEvRxMbpcdResp"
45 aniEvRxTcontsResp = "aniEvRxTcontsResp"
46 aniEvRxGemntcpsResp = "aniEvRxGemntcpsResp"
47 aniEvRxGemiwsResp = "aniEvRxGemiwsResp"
48 aniEvRxPrioqsResp = "aniEvRxPrioqsResp"
49 aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
50 aniEvRemGemiw = "aniEvRemGemiw"
Girish Gowdra26a40922021-01-29 17:14:34 -080051 aniEvWaitFlowRem = "aniEvWaitFlowRem"
52 aniEvFlowRemDone = "aniEvFlowRemDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000053 aniEvRxRemGemiwResp = "aniEvRxRemGemiwResp"
54 aniEvRxRemGemntpResp = "aniEvRxRemGemntpResp"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030055 aniEvRxRemTdResp = "aniEvRxRemTdResp"
mpagenko8b07c1b2020-11-26 10:36:31 +000056 aniEvRemTcontPath = "aniEvRemTcontPath"
57 aniEvRxResetTcontResp = "aniEvRxResetTcontResp"
58 aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
59 aniEvRxRemAniBPCDResp = "aniEvRxRemAniBPCDResp"
60 aniEvTimeoutSimple = "aniEvTimeoutSimple"
61 aniEvTimeoutMids = "aniEvTimeoutMids"
62 aniEvReset = "aniEvReset"
63 aniEvRestart = "aniEvRestart"
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +000064 aniEvSkipOmciConfig = "aniEvSkipOmciConfig"
Mahir Gunyel9545be22021-07-04 15:53:16 -070065 aniEvRemGemDone = "aniEvRemGemDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000066)
67const (
68 // states of config PON ANI port FSM
69 aniStDisabled = "aniStDisabled"
70 aniStStarting = "aniStStarting"
71 aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
72 aniStCreatingMBPCD = "aniStCreatingMBPCD"
73 aniStSettingTconts = "aniStSettingTconts"
74 aniStCreatingGemNCTPs = "aniStCreatingGemNCTPs"
75 aniStCreatingGemIWs = "aniStCreatingGemIWs"
76 aniStSettingPQs = "aniStSettingPQs"
77 aniStSettingDot1PMapper = "aniStSettingDot1PMapper"
78 aniStConfigDone = "aniStConfigDone"
mpagenko8b07c1b2020-11-26 10:36:31 +000079 aniStRemovingGemIW = "aniStRemovingGemIW"
Girish Gowdra26a40922021-01-29 17:14:34 -080080 aniStWaitingFlowRem = "aniStWaitingFlowRem"
mpagenko8b07c1b2020-11-26 10:36:31 +000081 aniStRemovingGemNCTP = "aniStRemovingGemNCTP"
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +030082 aniStRemovingTD = "aniStRemovingTD"
mpagenko8b07c1b2020-11-26 10:36:31 +000083 aniStResetTcont = "aniStResetTcont"
84 aniStRemDot1PMapper = "aniStRemDot1PMapper"
85 aniStRemAniBPCD = "aniStRemAniBPCD"
86 aniStRemoveDone = "aniStRemoveDone"
mpagenko1cc3cb42020-07-27 15:24:38 +000087 aniStResetting = "aniStResetting"
88)
Holger Hildebrandt10d98192021-01-27 15:29:31 +000089const cAniFsmIdleState = aniStConfigDone
mpagenko1cc3cb42020-07-27 15:24:38 +000090
Girish Gowdra09e5f212021-09-30 16:28:36 -070091const (
92 bitTrafficSchedulerPtrSetPermitted = 0x0002 // Refer section 9.1.2 ONU-2G, table for "Quality of service (QoS) configuration flexibility" IE
93)
94
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +000095type ponAniGemPortAttribs struct {
ozgecanetsia4b232302020-11-11 10:58:10 +030096 gemPortID uint16
97 upQueueID uint16
98 downQueueID uint16
99 direction uint8
100 qosPolicy string
101 weight uint8
102 pbitString string
103 isMulticast bool
104 multicastGemID uint16
105 staticACL string
106 dynamicACL string
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000107}
108
Himani Chawla6d2ae152020-09-02 13:11:20 +0530109//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
110type uniPonAniConfigFsm struct {
mpagenko01e726e2020-10-23 09:45:29 +0000111 pDeviceHandler *deviceHandler
112 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530113 pOmciCC *omciCC
114 pOnuUniPort *onuUniPort
115 pUniTechProf *onuUniTechProf
116 pOnuDB *onuDeviceDB
Girish Gowdra041dcb32020-11-16 16:54:30 -0800117 techProfileID uint8
mpagenko8b07c1b2020-11-26 10:36:31 +0000118 uniTpKey uniTP
mpagenko3dbcdd22020-07-22 07:38:45 +0000119 requestEvent OnuDeviceEvent
mpagenko7d6bb022021-03-11 15:07:55 +0000120 mutexIsAwaitingResponse sync.RWMutex
mpagenkocf48e452021-04-23 09:23:00 +0000121 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000122 isAwaitingResponse bool
Himani Chawla4d908332020-08-31 12:30:20 +0530123 omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
mpagenko3dbcdd22020-07-22 07:38:45 +0000124 pAdaptFsm *AdapterFsm
125 chSuccess chan<- uint8
126 procStep uint8
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000127 mutexChanSet sync.RWMutex
mpagenko3dbcdd22020-07-22 07:38:45 +0000128 chanSet bool
129 mapperSP0ID uint16
130 macBPCD0ID uint16
131 tcont0ID uint16
132 alloc0ID uint16
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000133 gemPortAttribsSlice []ponAniGemPortAttribs
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000134 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000135 pLastTxMeInstance *me.ManagedEntity
mpagenko8b07c1b2020-11-26 10:36:31 +0000136 requestEventOffset uint8 //used to indicate ConfigDone or Removed using successor (enum)
mpagenkobb47bc22021-04-20 13:29:09 +0000137 isWaitingForFlowDelete bool
138 waitFlowDeleteChannel chan bool
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700139 tcontSetBefore bool
mpagenko3dbcdd22020-07-22 07:38:45 +0000140}
141
Himani Chawla6d2ae152020-09-02 13:11:20 +0530142//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 +0000143func newUniPonAniConfigFsm(ctx context.Context, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
Girish Gowdra041dcb32020-11-16 16:54:30 -0800144 apOnuDB *onuDeviceDB, aTechProfileID uint8, aRequestEvent OnuDeviceEvent, aName string,
mpagenko01e726e2020-10-23 09:45:29 +0000145 apDeviceHandler *deviceHandler, aCommChannel chan Message) *uniPonAniConfigFsm {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530146 instFsm := &uniPonAniConfigFsm{
mpagenko01e726e2020-10-23 09:45:29 +0000147 pDeviceHandler: apDeviceHandler,
148 deviceID: apDeviceHandler.deviceID,
149 pOmciCC: apDevOmciCC,
150 pOnuUniPort: apUniPort,
151 pUniTechProf: apUniTechProf,
152 pOnuDB: apOnuDB,
153 techProfileID: aTechProfileID,
154 requestEvent: aRequestEvent,
155 chanSet: false,
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700156 tcontSetBefore: false,
mpagenko3dbcdd22020-07-22 07:38:45 +0000157 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000158 instFsm.uniTpKey = uniTP{uniID: apUniPort.uniID, tpID: aTechProfileID}
mpagenkobb47bc22021-04-20 13:29:09 +0000159 instFsm.waitFlowDeleteChannel = make(chan bool)
mpagenko8b07c1b2020-11-26 10:36:31 +0000160
mpagenko01e726e2020-10-23 09:45:29 +0000161 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenko3dbcdd22020-07-22 07:38:45 +0000162 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000163 logger.Errorw(ctx, "uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000164 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000165 return nil
166 }
167
168 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000169 aniStDisabled,
mpagenko3dbcdd22020-07-22 07:38:45 +0000170 fsm.Events{
171
mpagenko1cc3cb42020-07-27 15:24:38 +0000172 {Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000173
174 //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 +0000175 {Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000176 {Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
mpagenko1cc3cb42020-07-27 15:24:38 +0000177 {Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
178 {Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000179 // the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000180 {Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000181 // the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
mpagenko1cc3cb42020-07-27 15:24:38 +0000182 {Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
mpagenko3dbcdd22020-07-22 07:38:45 +0000183 // the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
mpagenko1cc3cb42020-07-27 15:24:38 +0000184 {Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
mpagenkodff5dda2020-08-28 11:52:01 +0000185 {Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000186
mpagenko8b07c1b2020-11-26 10:36:31 +0000187 //for removing Gem related resources
188 {Name: aniEvRemGemiw, Src: []string{aniStConfigDone}, Dst: aniStRemovingGemIW},
Girish Gowdra26a40922021-01-29 17:14:34 -0800189 {Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
190 {Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
mpagenko8b07c1b2020-11-26 10:36:31 +0000191 {Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300192 {Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700193 {Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStRemDot1PMapper},
194 {Name: aniEvRemGemDone, Src: []string{aniStRemDot1PMapper}, Dst: aniStConfigDone},
195 {Name: aniEvRxRem1pMapperResp, Src: []string{aniStRemDot1PMapper}, Dst: aniStRemAniBPCD},
196 {Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000197
198 //for removing TCONT related resources
199 {Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
Mahir Gunyel9545be22021-07-04 15:53:16 -0700200 {Name: aniEvRxResetTcontResp, Src: []string{aniStResetTcont}, Dst: aniStConfigDone},
mpagenko8b07c1b2020-11-26 10:36:31 +0000201
202 {Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300203 aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000204 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
mpagenko1cc3cb42020-07-27 15:24:38 +0000205 {Name: aniEvTimeoutMids, Src: []string{
206 aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000207
mpagenko1cc3cb42020-07-27 15:24:38 +0000208 // exceptional treatment for all states except aniStResetting
209 {Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
210 aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300211 aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
mpagenko8b07c1b2020-11-26 10:36:31 +0000212 aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
mpagenko3dbcdd22020-07-22 07:38:45 +0000213 // the only way to get to resource-cleared disabled state again is via "resseting"
mpagenko1cc3cb42020-07-27 15:24:38 +0000214 {Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000215 {Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
mpagenko3dbcdd22020-07-22 07:38:45 +0000216 },
217
218 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000219 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
220 ("enter_" + aniStStarting): func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
221 ("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
222 ("enter_" + aniStCreatingMBPCD): func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
223 ("enter_" + aniStSettingTconts): func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
224 ("enter_" + aniStCreatingGemNCTPs): func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(ctx, e) },
225 ("enter_" + aniStCreatingGemIWs): func(e *fsm.Event) { instFsm.enterCreatingGemIWs(ctx, e) },
226 ("enter_" + aniStSettingPQs): func(e *fsm.Event) { instFsm.enterSettingPQs(ctx, e) },
227 ("enter_" + aniStSettingDot1PMapper): func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(ctx, e) },
228 ("enter_" + aniStConfigDone): func(e *fsm.Event) { instFsm.enterAniConfigDone(ctx, e) },
229 ("enter_" + aniStRemovingGemIW): func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
mpagenkobb47bc22021-04-20 13:29:09 +0000230 ("enter_" + aniStWaitingFlowRem): func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000231 ("enter_" + aniStRemovingGemNCTP): func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300232 ("enter_" + aniStRemovingTD): func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000233 ("enter_" + aniStResetTcont): func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
234 ("enter_" + aniStRemDot1PMapper): func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
235 ("enter_" + aniStRemAniBPCD): func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
236 ("enter_" + aniStRemoveDone): func(e *fsm.Event) { instFsm.enterAniRemoveDone(ctx, e) },
237 ("enter_" + aniStResetting): func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
238 ("enter_" + aniStDisabled): func(e *fsm.Event) { instFsm.enterDisabledState(ctx, e) },
mpagenko3dbcdd22020-07-22 07:38:45 +0000239 },
240 )
241 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000242 logger.Errorw(ctx, "uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000243 "device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000244 return nil
245 }
246
dbainbri4d3a0dc2020-12-02 00:33:42 +0000247 logger.Debugw(ctx, "uniPonAniConfigFsm created", log.Fields{"device-id": instFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000248 return instFsm
249}
250
Himani Chawla6d2ae152020-09-02 13:11:20 +0530251//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
252func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
mpagenko3dbcdd22020-07-22 07:38:45 +0000253 oFsm.chSuccess = aChSuccess
254 oFsm.procStep = aProcStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000255 oFsm.setChanSet(true)
mpagenko3dbcdd22020-07-22 07:38:45 +0000256}
257
mpagenko7d6bb022021-03-11 15:07:55 +0000258//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000259func (oFsm *uniPonAniConfigFsm) CancelProcessing(ctx context.Context) {
260 //early indication about started reset processing
261 oFsm.pUniTechProf.setProfileResetting(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
mpagenko7d6bb022021-03-11 15:07:55 +0000262 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000263 oFsm.mutexIsAwaitingResponse.Lock()
264 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000265 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000266 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
267 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
268 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000269 //use channel to indicate that the response waiting shall be aborted
270 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000271 } else {
272 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000273 }
mpagenkocf48e452021-04-23 09:23:00 +0000274
275 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkobb47bc22021-04-20 13:29:09 +0000276 if oFsm.isWaitingForFlowDelete {
mpagenkocf48e452021-04-23 09:23:00 +0000277 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000278 //use channel to indicate that the response waiting shall be aborted
279 oFsm.waitFlowDeleteChannel <- false
mpagenkocf48e452021-04-23 09:23:00 +0000280 } else {
281 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkobb47bc22021-04-20 13:29:09 +0000282 }
mpagenkocf48e452021-04-23 09:23:00 +0000283
mpagenko7d6bb022021-03-11 15:07:55 +0000284 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
285 pAdaptFsm := oFsm.pAdaptFsm
286 if pAdaptFsm != nil {
287 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
288 go func(aPAFsm *AdapterFsm) {
289 if aPAFsm.pFsm != nil {
290 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
291 }
292 }(pAdaptFsm)
293 }
mpagenko73143992021-04-09 15:17:10 +0000294
mpagenko45cc6a32021-07-23 10:06:57 +0000295 // possible access conflicts on internal data by next needed data clearance
296 // are avoided by using mutexTPState also from within clearAniSideConfig
297 // do not try to lock TpProcMutex here as done in previous code version
298 // as it may result in deadlock situations (as observed at soft-reboot handling where
299 // TpProcMutex is already locked by some ongoing TechProfile config/removal processing
mpagenko73143992021-04-09 15:17:10 +0000300 //remove all TechProf related internal data to allow for new configuration
301 oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.uniID, oFsm.techProfileID)
mpagenko7d6bb022021-03-11 15:07:55 +0000302}
303
Mahir Gunyel6781f962021-05-16 23:30:08 -0700304//nolint: gocyclo
305//TODO:visit here for refactoring for gocyclo
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *AdapterFsm) {
Himani Chawla26e555c2020-08-31 12:30:20 +0530307 if aPAFsm != nil && aPAFsm.pFsm != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -0700308 var err error
309 oFsm.mapperSP0ID, err = generateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
310 if err != nil {
311 logger.Errorw(ctx, "error generating maper id", log.Fields{"device-id": oFsm.deviceID,
312 "techProfileID": oFsm.techProfileID, "error": err})
313 return
314 }
315 oFsm.macBPCD0ID, err = generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.techProfileID))
316 if err != nil {
317 logger.Errorw(ctx, "error generating mbpcd id", log.Fields{"device-id": oFsm.deviceID,
318 "techProfileID": oFsm.techProfileID, "error": err})
319 return
320 }
321 logger.Debugw(ctx, "generated ids for ani config", log.Fields{"mapperSP0ID": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
322 "macBPCD0ID": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16), "device-id": oFsm.deviceID,
323 "macBpNo": oFsm.pOnuUniPort.macBpNo, "techProfileID": oFsm.techProfileID})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700324 pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false)
325 if pDevEntry == nil {
326 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800327 return
Himani Chawla26e555c2020-08-31 12:30:20 +0530328 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700329 tcontInstID, tcontAlreadyExist, err := pDevEntry.allocateFreeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
330 if err != nil {
331 logger.Errorw(ctx, "No TCont instances found", log.Fields{"device-id": oFsm.deviceID, "err": err})
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700332 //reset the state machine to enable usage on subsequent requests
333 _ = aPAFsm.pFsm.Event(aniEvReset)
334 return
335 }
336 oFsm.tcont0ID = tcontInstID
337 oFsm.tcontSetBefore = tcontAlreadyExist
338 logger.Debugw(ctx, "used-tcont-instance-id", log.Fields{"tcont-inst-id": oFsm.tcont0ID,
339 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID,
340 "tcontAlreadyExist": tcontAlreadyExist,
341 "device-id": oFsm.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800342
343 // Access critical state with lock
mpagenko3ce9fa02021-07-28 13:26:54 +0000344 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000345 oFsm.alloc0ID = oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID
346 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
mpagenko3ce9fa02021-07-28 13:26:54 +0000347 oFsm.pUniTechProf.mutexTPState.RUnlock()
Girish Gowdra041dcb32020-11-16 16:54:30 -0800348
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 //for all TechProfile set GemIndices
Girish Gowdra041dcb32020-11-16 16:54:30 -0800350 for _, gemEntry := range mapGemPortParams {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300351 loGemPortAttribs := ponAniGemPortAttribs{}
352
Himani Chawla26e555c2020-08-31 12:30:20 +0530353 //collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
354
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(ctx, me.PriorityQueueClassID); len(queueInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +0530356
357 loGemPortAttribs.gemPortID = gemEntry.gemPortID
358 // MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
359 // i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
360 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == yyyy (expect 0..7)
361 usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
362
363 // MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
364 // i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
365 // from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
366 // Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
367 // Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
368 dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
369
370 usQueueFound := false
371 dsQueueFound := false
372 for _, mgmtEntityID := range queueInstKeys {
373 if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
374 returnVal := meAttributes["RelatedPort"]
375 if returnVal != nil {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530376 if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 if relatedPort == usQrelPortMask {
378 loGemPortAttribs.upQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Debugw(ctx, "UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000380 "upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 usQueueFound = true
382 } else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
383 loGemPortAttribs.downQueueID = mgmtEntityID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 logger.Debugw(ctx, "DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
mpagenko01e726e2020-10-23 09:45:29 +0000385 "downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 dsQueueFound = true
387 }
388 if usQueueFound && dsQueueFound {
389 break
390 }
391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000392 logger.Warnw(ctx, "Could not convert attribute value", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 }
394 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000395 logger.Warnw(ctx, "'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
397 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 logger.Warnw(ctx, "No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
mpagenko01e726e2020-10-23 09:45:29 +0000399 "mgmtEntityID": mgmtEntityID, "device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 }
401 }
402 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000403 logger.Warnw(ctx, "No PriorityQueue instances found", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 }
405 loGemPortAttribs.direction = gemEntry.direction
406 loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
407 loGemPortAttribs.weight = gemEntry.queueWeight
408 loGemPortAttribs.pbitString = gemEntry.pbitString
ozgecanetsia82b91a62021-05-21 18:54:49 +0300409
ozgecanetsia4b232302020-11-11 10:58:10 +0300410 if gemEntry.isMulticast {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300411 //TODO this might effectively ignore the for loop starting at line 316
412 loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
ozgecanetsia4b232302020-11-11 10:58:10 +0300413 loGemPortAttribs.isMulticast = true
414 loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
415 loGemPortAttribs.staticACL = gemEntry.staticACL
416 loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
Himani Chawla26e555c2020-08-31 12:30:20 +0530417
dbainbri4d3a0dc2020-12-02 00:33:42 +0000418 logger.Debugw(ctx, "Multicast GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300419 "gemPortID": loGemPortAttribs.gemPortID,
420 "isMulticast": loGemPortAttribs.isMulticast,
421 "multicastGemID": loGemPortAttribs.multicastGemID,
422 "staticACL": loGemPortAttribs.staticACL,
423 "dynamicACL": loGemPortAttribs.dynamicACL,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000424 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300425 })
426
427 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 logger.Debugw(ctx, "Upstream GemPort attributes:", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300429 "gemPortID": loGemPortAttribs.gemPortID,
430 "upQueueID": loGemPortAttribs.upQueueID,
431 "downQueueID": loGemPortAttribs.downQueueID,
432 "pbitString": loGemPortAttribs.pbitString,
433 "prioQueueIndex": gemEntry.prioQueueIndex,
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000434 "device-id": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300435 })
436 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530437
438 oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
439 }
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000440 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
441 _ = aPAFsm.pFsm.Event(aniEvStartConfig)
442 } else {
443 logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
444 _ = aPAFsm.pFsm.Event(aniEvSkipOmciConfig)
445 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530446 }
447}
448
dbainbri4d3a0dc2020-12-02 00:33:42 +0000449func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(ctx context.Context, e *fsm.Event) {
450 logger.Debugw(ctx, "UniPonAniConfigFsm start", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000451 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000452 // in case the used channel is not yet defined (can be re-used after restarts)
453 if oFsm.omciMIdsResponseReceived == nil {
454 oFsm.omciMIdsResponseReceived = make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000455 logger.Debug(ctx, "uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
mpagenko3dbcdd22020-07-22 07:38:45 +0000456 } else {
457 // as we may 're-use' this instance of FSM and the connected channel
458 // make sure there is no 'lingering' request in the already existing channel:
459 // (simple loop sufficient as we are the only receiver)
460 for len(oFsm.omciMIdsResponseReceived) > 0 {
461 <-oFsm.omciMIdsResponseReceived
462 }
463 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000464 //ensure internal slices are empty (which might be set from previous run) - release memory
465 oFsm.gemPortAttribsSlice = nil
mpagenkocf48e452021-04-23 09:23:00 +0000466 oFsm.mutexIsAwaitingResponse.Lock()
467 //reset the canceled state possibly existing from previous reset
468 oFsm.isCanceled = false
469 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000470
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000471 // start go routine for processing of ANI config messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 go oFsm.processOmciAniMessages(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000473
474 //let the state machine run forward from here directly
475 pConfigAniStateAFsm := oFsm.pAdaptFsm
476 if pConfigAniStateAFsm != nil {
477 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000478 go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
mpagenko3dbcdd22020-07-22 07:38:45 +0000479
mpagenko3dbcdd22020-07-22 07:38:45 +0000480 }
481}
482
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(ctx context.Context, e *fsm.Event) {
484 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000485 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000486 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
487 oFsm.requestEventOffset = 0 //0 offset for last config request activity
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000488 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300489 meInstance, err := oFsm.pOmciCC.sendCreateDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000490 oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300491 if err != nil {
492 logger.Errorw(ctx, "Dot1PMapper create failed, aborting uniPonAniConfigFsm!",
493 log.Fields{"device-id": oFsm.deviceID})
494 pConfigAniStateAFsm := oFsm.pAdaptFsm
495 if pConfigAniStateAFsm != nil {
496 oFsm.mutexPLastTxMeInstance.Unlock()
497 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
498 go func(aPAFsm *AdapterFsm) {
499 if aPAFsm != nil && aPAFsm.pFsm != nil {
500 _ = aPAFsm.pFsm.Event(aniEvReset)
501 }
502 }(pConfigAniStateAFsm)
503 return
504 }
505 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000506 //accept also nil as (error) return value for writing to LastTx
507 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000508 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300509 oFsm.mutexPLastTxMeInstance.Unlock()
510
mpagenko3dbcdd22020-07-22 07:38:45 +0000511}
512
dbainbri4d3a0dc2020-12-02 00:33:42 +0000513func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(ctx context.Context, e *fsm.Event) {
514 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000515 "EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
516 "TPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko8b07c1b2020-11-26 10:36:31 +0000517 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000518 bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
519 meParams := me.ParamData{
520 EntityID: oFsm.macBPCD0ID,
521 Attributes: me.AttributeValueMap{
522 "BridgeIdPointer": bridgePtr,
523 "PortNum": 0xFF, //fixed unique ANI side indication
524 "TpType": 3, //for .1PMapper
525 "TpPointer": oFsm.mapperSP0ID,
526 },
527 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000528 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300529 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000530 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300531 if err != nil {
532 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting uniPonAniConfigFsm!",
533 log.Fields{"device-id": oFsm.deviceID})
534 pConfigAniStateAFsm := oFsm.pAdaptFsm
535 if pConfigAniStateAFsm != nil {
536 oFsm.mutexPLastTxMeInstance.Unlock()
537 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
538 go func(aPAFsm *AdapterFsm) {
539 if aPAFsm != nil && aPAFsm.pFsm != nil {
540 _ = aPAFsm.pFsm.Event(aniEvReset)
541 }
542 }(pConfigAniStateAFsm)
543 return
544 }
545 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000546 //accept also nil as (error) return value for writing to LastTx
547 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000548 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300549 oFsm.mutexPLastTxMeInstance.Unlock()
550
mpagenko3dbcdd22020-07-22 07:38:45 +0000551}
552
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553func (oFsm *uniPonAniConfigFsm) enterSettingTconts(ctx context.Context, e *fsm.Event) {
554 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
mpagenko3dbcdd22020-07-22 07:38:45 +0000555 "EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
556 "AllocId": strconv.FormatInt(int64(oFsm.alloc0ID), 16),
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700557 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
558 "tcontExist": oFsm.tcontSetBefore})
559 //If tcont was set before, then no need to set it again. Let state machine to proceed.
560 if oFsm.tcontSetBefore {
561 go func(aPAFsm *AdapterFsm) {
562 if aPAFsm != nil && aPAFsm.pFsm != nil {
563 _ = aPAFsm.pFsm.Event(aniEvRxTcontsResp)
564 }
565 }(oFsm.pAdaptFsm)
566 return
567 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000568 meParams := me.ParamData{
569 EntityID: oFsm.tcont0ID,
570 Attributes: me.AttributeValueMap{
571 "AllocId": oFsm.alloc0ID,
572 },
573 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000574 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300575 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko3dbcdd22020-07-22 07:38:45 +0000576 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300577 if err != nil {
578 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
579 log.Fields{"device-id": oFsm.deviceID})
580 pConfigAniStateAFsm := oFsm.pAdaptFsm
581 if pConfigAniStateAFsm != nil {
582 oFsm.mutexPLastTxMeInstance.Unlock()
583 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
584 go func(aPAFsm *AdapterFsm) {
585 if aPAFsm != nil && aPAFsm.pFsm != nil {
586 _ = aPAFsm.pFsm.Event(aniEvReset)
587 }
588 }(pConfigAniStateAFsm)
589 return
590 }
591 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000592 //accept also nil as (error) return value for writing to LastTx
593 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +0000594 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300595 oFsm.mutexPLastTxMeInstance.Unlock()
596
mpagenko3dbcdd22020-07-22 07:38:45 +0000597}
598
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(ctx context.Context, e *fsm.Event) {
600 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000601 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000602 go oFsm.performCreatingGemNCTPs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000603}
604
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(ctx context.Context, e *fsm.Event) {
606 logger.Debugw(ctx, "uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000607 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 go oFsm.performCreatingGemIWs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000609}
610
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611func (oFsm *uniPonAniConfigFsm) enterSettingPQs(ctx context.Context, e *fsm.Event) {
612 logger.Debugw(ctx, "uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000613 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 go oFsm.performSettingPQs(ctx)
mpagenko3dbcdd22020-07-22 07:38:45 +0000615}
616
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(ctx context.Context, e *fsm.Event) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300618
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
mpagenko8b07c1b2020-11-26 10:36:31 +0000620 "toGemIw": 1024, /* cmp above */
621 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000622
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000624 "EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000625 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000626
mpagenko3dbcdd22020-07-22 07:38:45 +0000627 meParams := me.ParamData{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000628 EntityID: oFsm.mapperSP0ID,
Himani Chawla4d908332020-08-31 12:30:20 +0530629 Attributes: make(me.AttributeValueMap),
mpagenko3dbcdd22020-07-22 07:38:45 +0000630 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000631
632 //assign the GemPorts according to the configured Prio
633 var loPrioGemPortArray [8]uint16
634 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300635 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300637 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
638 "prioString": gemPortAttribs.pbitString})
639 continue
640 }
641 if gemPortAttribs.pbitString == "" {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString empty string error", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300643 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
644 "prioString": gemPortAttribs.pbitString})
645 continue
646 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000647 for i := 0; i < 8; i++ {
648 // "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
649 if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
650 if prio == 1 { // Check this p-bit is set
651 if loPrioGemPortArray[i] == 0 {
652 loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString not unique", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000655 "device-id": oFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000656 "SetGemPort": loPrioGemPortArray[i]})
657 }
658 }
659 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660 logger.Warnw(ctx, "uniPonAniConfigFsm PrioString evaluation error", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000661 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000662 "prioString": gemPortAttribs.pbitString, "position": i})
663 }
664
665 }
666 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300667
ozgecanetsia4b232302020-11-11 10:58:10 +0300668 var foundIwPtr = false
Himani Chawla4d908332020-08-31 12:30:20 +0530669 for index, value := range loPrioGemPortArray {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300670 meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
Himani Chawla4d908332020-08-31 12:30:20 +0530671 if value != 0 {
672 foundIwPtr = true
Himani Chawla4d908332020-08-31 12:30:20 +0530673 meParams.Attributes[meAttribute] = value
dbainbri4d3a0dc2020-12-02 00:33:42 +0000674 logger.Debugw(ctx, "UniPonAniConfigFsm Set::1pMapper", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000675 "for Prio": index,
676 "IwPtr": strconv.FormatInt(int64(value), 16),
677 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300678 } else {
679 // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
mpagenko8b5fdd22020-12-17 17:58:32 +0000680 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
681 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300682 meParams.Attributes[meAttribute] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530683 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000684 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300685 // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
mpagenko8b5fdd22020-12-17 17:58:32 +0000686 // setting this parameter is not strictly needed anymore with the ensured .1pMapper create default setting
687 // but except for processing effort does not really harm - left to keep changes low
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300688 meParams.Attributes["TpPointer"] = 0xffff
Himani Chawla4d908332020-08-31 12:30:20 +0530689
690 if !foundIwPtr {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691 logger.Debugw(ctx, "UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000692 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300693 //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
694 // this reset needs to be performed only if the tech profile provides upstream gem ports but no priority is set
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000695 //let's reset the state machine in order to release all resources now
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300696 //pConfigAniStateAFsm := oFsm.pAdaptFsm
697 //if pConfigAniStateAFsm != nil {
698 // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
699 // go func(aPAFsm *AdapterFsm) {
700 // if aPAFsm != nil && aPAFsm.pFsm != nil {
701 // _ = aPAFsm.pFsm.Event(aniEvReset)
702 // }
703 // }(pConfigAniStateAFsm)
704 //}
705 //Moving forward the FSM as if the response was received correctly.
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000706 pConfigAniStateAFsm := oFsm.pAdaptFsm
707 if pConfigAniStateAFsm != nil {
708 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
Himani Chawla26e555c2020-08-31 12:30:20 +0530709 go func(aPAFsm *AdapterFsm) {
710 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300711 _ = aPAFsm.pFsm.Event(aniEvRxDot1pmapSResp)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000712 }
713 }(pConfigAniStateAFsm)
714 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300715 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000716 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300717 meInstance, err := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300718 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300719 if err != nil {
720 logger.Errorw(ctx, "Dot1PMapperVar set failed, aborting uniPonAniConfigFsm!",
721 log.Fields{"device-id": oFsm.deviceID})
722 pConfigAniStateAFsm := oFsm.pAdaptFsm
723 if pConfigAniStateAFsm != nil {
724 oFsm.mutexPLastTxMeInstance.Unlock()
725 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
726 go func(aPAFsm *AdapterFsm) {
727 if aPAFsm != nil && aPAFsm.pFsm != nil {
728 _ = aPAFsm.pFsm.Event(aniEvReset)
729 }
730 }(pConfigAniStateAFsm)
731 return
732 }
733 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300734 //accept also nil as (error) return value for writing to LastTx
735 // - this avoids misinterpretation of new received OMCI messages
736 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300737 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000738 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000739}
740
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(ctx context.Context, e *fsm.Event) {
742 logger.Debugw(ctx, "uniPonAniConfigFsm ani config done", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000743 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
mpagenko01e726e2020-10-23 09:45:29 +0000744 //store that the UNI related techProfile processing is done for the given Profile and Uni
Girish Gowdra041dcb32020-11-16 16:54:30 -0800745 oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID, true)
Holger Hildebrandt01bc3bf2021-04-26 09:59:01 +0000746 if !oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
747 //use DeviceHandler event notification directly
748 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
749 //if techProfile processing is done it must be checked, if some prior/parallel flow configuration is pending
750 // but only in case the techProfile was configured (not deleted)
751 if oFsm.requestEventOffset == 0 {
752 go oFsm.pDeviceHandler.verifyUniVlanConfigRequest(ctx, oFsm.pOnuUniPort, oFsm.techProfileID)
753 }
754 } else {
755 logger.Debugw(ctx, "reconciling - skip AniConfigDone processing", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +0000756 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000757 if oFsm.isChanSet() {
mpagenko01e726e2020-10-23 09:45:29 +0000758 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000760 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
761 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000762 oFsm.setChanSet(false) //reset the internal channel state
mpagenko3dbcdd22020-07-22 07:38:45 +0000763 }
mpagenko01e726e2020-10-23 09:45:29 +0000764
765 //the FSM is left active in this state as long as no specific reset or remove is requested from outside
mpagenko3dbcdd22020-07-22 07:38:45 +0000766}
767
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768func (oFsm *uniPonAniConfigFsm) enterRemovingGemIW(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000769 // no need to protect access to oFsm.waitFlowDeleteChannel, only used in synchronized state entries
770 // or CancelProcessing() that uses separate isWaitingForFlowDelete to write to the channel
mpagenkobb47bc22021-04-20 13:29:09 +0000771 //flush the waitFlowDeleteChannel - possibly already/still set by some previous activity
772 select {
773 case <-oFsm.waitFlowDeleteChannel:
774 logger.Debug(ctx, "flushed waitFlowDeleteChannel")
775 default:
776 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000777
778 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID] != nil {
mpagenko3ce9fa02021-07-28 13:26:54 +0000779 // ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000780 if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000781 logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
782 log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
783 // if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
784 pConfigAniStateAFsm := oFsm.pAdaptFsm
785 if pConfigAniStateAFsm != nil {
786 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
787 go func(aPAFsm *AdapterFsm) {
788 if aPAFsm != nil && aPAFsm.pFsm != nil {
789 _ = aPAFsm.pFsm.Event(aniEvWaitFlowRem)
790 }
791 }(pConfigAniStateAFsm)
792 } else {
793 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
794 }
795 return
Girish Gowdra26a40922021-01-29 17:14:34 -0800796 }
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000797 } else {
798 logger.Debugw(ctx, "uni vlan config doesn't exist - no flow remove could be pending",
799 log.Fields{"device-id": oFsm.deviceID, "techProfile-id": oFsm.techProfileID})
Girish Gowdra26a40922021-01-29 17:14:34 -0800800 }
801
mpagenko3ce9fa02021-07-28 13:26:54 +0000802 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000803 // get the related GemPort entity Id from pUniTechProf, OMCI Gem* entityID is set to be equal to GemPortId!
mpagenko8b07c1b2020-11-26 10:36:31 +0000804 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000805 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemIwTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000807 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
808 "GemIwTp-entity-id": loGemPortID})
809 oFsm.requestEventOffset = 1 //offset 1 to indicate last activity = remove
810
811 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000812 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300813 meInstance, err := oFsm.pOmciCC.sendDeleteGemIWTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000814 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300815 if err != nil {
816 logger.Errorw(ctx, "GemIWTP delete failed, aborting uniPonAniConfigFsm!",
817 log.Fields{"device-id": oFsm.deviceID})
818 pConfigAniStateAFsm := oFsm.pAdaptFsm
819 if pConfigAniStateAFsm != nil {
820 oFsm.mutexPLastTxMeInstance.Unlock()
821 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
822 go func(aPAFsm *AdapterFsm) {
823 if aPAFsm != nil && aPAFsm.pFsm != nil {
824 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
825 }
826 }(pConfigAniStateAFsm)
827 return
828 }
829 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000830 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +0300831 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000832}
833
mpagenkobb47bc22021-04-20 13:29:09 +0000834func (oFsm *uniPonAniConfigFsm) enterWaitingFlowRem(ctx context.Context, e *fsm.Event) {
835 oFsm.mutexIsAwaitingResponse.Lock()
836 oFsm.isWaitingForFlowDelete = true
837 oFsm.mutexIsAwaitingResponse.Unlock()
838 select {
839 // maybe be also some outside cancel (but no context modeled for the moment ...)
840 // case <-ctx.Done():
841 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000842 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 +0000843 logger.Warnw(ctx, "uniPonAniConfigFsm WaitingFlowRem timeout", log.Fields{
844 "for device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
845 oFsm.mutexIsAwaitingResponse.Lock()
846 oFsm.isWaitingForFlowDelete = false
847 oFsm.mutexIsAwaitingResponse.Unlock()
848 //if the flow is not removed as expected we just try to continue with GemPort removal and hope things are clearing up afterwards
849 pConfigAniStateAFsm := oFsm.pAdaptFsm
850 if pConfigAniStateAFsm != nil {
851 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
852 go func(aPAFsm *AdapterFsm) {
853 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300854 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000855 }
856 }(pConfigAniStateAFsm)
857 } else {
858 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
859 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
860 }
861 return
862
863 case success := <-oFsm.waitFlowDeleteChannel:
864 if success {
865 logger.Debugw(ctx, "uniPonAniConfigFsm flow removed info received", log.Fields{
866 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
867 oFsm.mutexIsAwaitingResponse.Lock()
868 oFsm.isWaitingForFlowDelete = false
869 oFsm.mutexIsAwaitingResponse.Unlock()
870 pConfigAniStateAFsm := oFsm.pAdaptFsm
871 if pConfigAniStateAFsm != nil {
872 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
873 go func(aPAFsm *AdapterFsm) {
874 if aPAFsm != nil && aPAFsm.pFsm != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +0300875 _ = aPAFsm.pFsm.Event(aniEvFlowRemDone)
mpagenkobb47bc22021-04-20 13:29:09 +0000876 }
877 }(pConfigAniStateAFsm)
878 } else {
879 logger.Errorw(ctx, "pConfigAniStateAFsm is nil", log.Fields{
880 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
881 }
882 return
883 }
884 // waiting was aborted (probably on external request)
885 logger.Debugw(ctx, "uniPonAniConfigFsm WaitingFlowRem aborted", log.Fields{
886 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
887 oFsm.mutexIsAwaitingResponse.Lock()
888 oFsm.isWaitingForFlowDelete = false
889 oFsm.mutexIsAwaitingResponse.Unlock()
890 //to be sure we can just generate the reset-event to ensure leaving this state towards 'reset'
891 pConfigAniStateAFsm := oFsm.pAdaptFsm
892 if pConfigAniStateAFsm != nil {
893 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
894 go func(aPAFsm *AdapterFsm) {
895 if aPAFsm != nil && aPAFsm.pFsm != nil {
896 _ = aPAFsm.pFsm.Event(aniEvReset)
897 }
898 }(pConfigAniStateAFsm)
899 }
900 return
901 }
902}
903
dbainbri4d3a0dc2020-12-02 00:33:42 +0000904func (oFsm *uniPonAniConfigFsm) enterRemovingGemNCTP(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000905 oFsm.pUniTechProf.mutexTPState.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000906 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000907 oFsm.pUniTechProf.mutexTPState.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing one GemNCTP", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000909 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
910 "GemNCTP-entity-id": loGemPortID})
911 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000912 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300913 meInstance, err := oFsm.pOmciCC.sendDeleteGemNCTP(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000914 oFsm.pAdaptFsm.commChan, loGemPortID)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300915 if err != nil {
916 logger.Errorw(ctx, "GemNCTP delete failed, aborting uniPonAniConfigFsm!",
917 log.Fields{"device-id": oFsm.deviceID})
918 pConfigAniStateAFsm := oFsm.pAdaptFsm
919 if pConfigAniStateAFsm != nil {
920 oFsm.mutexPLastTxMeInstance.Unlock()
921 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
922 go func(aPAFsm *AdapterFsm) {
923 if aPAFsm != nil && aPAFsm.pFsm != nil {
924 _ = aPAFsm.pFsm.Event(aniEvReset)
925 }
926 }(pConfigAniStateAFsm)
927 return
928 }
929 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000930 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000931 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300932
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800933 // Mark the gem port to be removed for Performance History monitoring
934 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -0700935 oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -0800936 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000937}
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300938func (oFsm *uniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
mpagenko3ce9fa02021-07-28 13:26:54 +0000939 oFsm.pUniTechProf.mutexTPState.RLock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300940 loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
mpagenko3ce9fa02021-07-28 13:26:54 +0000941 oFsm.pUniTechProf.mutexTPState.RUnlock()
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +0300942 logger.Debugw(ctx, "uniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
943 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
944 "TD-entity-id": loGemPortID})
945
946 oFsm.mutexPLastTxMeInstance.Lock()
947 meInstance, err := oFsm.pOmciCC.sendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
948 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, loGemPortID)
949
950 if err != nil {
951 logger.Errorw(ctx, "TD delete failed - proceed fsm",
952 log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
953 pConfigAniStateAFsm := oFsm.pAdaptFsm
954 if pConfigAniStateAFsm != nil {
955 oFsm.mutexPLastTxMeInstance.Unlock()
956 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
957 go func(aPAFsm *AdapterFsm) {
958 if aPAFsm != nil && aPAFsm.pFsm != nil {
959 _ = aPAFsm.pFsm.Event(aniEvReset)
960 }
961 }(pConfigAniStateAFsm)
962 return
963 }
964 }
965 oFsm.pLastTxMeInstance = meInstance
966 oFsm.mutexPLastTxMeInstance.Unlock()
967}
mpagenko8b07c1b2020-11-26 10:36:31 +0000968
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
970 logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +0000971 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
972
973 oFsm.requestEventOffset = 1 //offset 1 for last remove activity
974 // this state entry is only expected in a suitable state (checked outside in onu_uni_tp)
975 meParams := me.ParamData{
976 EntityID: oFsm.tcont0ID,
977 Attributes: me.AttributeValueMap{
978 "AllocId": unusedTcontAllocID,
979 },
980 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +0000981 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300982 meInstance, err := oFsm.pOmciCC.sendSetTcontVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +0000983 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300984 if err != nil {
985 logger.Errorw(ctx, "TcontVar set failed, aborting uniPonAniConfigFsm!",
986 log.Fields{"device-id": oFsm.deviceID})
987 pConfigAniStateAFsm := oFsm.pAdaptFsm
988 if pConfigAniStateAFsm != nil {
989 oFsm.mutexPLastTxMeInstance.Unlock()
990 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
991 go func(aPAFsm *AdapterFsm) {
992 if aPAFsm != nil && aPAFsm.pFsm != nil {
993 _ = aPAFsm.pFsm.Event(aniEvReset)
994 }
995 }(pConfigAniStateAFsm)
996 return
997 }
998 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000999 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001000 oFsm.mutexPLastTxMeInstance.Unlock()
1001
mpagenko8b07c1b2020-11-26 10:36:31 +00001002}
1003
dbainbri4d3a0dc2020-12-02 00:33:42 +00001004func (oFsm *uniPonAniConfigFsm) enterRemoving1pMapper(ctx context.Context, e *fsm.Event) {
1005 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the .1pMapper", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001006 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Mahir Gunyel9545be22021-07-04 15:53:16 -07001007 mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
1008 unicastGemCount := 0
1009 for _, gemEntry := range mapGemPortParams {
1010 if !gemEntry.isMulticast {
1011 unicastGemCount++
1012 }
1013 }
1014 if unicastGemCount > 1 {
1015 logger.Debugw(ctx, "uniPonAniConfigFsm - Not the last gem in fsm. Skip the rest", log.Fields{
1016 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
1017 pConfigAniStateAFsm := oFsm.pAdaptFsm
1018 if pConfigAniStateAFsm != nil {
1019 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1020 go func(aPAFsm *AdapterFsm) {
1021 if aPAFsm != nil && aPAFsm.pFsm != nil {
1022 _ = aPAFsm.pFsm.Event(aniEvRemGemDone)
1023 }
1024 }(pConfigAniStateAFsm)
1025 return
1026 }
1027 }
1028 logger.Debugw(ctx, "uniPonAniConfigFsm - Last gem in fsm. Continue with Mapper removal", log.Fields{
1029 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "unicast-gem-count": unicastGemCount, "gem-count": len(mapGemPortParams)})
mpagenko8b07c1b2020-11-26 10:36:31 +00001030
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001031 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001032 meInstance, err := oFsm.pOmciCC.sendDeleteDot1PMapper(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001033 oFsm.pAdaptFsm.commChan, oFsm.mapperSP0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001034 if err != nil {
1035 logger.Errorw(ctx, "Dot1Mapper delete failed, aborting uniPonAniConfigFsm!",
1036 log.Fields{"device-id": oFsm.deviceID})
1037 pConfigAniStateAFsm := oFsm.pAdaptFsm
1038 if pConfigAniStateAFsm != nil {
1039 oFsm.mutexPLastTxMeInstance.Unlock()
1040 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1041 go func(aPAFsm *AdapterFsm) {
1042 if aPAFsm != nil && aPAFsm.pFsm != nil {
1043 _ = aPAFsm.pFsm.Event(aniEvReset)
1044 }
1045 }(pConfigAniStateAFsm)
1046 return
1047 }
1048 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001049 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001050 oFsm.mutexPLastTxMeInstance.Unlock()
1051
mpagenko8b07c1b2020-11-26 10:36:31 +00001052}
1053
dbainbri4d3a0dc2020-12-02 00:33:42 +00001054func (oFsm *uniPonAniConfigFsm) enterRemovingAniBPCD(ctx context.Context, e *fsm.Event) {
1055 logger.Debugw(ctx, "uniPonAniConfigFsm - start deleting the ANI MBCD", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001056 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1057
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001058 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001059 meInstance, err := oFsm.pOmciCC.sendDeleteMBPConfigData(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko8b07c1b2020-11-26 10:36:31 +00001060 oFsm.pAdaptFsm.commChan, oFsm.macBPCD0ID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001061 if err != nil {
1062 logger.Errorw(ctx, "MBPConfigData delete failed, aborting uniPonAniConfigFsm!",
1063 log.Fields{"device-id": oFsm.deviceID})
1064 pConfigAniStateAFsm := oFsm.pAdaptFsm
1065 if pConfigAniStateAFsm != nil {
1066 oFsm.mutexPLastTxMeInstance.Unlock()
1067 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1068 go func(aPAFsm *AdapterFsm) {
1069 if aPAFsm != nil && aPAFsm.pFsm != nil {
1070 _ = aPAFsm.pFsm.Event(aniEvReset)
1071 }
1072 }(pConfigAniStateAFsm)
1073 return
1074 }
1075 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001076 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03001077 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001078}
1079
dbainbri4d3a0dc2020-12-02 00:33:42 +00001080func (oFsm *uniPonAniConfigFsm) enterAniRemoveDone(ctx context.Context, e *fsm.Event) {
1081 logger.Debugw(ctx, "uniPonAniConfigFsm ani removal done", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001082 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1083 //use DeviceHandler event notification directly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001084 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent((uint8(oFsm.requestEvent) + oFsm.requestEventOffset)))
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001085 if oFsm.isChanSet() {
mpagenko8b07c1b2020-11-26 10:36:31 +00001086 // indicate processing done to the caller
dbainbri4d3a0dc2020-12-02 00:33:42 +00001087 logger.Debugw(ctx, "uniPonAniConfigFsm processingDone on channel", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001088 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1089 oFsm.chSuccess <- oFsm.procStep
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001090 oFsm.setChanSet(false) //reset the internal channel state
mpagenko8b07c1b2020-11-26 10:36:31 +00001091 }
1092
1093 //let's reset the state machine in order to release all resources now
1094 pConfigAniStateAFsm := oFsm.pAdaptFsm
1095 if pConfigAniStateAFsm != nil {
1096 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1097 go func(aPAFsm *AdapterFsm) {
1098 if aPAFsm != nil && aPAFsm.pFsm != nil {
1099 _ = aPAFsm.pFsm.Event(aniEvReset)
1100 }
1101 }(pConfigAniStateAFsm)
1102 }
1103}
1104
dbainbri4d3a0dc2020-12-02 00:33:42 +00001105func (oFsm *uniPonAniConfigFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
1106 logger.Debugw(ctx, "uniPonAniConfigFsm resetting", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001107 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001108
mpagenko45cc6a32021-07-23 10:06:57 +00001109 if oFsm.isChanSet() {
1110 // indicate processing error to the caller (in case there was still some open request)
1111 logger.Debugw(ctx, "uniPonAniConfigFsm processingError on channel", log.Fields{
1112 "ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.deviceID})
1113 //use non-blocking channel send to avoid blocking because of non-existing receiver
1114 // (even though the channel is checked on 'set', the outside receiver channel might (theoretically) already be deleted)
1115 select {
1116 case oFsm.chSuccess <- 0:
1117 default:
1118 logger.Debugw(ctx, "uniPonAniConfigFsm processingError not send on channel (no receiver)", log.Fields{
1119 "device-id": oFsm.deviceID})
1120 }
1121 oFsm.setChanSet(false) //reset the internal channel state
1122 }
1123
mpagenko3dbcdd22020-07-22 07:38:45 +00001124 pConfigAniStateAFsm := oFsm.pAdaptFsm
1125 if pConfigAniStateAFsm != nil {
1126 // abort running message processing
1127 fsmAbortMsg := Message{
1128 Type: TestMsg,
1129 Data: TestMessage{
1130 TestMessageVal: AbortMessageProcessing,
1131 },
1132 }
1133 pConfigAniStateAFsm.commChan <- fsmAbortMsg
1134
1135 //try to restart the FSM to 'disabled', decouple event transfer
Himani Chawla26e555c2020-08-31 12:30:20 +05301136 go func(aPAFsm *AdapterFsm) {
1137 if aPAFsm != nil && aPAFsm.pFsm != nil {
1138 _ = aPAFsm.pFsm.Event(aniEvRestart)
mpagenko3dbcdd22020-07-22 07:38:45 +00001139 }
1140 }(pConfigAniStateAFsm)
1141 }
1142}
1143
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144func (oFsm *uniPonAniConfigFsm) enterDisabledState(ctx context.Context, e *fsm.Event) {
1145 logger.Debugw(ctx, "uniPonAniConfigFsm enters disabled state", log.Fields{
mpagenko8b07c1b2020-11-26 10:36:31 +00001146 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001147 oFsm.mutexPLastTxMeInstance.Lock()
1148 defer oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001149 oFsm.pLastTxMeInstance = nil
mpagenko1cc3cb42020-07-27 15:24:38 +00001150}
1151
dbainbri4d3a0dc2020-12-02 00:33:42 +00001152func (oFsm *uniPonAniConfigFsm) processOmciAniMessages(ctx context.Context) {
1153 logger.Debugw(ctx, "Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001154loop:
1155 for {
mpagenko3dbcdd22020-07-22 07:38:45 +00001156 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001157 // logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001158 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301159 message, ok := <-oFsm.pAdaptFsm.commChan
1160 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001161 logger.Info(ctx, "UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301162 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1163 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1164 break loop
1165 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001166 logger.Debugw(ctx, "UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301167
1168 switch message.Type {
1169 case TestMsg:
1170 msg, _ := message.Data.(TestMessage)
1171 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 logger.Infow(ctx, "UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001173 break loop
1174 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 logger.Warnw(ctx, "UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301176 case OMCI:
1177 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001178 oFsm.handleOmciAniConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301179 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001180 logger.Warn(ctx, "UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301181 "message.Type": message.Type})
1182 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001183
Himani Chawla4d908332020-08-31 12:30:20 +05301184 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001185 logger.Infow(ctx, "End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301186}
1187
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301189 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
1190 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001191 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001192 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301193 return
1194 }
1195 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1196 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001197 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001198 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301199 return
1200 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001201 logger.Debugw(ctx, "CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkofc4f56e2020-11-04 17:17:49 +00001202 if msgObj.Result == me.Success || msgObj.Result == me.InstanceExists {
1203 //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 +00001204 oFsm.mutexPLastTxMeInstance.RLock()
1205 if oFsm.pLastTxMeInstance != nil {
1206 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1207 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1208 // maybe we can use just the same eventName for different state transitions like "forward"
1209 // - might be checked, but so far I go for sure and have to inspect the concrete state events ...
1210 switch oFsm.pLastTxMeInstance.GetName() {
1211 case "Ieee8021PMapperServiceProfile":
1212 { // let the FSM proceed ...
1213 oFsm.mutexPLastTxMeInstance.RUnlock()
1214 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
1215 }
1216 case "MacBridgePortConfigurationData":
1217 { // let the FSM proceed ...
1218 oFsm.mutexPLastTxMeInstance.RUnlock()
1219 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
1220 }
1221 case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
1222 { // let aniConfig Multi-Id processing proceed by stopping the wait function
1223 oFsm.mutexPLastTxMeInstance.RUnlock()
1224 oFsm.omciMIdsResponseReceived <- true
1225 }
1226 default:
1227 {
1228 oFsm.mutexPLastTxMeInstance.RUnlock()
1229 logger.Warnw(ctx, "Unsupported ME name received!",
1230 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1231 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001232 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001233 } else {
1234 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001235 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001236 } else {
1237 oFsm.mutexPLastTxMeInstance.RUnlock()
1238 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001239 }
1240 } else {
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001241 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?",
1242 log.Fields{"Error": msgObj.Result, "device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301243 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1244 return
1245 }
Himani Chawla4d908332020-08-31 12:30:20 +05301246}
Mahir Gunyel01034b62021-06-29 11:25:09 -07001247func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetFailResponseMessage(ctx context.Context, msgObj *omci.SetResponse) {
1248 //If TCONT fails, then we need to revert the allocated TCONT in DB.
1249 //Because FSMs are running sequentially, we don't expect the same TCONT hit by another tech-profile FSM while this FSM is running.
1250 oFsm.mutexPLastTxMeInstance.RLock()
1251 defer oFsm.mutexPLastTxMeInstance.RUnlock()
1252 if oFsm.pLastTxMeInstance != nil && msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1253 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1254 switch oFsm.pLastTxMeInstance.GetName() {
1255 case "TCont":
1256 //If this is for TCONT creation(requestEventOffset=0) and this is the first allocation of TCONT(so noone else is using the same TCONT)
1257 //We should revert DB
1258 if oFsm.requestEventOffset == 0 && !oFsm.tcontSetBefore && oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey] != nil {
1259 logger.Debugw(ctx, "UniPonAniConfigFsm TCONT creation failed on device. Freeing alloc id", log.Fields{"device-id": oFsm.deviceID,
1260 "alloc-id": oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID, "uni-tp": oFsm.uniTpKey})
1261 if pDevEntry := oFsm.pDeviceHandler.getOnuDeviceEntry(ctx, false); pDevEntry != nil {
1262 pDevEntry.freeTcont(ctx, oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].tcontParams.allocID)
1263 } else {
1264 logger.Warnw(ctx, "Unable to get device entry! couldn't free tcont",
1265 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1266 }
1267 }
1268 default:
1269 logger.Warnw(ctx, "Unsupported ME name received with error!",
1270 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "result": msgObj.Result, "device-id": oFsm.deviceID})
1271 }
1272 }
1273}
dbainbri4d3a0dc2020-12-02 00:33:42 +00001274func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(ctx context.Context, msg OmciMessage) {
Himani Chawla4d908332020-08-31 12:30:20 +05301275 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1276 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001277 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001278 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301279 return
1280 }
1281 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1282 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001284 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301285 return
1286 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001287 logger.Debugw(ctx, "UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Himani Chawla4d908332020-08-31 12:30:20 +05301288 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001289 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001290 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Himani Chawla4d908332020-08-31 12:30:20 +05301291 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001292
Mahir Gunyel01034b62021-06-29 11:25:09 -07001293 oFsm.handleOmciAniConfigSetFailResponseMessage(ctx, msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301294 return
1295 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001296 oFsm.mutexPLastTxMeInstance.RLock()
1297 if oFsm.pLastTxMeInstance != nil {
1298 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1299 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1300 //store the created ME into DB //TODO??? obviously the Python code does not store the config ...
1301 // if, then something like:
1302 //oFsm.pOnuDB.StoreMe(msgObj)
Himani Chawla4d908332020-08-31 12:30:20 +05301303
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001304 switch oFsm.pLastTxMeInstance.GetName() {
1305 case "TCont":
1306 { // let the FSM proceed ...
1307 oFsm.mutexPLastTxMeInstance.RUnlock()
1308 if oFsm.requestEventOffset == 0 { //from TCont config request
1309 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
1310 } else { // from T-Cont reset request
1311 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
1312 }
1313 }
1314 case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
1315 { // let the PrioQueue init proceed by stopping the wait function
1316 oFsm.mutexPLastTxMeInstance.RUnlock()
1317 oFsm.omciMIdsResponseReceived <- true
1318 }
1319 case "Ieee8021PMapperServiceProfile":
1320 { // let the FSM proceed ...
1321 oFsm.mutexPLastTxMeInstance.RUnlock()
1322 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
1323 }
1324 default:
1325 {
1326 oFsm.mutexPLastTxMeInstance.RUnlock()
1327 logger.Warnw(ctx, "Unsupported ME name received!",
1328 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001329 }
Himani Chawla4d908332020-08-31 12:30:20 +05301330 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001331 } else {
1332 oFsm.mutexPLastTxMeInstance.RUnlock()
Himani Chawla4d908332020-08-31 12:30:20 +05301333 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001334 } else {
1335 oFsm.mutexPLastTxMeInstance.RUnlock()
1336 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301337 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001338}
1339
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigDeleteResponseMessage(ctx context.Context, msg OmciMessage) {
mpagenko8b07c1b2020-11-26 10:36:31 +00001341 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDeleteResponse)
1342 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001343 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001344 log.Fields{"device-id": oFsm.deviceID})
1345 return
1346 }
1347 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1348 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001349 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko8b07c1b2020-11-26 10:36:31 +00001350 log.Fields{"device-id": oFsm.deviceID})
1351 return
1352 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001353 logger.Debugw(ctx, "UniPonAniConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko8b07c1b2020-11-26 10:36:31 +00001354 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001355 logger.Errorw(ctx, "UniPonAniConfigFsm - Omci DeleteResponse Error",
mpagenko8b07c1b2020-11-26 10:36:31 +00001356 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1357 //TODO: - later: possibly force FSM into abort or ignore some errors for some messages?
1358 // store error for mgmt display?
1359 return
1360 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001361 oFsm.mutexPLastTxMeInstance.RLock()
1362 if oFsm.pLastTxMeInstance != nil {
1363 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1364 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1365 //remove ME from DB //TODO??? obviously the Python code does not store/remove the config ...
1366 // if, then something like: oFsm.pOnuDB.XyyMe(msgObj)
mpagenko8b07c1b2020-11-26 10:36:31 +00001367
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001368 switch oFsm.pLastTxMeInstance.GetName() {
1369 case "GemInterworkingTerminationPoint":
1370 { // let the FSM proceed ...
1371 oFsm.mutexPLastTxMeInstance.RUnlock()
1372 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemiwResp)
1373 }
1374 case "GemPortNetworkCtp":
1375 { // let the FSM proceed ...
1376 oFsm.mutexPLastTxMeInstance.RUnlock()
1377 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
1378 }
ozgecanetsiaa88b5ca2021-06-28 21:00:16 +03001379 case "TrafficDescriptor":
1380 { // let the FSM proceed ...
1381 oFsm.mutexPLastTxMeInstance.RUnlock()
1382 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemTdResp)
1383 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001384 case "Ieee8021PMapperServiceProfile":
1385 { // let the FSM proceed ...
1386 oFsm.mutexPLastTxMeInstance.RUnlock()
1387 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRem1pMapperResp)
1388 }
1389 case "MacBridgePortConfigurationData":
1390 { // this is the last event of the T-Cont cleanup procedure, FSM may be reset here
1391 oFsm.mutexPLastTxMeInstance.RUnlock()
1392 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemAniBPCDResp)
1393 }
1394 default:
1395 {
1396 oFsm.mutexPLastTxMeInstance.RUnlock()
1397 logger.Warnw(ctx, "Unsupported ME name received!",
1398 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1399 }
mpagenko8b07c1b2020-11-26 10:36:31 +00001400 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001401 } else {
1402 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001403 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001404 } else {
1405 oFsm.mutexPLastTxMeInstance.RUnlock()
1406 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko8b07c1b2020-11-26 10:36:31 +00001407 }
1408}
1409
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(ctx context.Context, msg OmciMessage) {
1411 logger.Debugw(ctx, "Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001412 "msgType": msg.OmciMsg.MessageType})
1413
1414 switch msg.OmciMsg.MessageType {
1415 case omci.CreateResponseType:
1416 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001417 oFsm.handleOmciAniConfigCreateResponseMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301418
mpagenko3dbcdd22020-07-22 07:38:45 +00001419 } //CreateResponseType
1420 case omci.SetResponseType:
1421 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001422 oFsm.handleOmciAniConfigSetResponseMessage(ctx, msg)
mpagenko3dbcdd22020-07-22 07:38:45 +00001423
mpagenko3dbcdd22020-07-22 07:38:45 +00001424 } //SetResponseType
mpagenko8b07c1b2020-11-26 10:36:31 +00001425 case omci.DeleteResponseType:
1426 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001427 oFsm.handleOmciAniConfigDeleteResponseMessage(ctx, msg)
mpagenko8b07c1b2020-11-26 10:36:31 +00001428
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001429 } //DeleteResponseType
mpagenko3dbcdd22020-07-22 07:38:45 +00001430 default:
1431 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001432 logger.Errorw(ctx, "uniPonAniConfigFsm - Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001433 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001434 return
1435 }
1436 }
1437}
1438
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001440 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1441 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001443 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1444 "TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001445 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001446 meParams := me.ParamData{
1447 EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
1448 Attributes: me.AttributeValueMap{
1449 "PortId": gemPortAttribs.gemPortID,
1450 "TContPointer": oFsm.tcont0ID,
1451 "Direction": gemPortAttribs.direction,
1452 //ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
1453 // TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
1454 "TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
1455 "PriorityQueuePointerForDownStream": gemPortAttribs.downQueueID,
1456 },
1457 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001458 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001459 meInstance, err := oFsm.pOmciCC.sendCreateGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001460 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001461 if err != nil {
1462 oFsm.mutexPLastTxMeInstance.Unlock()
1463 logger.Errorw(ctx, "GemNCTPVar create failed, aborting uniPonAniConfigFsm!",
1464 log.Fields{"device-id": oFsm.deviceID})
1465 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1466 return
1467 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001468 //accept also nil as (error) return value for writing to LastTx
1469 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001470 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001471 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001472 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001473 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001474 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475 logger.Errorw(ctx, "GemNWCtp create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001476 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301477 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001478 return
1479 }
Girish Gowdra50e56422021-06-01 16:46:04 -07001480 // Mark the gem port to be added for Performance History monitoring
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001481 if oFsm.pDeviceHandler.pOnuMetricsMgr != nil {
Girish Gowdra69570d92021-04-22 18:26:20 -07001482 oFsm.pDeviceHandler.pOnuMetricsMgr.AddGemPortForPerfMonitoring(ctx, gemPortAttribs.gemPortID)
Girish Gowdra5c5aaf42021-02-17 19:40:50 -08001483 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001484 } //for all GemPorts of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001485
1486 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 logger.Debugw(ctx, "GemNWCtp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301488 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001489}
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001490func (oFsm *uniPonAniConfigFsm) hasMulticastGem(ctx context.Context) bool {
1491 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
1492 if gemPortAttribs.isMulticast {
1493 logger.Debugw(ctx, "Found multicast gem", log.Fields{"device-id": oFsm.deviceID})
1494 return true
1495 }
1496 }
1497 return false
1498}
mpagenko3dbcdd22020-07-22 07:38:45 +00001499
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs(ctx context.Context) {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001501 // for all GemPorts of this T-Cont as given by the size of set gemPortAttribsSlice
1502 for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001504 "EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
1505 "SPPtr": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001506 "device-id": oFsm.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001507
ozgecanetsia4b232302020-11-11 10:58:10 +03001508 //TODO if the port has only downstream direction the isMulticast flag can be removed.
1509 if gemPortAttribs.isMulticast {
ozgecanetsia4b232302020-11-11 10:58:10 +03001510
1511 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001512 EntityID: gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001513 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001514 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001515 "InterworkingOption": 0, // Don't Care
1516 "ServiceProfilePointer": 0, // Don't Care
1517 "GalProfilePointer": galEthernetEID,
ozgecanetsia4b232302020-11-11 10:58:10 +03001518 },
1519 }
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03001520 if oFsm.pUniTechProf.multicastConfiguredForOtherUniTps(ctx, oFsm.uniTpKey) {
1521 logger.Debugw(ctx, "MulticastGemInterworkingTP already exist", log.Fields{"device-id": oFsm.deviceID, "multicast-gem-id": gemPortAttribs.multicastGemID})
1522 continue
1523 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001524 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001525 meInstance, err := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsia4b232302020-11-11 10:58:10 +03001526 true, oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001527 if err != nil {
1528 oFsm.mutexPLastTxMeInstance.Unlock()
1529 logger.Errorw(ctx, "MulticastGemIWTPVar create failed, aborting uniPonAniConfigFsm!",
1530 log.Fields{"device-id": oFsm.deviceID})
1531 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1532 return
1533
1534 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001535 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001536 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001537 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001538 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001539 if err != nil {
ozgecanetsiab36ed572021-04-01 10:38:48 +03001540 logger.Errorw(ctx, "MulticastGemIWTP create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001541 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
1542 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1543 return
1544 }
1545 ipv4MulticastTable := make([]uint8, 12)
1546 //Gem Port ID
1547 binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
1548 //Secondary Key
1549 binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
1550 // Multicast IP range start This is the 224.0.0.1 address
1551 binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
1552 // MulticastIp range stop
1553 binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1554
1555 meIPV4MCTableParams := me.ParamData{
1556 EntityID: gemPortAttribs.multicastGemID,
1557 Attributes: me.AttributeValueMap{
1558 "Ipv4MulticastAddressTable": ipv4MulticastTable,
1559 },
1560 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001561 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001562 meIPV4MCTableInstance, err := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001563 true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001564 if err != nil {
1565 oFsm.mutexPLastTxMeInstance.Unlock()
1566 logger.Errorw(ctx, "MulticastGemIWTPVar set failed, aborting uniPonAniConfigFsm!",
1567 log.Fields{"device-id": oFsm.deviceID})
1568 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1569 return
1570 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001571 oFsm.pLastTxMeInstance = meIPV4MCTableInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001572 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001573
1574 } else {
1575 meParams := me.ParamData{
1576 EntityID: gemPortAttribs.gemPortID,
1577 Attributes: me.AttributeValueMap{
1578 "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
1579 "InterworkingOption": 5, //fixed model:: G.998 .1pMapper
1580 "ServiceProfilePointer": oFsm.mapperSP0ID,
1581 "InterworkingTerminationPointPointer": 0, //not used with .1PMapper Mac bridge
1582 "GalProfilePointer": galEthernetEID,
1583 },
1584 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001585 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001586 meInstance, err := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsia4b232302020-11-11 10:58:10 +03001587 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001588 if err != nil {
1589 oFsm.mutexPLastTxMeInstance.Unlock()
1590 logger.Errorw(ctx, "GEMIWTPVar create failed, aborting uniPonAniConfigFsm!",
1591 log.Fields{"device-id": oFsm.deviceID})
1592 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1593 return
1594 }
ozgecanetsia4b232302020-11-11 10:58:10 +03001595 //accept also nil as (error) return value for writing to LastTx
1596 // - this avoids misinterpretation of new received OMCI messages
1597 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001598 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia4b232302020-11-11 10:58:10 +03001599 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001600 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001601 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001602 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 logger.Errorw(ctx, "GemTP create failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001604 log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
Himani Chawla4d908332020-08-31 12:30:20 +05301605 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001606 return
1607 }
1608 } //for all GemPort's of this T-Cont
mpagenko3dbcdd22020-07-22 07:38:45 +00001609
1610 // if Config has been done for all GemPort instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 logger.Debugw(ctx, "GemIwTp create loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301612 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001613}
1614
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615func (oFsm *uniPonAniConfigFsm) performSettingPQs(ctx context.Context) {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -07001616 //If upstream PQs were set before, then no need to set them again. Let state machine to proceed.
1617 if oFsm.tcontSetBefore {
1618 logger.Debugw(ctx, "No need to set PQs again.", log.Fields{
1619 "device-id": oFsm.deviceID, "tcont": oFsm.alloc0ID,
1620 "uni-id": oFsm.pOnuUniPort.uniID,
1621 "techProfile-id": oFsm.techProfileID})
1622 go func(aPAFsm *AdapterFsm) {
1623 if aPAFsm != nil && aPAFsm.pFsm != nil {
1624 _ = aPAFsm.pFsm.Event(aniEvRxPrioqsResp)
1625 }
1626 }(oFsm.pAdaptFsm)
1627 return
1628 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001629 const cu16StrictPrioWeight uint16 = 0xFFFF
1630 //find all upstream PrioQueues related to this T-Cont
1631 loQueueMap := ordered_map.NewOrderedMap()
1632 for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001633 if gemPortAttribs.isMulticast {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debugw(ctx, "uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001635 "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
1636 "prioString": gemPortAttribs.pbitString})
1637 continue
1638 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001639 if gemPortAttribs.qosPolicy == "WRR" {
Himani Chawla4d908332020-08-31 12:30:20 +05301640 if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001641 //key does not yet exist
1642 loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
1643 }
1644 } else {
1645 loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
1646 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001647 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001648
Girish Gowdra09e5f212021-09-30 16:28:36 -07001649 trafficSchedPtrSetSupported := false
1650 loOnu2g := oFsm.pOnuDB.GetMe(me.Onu2GClassID, onu2gMeID)
1651 if loOnu2g == nil {
1652 logger.Errorw(ctx, "onu2g is nil, cannot read qos configuration flexibility parameter",
1653 log.Fields{"device-id": oFsm.deviceID})
1654 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1655 return
1656 }
1657 returnVal := loOnu2g["QualityOfServiceQosConfigurationFlexibility"]
1658 if returnVal != nil {
1659 if qosCfgFlexParam, err := oFsm.pOnuDB.getUint16Attrib(returnVal); err == nil {
1660 trafficSchedPtrSetSupported = qosCfgFlexParam&bitTrafficSchedulerPtrSetPermitted == bitTrafficSchedulerPtrSetPermitted
1661 logger.Debugw(ctx, "trafficSchedPtrSetSupported set",
1662 log.Fields{"qosCfgFlexParam": qosCfgFlexParam, "trafficSchedPtrSetSupported": trafficSchedPtrSetSupported})
1663 } else {
1664 logger.Errorw(ctx, "Cannot extract qos configuration flexibility parameter",
1665 log.Fields{"device-id": oFsm.deviceID})
1666 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1667 return
1668 }
1669 } else {
1670 logger.Errorw(ctx, "Cannot read qos configuration flexibility parameter",
1671 log.Fields{"device-id": oFsm.deviceID})
1672 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1673 return
1674 }
1675
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001676 //TODO: assumption here is that ONU data uses SP setting in the T-Cont and WRR in the TrafficScheduler
1677 // if that is not the case, the reverse case could be checked and reacted accordingly or if the
1678 // complete chain is not valid, then some error should be thrown and configuration can be aborted
1679 // or even be finished without correct SP/WRR setting
1680
1681 //TODO: search for the (WRR)trafficScheduler related to the T-Cont of this queue
1682 //By now assume fixed value 0x8000, which is the only announce BBSIM TrafficScheduler,
1683 // even though its T-Cont seems to be wrong ...
1684 loTrafficSchedulerEID := 0x8000
1685 //for all found queues
1686 iter := loQueueMap.IterFunc()
1687 for kv, ok := iter(); ok; kv, ok = iter() {
1688 queueIndex := (kv.Key).(uint16)
1689 meParams := me.ParamData{
1690 EntityID: queueIndex,
Himani Chawla4d908332020-08-31 12:30:20 +05301691 Attributes: make(me.AttributeValueMap),
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001692 }
Girish Gowdra09e5f212021-09-30 16:28:36 -07001693 if trafficSchedPtrSetSupported {
1694 if (kv.Value).(uint16) == cu16StrictPrioWeight {
1695 //StrictPrio indication
1696 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
1697 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1698 "device-id": oFsm.deviceID})
1699 meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
1700 } else {
1701 //WRR indication
1702 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
1703 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1704 "Weight": kv.Value,
1705 "device-id": oFsm.deviceID})
1706 meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
1707 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1708 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001709 } else {
Girish Gowdra09e5f212021-09-30 16:28:36 -07001710 // setting Traffic Scheduler (TS) pointer is not supported unless we point to another TS that points to the same TCONT.
1711 // For now lets use TS that is hardwired in the ONU and just update the weight in case of WRR, which in fact is all we need at the moment.
1712 // The code could get unnecessarily convoluted if we provide the flexibility try to find and point to another TS that points to the same TCONT.
1713 if (kv.Value).(uint16) == cu16StrictPrioWeight { // SP case, nothing to be done. Proceed to the next queue
1714 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio, traffic sched ptr set unsupported", log.Fields{
1715 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1716 "device-id": oFsm.deviceID})
1717 continue
1718 }
1719 // WRR case, update weight.
1720 logger.Debugw(ctx, "uniPonAniConfigFsm Tx Set::PrioQueue to WRR, traffic sched ptr set unsupported", log.Fields{
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001721 "EntitytId": strconv.FormatInt(int64(queueIndex), 16),
1722 "Weight": kv.Value,
mpagenko01e726e2020-10-23 09:45:29 +00001723 "device-id": oFsm.deviceID})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001724 meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
1725 }
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001726 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001727 meInstance, err := oFsm.pOmciCC.sendSetPrioQueueVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001728 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001729 if err != nil {
1730 oFsm.mutexPLastTxMeInstance.Unlock()
1731 logger.Errorw(ctx, "PrioQueueVar set failed, aborting uniPonAniConfigFsm!",
1732 log.Fields{"device-id": oFsm.deviceID})
1733 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1734 return
1735 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001736 //accept also nil as (error) return value for writing to LastTx
1737 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001738 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt9902b2b2021-04-21 14:52:32 +00001739 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001740
1741 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001742 err = oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001743 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Errorw(ctx, "PrioQueue set failed, aborting AniConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001745 log.Fields{"device-id": oFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
Himani Chawla4d908332020-08-31 12:30:20 +05301746 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001747 return
1748 }
1749
1750 //TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
1751 // write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
1752 // of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
1753 // not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
1754
1755 } //for all upstream prioQueues
mpagenko3dbcdd22020-07-22 07:38:45 +00001756
1757 // if Config has been done for all PrioQueue instances let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 logger.Debugw(ctx, "PrioQueue set loop finished", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301759 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
mpagenko3dbcdd22020-07-22 07:38:45 +00001760}
1761
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762func (oFsm *uniPonAniConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00001763 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00001764 if oFsm.isCanceled {
1765 // FSM already canceled before entering wait
1766 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
1767 oFsm.mutexIsAwaitingResponse.Unlock()
1768 return fmt.Errorf(cErrWaitAborted)
1769 }
mpagenko7d6bb022021-03-11 15:07:55 +00001770 oFsm.isAwaitingResponse = true
1771 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001772 select {
Himani Chawla4d908332020-08-31 12:30:20 +05301773 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenko3dbcdd22020-07-22 07:38:45 +00001774 // case <-ctx.Done():
mpagenko01e726e2020-10-23 09:45:29 +00001775 // logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001776 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 +00001777 logger.Warnw(ctx, "UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001778 oFsm.mutexIsAwaitingResponse.Lock()
1779 oFsm.isAwaitingResponse = false
1780 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001781 return fmt.Errorf("uniPonAniConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenko3dbcdd22020-07-22 07:38:45 +00001782 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301783 if success {
mpagenkocf48e452021-04-23 09:23:00 +00001784 logger.Debugw(ctx, "uniPonAniConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001785 oFsm.mutexIsAwaitingResponse.Lock()
1786 oFsm.isAwaitingResponse = false
1787 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko3dbcdd22020-07-22 07:38:45 +00001788 return nil
1789 }
mpagenko7d6bb022021-03-11 15:07:55 +00001790 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00001791 logger.Debugw(ctx, "uniPonAniConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00001792 oFsm.mutexIsAwaitingResponse.Lock()
1793 oFsm.isAwaitingResponse = false
1794 oFsm.mutexIsAwaitingResponse.Unlock()
1795 return fmt.Errorf(cErrWaitAborted)
mpagenko3dbcdd22020-07-22 07:38:45 +00001796 }
1797}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001798
1799func (oFsm *uniPonAniConfigFsm) setChanSet(flagValue bool) {
1800 oFsm.mutexChanSet.Lock()
1801 oFsm.chanSet = flagValue
1802 oFsm.mutexChanSet.Unlock()
1803}
1804
1805func (oFsm *uniPonAniConfigFsm) isChanSet() bool {
1806 oFsm.mutexChanSet.RLock()
1807 flagValue := oFsm.chanSet
1808 oFsm.mutexChanSet.RUnlock()
1809 return flagValue
1810}