blob: 58e78a468b9ea7c1cad0d044fa49c3c7b879aa73 [file] [log] [blame]
mpagenko80622a52021-02-09 16:53:23 +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"
22 "fmt"
23 "strconv"
24 "time"
25
26 "github.com/boguslaw-wojcik/crc32a"
27 "github.com/looplab/fsm"
28 "github.com/opencord/omci-lib-go"
29 me "github.com/opencord/omci-lib-go/generated"
30 "github.com/opencord/voltha-lib-go/v4/pkg/log"
31 "github.com/opencord/voltha-protos/v4/go/voltha"
32)
33
34const cMaxUint32 = ^uint32(0)
35
36const (
37 // internal predefined values - some off them should later be configurable (perhaps with theses as defaults)
38 cOmciDownloadSectionSize = 31 //in bytes
39 cOmciDownloadWindowSizeLimit = 31 //in sections for window offset (windowSize(32)-1)
40 //cOmciDownloadWindowRetryMax = 2 // max attempts for a specific window
41 cOmciSectionInterleaveMilliseconds = 100 //DownloadSection interleave time in milliseconds
42 cOmciEndSwDlDelaySeconds = 1 //End Software Download delay after last section (may be also configurable?)
mpagenko59498c12021-03-18 14:15:15 +000043 cWaitCountEndSwDl = 6 //maximum number of EndSwDl requests
44 cWaitDelayEndSwDlSeconds = 10 //duration, how long is waited before next request on EndSwDl
mpagenko80622a52021-02-09 16:53:23 +000045 //cOmciDownloadCompleteTimeout = 5400 //in s for the complete timeout (may be better scale to image size/ noOfWindows)
46)
47
48const (
49 // events of config PON ANI port FSM
50 upgradeEvStart = "upgradeEvStart"
51 upgradeEvPrepareSwDownload = "upgradeEvPrepareSwDownload"
52 upgradeEvRxStartSwDownload = "upgradeEvRxStartSwDownload"
53 upgradeEvWaitWindowAck = "upgradeEvWaitWindowAck"
54 upgradeEvContinueNextWindow = "upgradeEvContinueNextWindow"
55 upgradeEvEndSwDownload = "upgradeEvEndSwDownload"
mpagenko59498c12021-03-18 14:15:15 +000056 upgradeEvWaitEndDownload = "upgradeEvWaitEndDownload"
57 upgradeEvContinueFinalize = "upgradeEvContinueFinalize"
mpagenko80622a52021-02-09 16:53:23 +000058 upgradeEvRequestActivate = "upgradeEvRequestActivate"
59 upgradeEvWaitForCommit = "upgradeEvWaitForCommit"
60 upgradeEvCommitSw = "upgradeEvCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000061 upgradeEvCheckCommitted = "upgradeEvCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000062
63 //upgradeEvTimeoutSimple = "upgradeEvTimeoutSimple"
64 //upgradeEvTimeoutMids = "upgradeEvTimeoutMids"
65 upgradeEvReset = "upgradeEvReset"
66 upgradeEvAbort = "upgradeEvAbort"
67 upgradeEvRestart = "upgradeEvRestart"
68)
69
70const (
71 // states of config PON ANI port FSM
72 upgradeStDisabled = "upgradeStDisabled"
73 upgradeStStarting = "upgradeStStarting"
74 upgradeStPreparingDL = "upgradeStPreparingDL"
75 upgradeStDLSection = "upgradeStDLSection"
76 upgradeStVerifyWindow = "upgradeStVerifyWindow"
77 upgradeStFinalizeDL = "upgradeStFinalizeDL"
mpagenko59498c12021-03-18 14:15:15 +000078 upgradeStWaitEndDL = "upgradeStWaitEndDL"
mpagenko80622a52021-02-09 16:53:23 +000079 upgradeStRequestingActivate = "upgradeStRequestingActivate"
80 upgradeStWaitForCommit = "upgradeStWaitForCommit"
81 upgradeStCommitSw = "upgradeStCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000082 upgradeStCheckCommitted = "upgradeStCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000083 upgradeStResetting = "upgradeStResetting"
84)
85
86//required definition for IdleState detection for activities on OMCI
87const cOnuUpgradeFsmIdleState = upgradeStWaitForCommit
88
89//OnuUpgradeFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
90type OnuUpgradeFsm struct {
91 pDeviceHandler *deviceHandler
92 pDownloadManager *adapterDownloadManager
93 deviceID string
mpagenko15ff4a52021-03-02 10:09:20 +000094 pOnuOmciDevice *OnuDeviceEntry
mpagenko80622a52021-02-09 16:53:23 +000095 pOmciCC *omciCC
96 pOnuDB *onuDeviceDB
97 requestEvent OnuDeviceEvent
98 //omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
mpagenko59498c12021-03-18 14:15:15 +000099 pAdaptFsm *AdapterFsm
100 pImageDsc *voltha.ImageDownload
101 imageBuffer []byte
102 origImageLength uint32 //as also limited by OMCI
103 imageCRC uint32 //as per OMCI - ITU I.363.5 crc
104 imageLength uint32 //including last bytes padding
105 omciDownloadWindowSizeLimit uint8 //windowSize-1 in sections
106 omciDownloadWindowSizeLast uint8 //number of sections in last window
107 noOfSections uint32 //uint32 range for sections should be sufficient for very long images
108 nextDownloadSectionsAbsolute uint32 //number of next section to download in overall image
109 nextDownloadSectionsWindow uint8 //number of next section to download within current window
110 noOfWindows uint32 //uint32 range for windows should be sufficient for very long images
111 nextDownloadWindow uint32 //number of next window to download
112 inactiveImageMeID uint16 //ME-ID of the inactive image
113 omciSectionInterleaveDelay time.Duration //DownloadSectionInterleave delay in milliseconds
114 delayEndSwDl bool //flag to provide a delay between last section and EndSwDl
115 pLastTxMeInstance *me.ManagedEntity
116 waitCountEndSwDl uint8 //number, how often is waited for EndSwDl at maximum
117 waitDelayEndSwDl time.Duration //duration, how long is waited before next request on EndSwDl
118 chReceiveExpectedResponse chan bool
mpagenko80622a52021-02-09 16:53:23 +0000119}
120
121//NewOnuUpgradeFsm is the 'constructor' for the state machine to config the PON ANI ports
122// of ONU UNI ports via OMCI
123func NewOnuUpgradeFsm(ctx context.Context, apDeviceHandler *deviceHandler,
mpagenko15ff4a52021-03-02 10:09:20 +0000124 apDevEntry *OnuDeviceEntry, apOnuDB *onuDeviceDB,
mpagenko80622a52021-02-09 16:53:23 +0000125 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message) *OnuUpgradeFsm {
126 instFsm := &OnuUpgradeFsm{
mpagenko59498c12021-03-18 14:15:15 +0000127 pDeviceHandler: apDeviceHandler,
128 deviceID: apDeviceHandler.deviceID,
129 pOnuOmciDevice: apDevEntry,
130 pOmciCC: apDevEntry.PDevOmciCC,
131 pOnuDB: apOnuDB,
132 requestEvent: aRequestEvent,
133 omciDownloadWindowSizeLimit: cOmciDownloadWindowSizeLimit,
134 omciSectionInterleaveDelay: cOmciSectionInterleaveMilliseconds,
135 waitCountEndSwDl: cWaitCountEndSwDl,
136 waitDelayEndSwDl: cWaitDelayEndSwDlSeconds,
mpagenko80622a52021-02-09 16:53:23 +0000137 }
mpagenko59498c12021-03-18 14:15:15 +0000138 instFsm.chReceiveExpectedResponse = make(chan bool)
mpagenko80622a52021-02-09 16:53:23 +0000139
140 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
141 if instFsm.pAdaptFsm == nil {
142 logger.Errorw(ctx, "OnuUpgradeFsm's AdapterFsm could not be instantiated!!", log.Fields{
143 "device-id": instFsm.deviceID})
144 return nil
145 }
146 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
147 upgradeStDisabled,
148 fsm.Events{
149 {Name: upgradeEvStart, Src: []string{upgradeStDisabled}, Dst: upgradeStStarting},
150 {Name: upgradeEvPrepareSwDownload, Src: []string{upgradeStStarting}, Dst: upgradeStPreparingDL},
151 {Name: upgradeEvRxStartSwDownload, Src: []string{upgradeStPreparingDL}, Dst: upgradeStDLSection},
152 {Name: upgradeEvWaitWindowAck, Src: []string{upgradeStDLSection}, Dst: upgradeStVerifyWindow},
153 {Name: upgradeEvContinueNextWindow, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStDLSection},
154 {Name: upgradeEvEndSwDownload, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStFinalizeDL},
mpagenko59498c12021-03-18 14:15:15 +0000155 {Name: upgradeEvWaitEndDownload, Src: []string{upgradeStFinalizeDL}, Dst: upgradeStWaitEndDL},
156 {Name: upgradeEvContinueFinalize, Src: []string{upgradeStWaitEndDL}, Dst: upgradeStFinalizeDL},
157 {Name: upgradeEvRequestActivate, Src: []string{upgradeStWaitEndDL}, Dst: upgradeStRequestingActivate},
mpagenko80622a52021-02-09 16:53:23 +0000158 {Name: upgradeEvWaitForCommit, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStWaitForCommit},
159 {Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStWaitForCommit},
160 Dst: upgradeStCommitSw},
mpagenko15ff4a52021-03-02 10:09:20 +0000161 {Name: upgradeEvCheckCommitted, Src: []string{upgradeStCommitSw}, Dst: upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000162
163 /*
164 {Name: upgradeEvTimeoutSimple, Src: []string{
165 upgradeStCreatingDot1PMapper, upgradeStCreatingMBPCD, upgradeStSettingTconts, upgradeStSettingDot1PMapper}, Dst: upgradeStStarting},
166 {Name: upgradeEvTimeoutMids, Src: []string{
167 upgradeStCreatingGemNCTPs, upgradeStCreatingGemIWs, upgradeStSettingPQs}, Dst: upgradeStStarting},
168 */
169 // exceptional treatments
170 {Name: upgradeEvReset, Src: []string{upgradeStStarting, upgradeStPreparingDL, upgradeStDLSection,
mpagenko59498c12021-03-18 14:15:15 +0000171 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStRequestingActivate,
mpagenko15ff4a52021-03-02 10:09:20 +0000172 upgradeStCommitSw, upgradeStCheckCommitted}, //upgradeStWaitForCommit is not reset (later perhaps also not upgradeStWaitActivate)
mpagenko80622a52021-02-09 16:53:23 +0000173 Dst: upgradeStResetting},
174 {Name: upgradeEvAbort, Src: []string{upgradeStStarting, upgradeStPreparingDL, upgradeStDLSection,
mpagenko59498c12021-03-18 14:15:15 +0000175 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStRequestingActivate,
mpagenko15ff4a52021-03-02 10:09:20 +0000176 upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000177 Dst: upgradeStResetting},
178 {Name: upgradeEvRestart, Src: []string{upgradeStResetting}, Dst: upgradeStDisabled},
179 },
180 fsm.Callbacks{
181 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
182 "enter_" + upgradeStStarting: func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
183 "enter_" + upgradeStPreparingDL: func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
184 "enter_" + upgradeStDLSection: func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
185 "enter_" + upgradeStVerifyWindow: func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
186 "enter_" + upgradeStFinalizeDL: func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
mpagenko59498c12021-03-18 14:15:15 +0000187 "enter_" + upgradeStWaitEndDL: func(e *fsm.Event) { instFsm.enterWaitEndDL(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000188 "enter_" + upgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
189 "enter_" + upgradeStCommitSw: func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
mpagenko15ff4a52021-03-02 10:09:20 +0000190 "enter_" + upgradeStCheckCommitted: func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000191 "enter_" + upgradeStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
192 "enter_" + upgradeStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
193 },
194 )
195 if instFsm.pAdaptFsm.pFsm == nil {
196 logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
197 "device-id": instFsm.deviceID})
198 return nil
199 }
200
201 logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
202 return instFsm
203}
204
205//SetDownloadParams configures the needed parameters for a specific download to the ONU
mpagenko15ff4a52021-03-02 10:09:20 +0000206func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
207 apImageDsc *voltha.ImageDownload, apDownloadManager *adapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +0000208 pBaseFsm := oFsm.pAdaptFsm.pFsm
209 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
210 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
211 "device-id": oFsm.deviceID, "image-description": apImageDsc})
mpagenko15ff4a52021-03-02 10:09:20 +0000212 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenko80622a52021-02-09 16:53:23 +0000213 oFsm.pImageDsc = apImageDsc
214 oFsm.pDownloadManager = apDownloadManager
215
216 go func(aPBaseFsm *fsm.FSM) {
217 // let the upgrade FSm proceed to PreparinDL
218 _ = aPBaseFsm.Event(upgradeEvPrepareSwDownload)
219 }(pBaseFsm)
220 return nil
221 }
222 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
223 "device-id": oFsm.deviceID})
224 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
225}
226
227func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
228 logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
229 "device-id": oFsm.deviceID})
230
231 // start go routine for processing of LockState messages
232 go oFsm.processOmciUpgradeMessages(ctx)
233}
234
235func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
236 logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
237 "device-id": oFsm.deviceID})
238
239 fileLen, err := oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
240 if err != nil || fileLen > int64(cMaxUint32) {
241 logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
242 "device-id": oFsm.deviceID, "error": err, "length": fileLen})
243 pBaseFsm := oFsm.pAdaptFsm
244 // Can't call FSM Event directly, decoupling it
245 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000246 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000247 }(pBaseFsm)
248 return
249 }
250
251 oFsm.imageBuffer = make([]byte, fileLen)
252 oFsm.imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
253 if err != nil {
254 logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
255 "device-id": oFsm.deviceID, "error": err})
256 pBaseFsm := oFsm.pAdaptFsm
257 // Can't call FSM Event directly, decoupling it
258 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000259 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000260 }(pBaseFsm)
261 return
262 }
263
264 oFsm.noOfSections = uint32(fileLen / cOmciDownloadSectionSize)
265 if fileLen%cOmciDownloadSectionSize > 0 {
266 bufferPadding := make([]byte, cOmciDownloadSectionSize-uint32(fileLen%cOmciDownloadSectionSize))
267 //expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
268 oFsm.imageBuffer = append(oFsm.imageBuffer[:fileLen], bufferPadding...)
269 oFsm.noOfSections++
270 }
271 oFsm.origImageLength = uint32(fileLen)
272 oFsm.imageLength = uint32(len(oFsm.imageBuffer))
mpagenko80622a52021-02-09 16:53:23 +0000273
274 logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
275 "MeId": oFsm.inactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
276 "ImageSize": oFsm.imageLength, "original file size": fileLen})
277 //"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
Girish Gowdra0b235842021-03-09 13:06:46 -0800278 err = oFsm.pOmciCC.sendStartSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000279 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength)
280 if err != nil {
281 logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
282 "device-id": oFsm.deviceID, "error": err})
283 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
284 pBaseFsm := oFsm.pAdaptFsm
285 // Can't call FSM Event directly, decoupling it
286 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000287 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000288 }(pBaseFsm)
289 return
290 }
291}
292
293func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
294 logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
295 "device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
296
297 var windowAckRequest uint8 = 0
298 var bufferStartOffset uint32
299 var bufferEndOffset uint32
300 var downloadSection []byte
301 framePrint := false //default no printing of downloadSection frames
302 if oFsm.nextDownloadSectionsAbsolute == 0 {
303 //debug print of first section frame
304 framePrint = true
305 }
306
307 for {
308 bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * cOmciDownloadSectionSize
309 bufferEndOffset = bufferStartOffset + cOmciDownloadSectionSize - 1 //for representing cOmciDownloadSectionSizeLimit values
310 logger.Debugw(ctx, "DlSection values are", log.Fields{
311 "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
312 "DlSectionWindow": oFsm.nextDownloadSectionsWindow,
313 "startOffset": bufferStartOffset, "endOffset": bufferEndOffset})
314 if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
315 logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
316 "device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
317 "bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
318 //logical error -- reset the FSM
319 pBaseFsm := oFsm.pAdaptFsm
320 // Can't call FSM Event directly, decoupling it
321 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000322 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000323 }(pBaseFsm)
324 return
325 }
326 downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
327 if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
328 windowAckRequest = 1
329 logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
330 "device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
331 }
332 if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
333 windowAckRequest = 1
334 framePrint = true //debug print of last frame
mpagenko15ff4a52021-03-02 10:09:20 +0000335 oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
336 logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000337 "device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
338 }
Girish Gowdra0b235842021-03-09 13:06:46 -0800339 err := oFsm.pOmciCC.sendDownloadSection(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000340 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, framePrint)
341 if err != nil {
342 logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
mpagenko15ff4a52021-03-02 10:09:20 +0000343 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
mpagenko80622a52021-02-09 16:53:23 +0000344 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
345 pBaseFsm := oFsm.pAdaptFsm
346 // Can't call FSM Event directly, decoupling it
347 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000348 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000349 }(pBaseFsm)
350 return
351 }
mpagenko80622a52021-02-09 16:53:23 +0000352 oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
353 if windowAckRequest == 1 {
354 pBaseFsm := oFsm.pAdaptFsm
355 // Can't call FSM Event directly, decoupling it
356 go func(a_pAFsm *AdapterFsm) {
357 _ = a_pAFsm.pFsm.Event(upgradeEvWaitWindowAck) //state transition to upgradeStVerifyWindow
358 }(pBaseFsm)
359 return
360 }
361 framePrint = false //for the next Section frame (if wanted, can be enabled in logic before sendXXX())
362 oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
mpagenko59498c12021-03-18 14:15:15 +0000363 if oFsm.omciSectionInterleaveDelay > 0 {
mpagenko80622a52021-02-09 16:53:23 +0000364 //ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
mpagenko59498c12021-03-18 14:15:15 +0000365 time.Sleep(oFsm.omciSectionInterleaveDelay * time.Millisecond)
mpagenko80622a52021-02-09 16:53:23 +0000366 }
367 }
368}
369
370func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
371 logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
372 "for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
373}
374
375func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
mpagenko80622a52021-02-09 16:53:23 +0000376 logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
mpagenko59498c12021-03-18 14:15:15 +0000377 "device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(oFsm.imageCRC), 16), "delay": oFsm.delayEndSwDl})
mpagenko80622a52021-02-09 16:53:23 +0000378
379 if oFsm.delayEndSwDl {
380 //give the ONU some time for image evaluation (hoping it does not base that on first EndSwDl itself)
381 // should not be set in case this state is used for real download abort (not yet implemented)
382 time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
383 }
384
mpagenko59498c12021-03-18 14:15:15 +0000385 pBaseFsm := oFsm.pAdaptFsm
386 if pBaseFsm == nil {
387 logger.Errorw(ctx, "EndSwDl abort: BaseFsm invalid", log.Fields{
388 "device-id": oFsm.deviceID})
389 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
390 // Can't call FSM Event directly, decoupling it
391 go func(a_pAFsm *AdapterFsm) {
392 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
393 }(pBaseFsm)
394 return
395 }
Girish Gowdra0b235842021-03-09 13:06:46 -0800396 err := oFsm.pOmciCC.sendEndSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko59498c12021-03-18 14:15:15 +0000397 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.origImageLength, oFsm.imageCRC)
mpagenko80622a52021-02-09 16:53:23 +0000398 if err != nil {
399 logger.Errorw(ctx, "EndSwDl abort: can't send section", log.Fields{
400 "device-id": oFsm.deviceID, "error": err})
401 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
mpagenko80622a52021-02-09 16:53:23 +0000402 // Can't call FSM Event directly, decoupling it
403 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000404 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000405 }(pBaseFsm)
406 return
407 }
mpagenko59498c12021-03-18 14:15:15 +0000408 // go waiting for the EndSwDLResponse and check, if the ONU is ready for activation
409 // Can't call FSM Event directly, decoupling it
410 go func(a_pAFsm *AdapterFsm) {
411 _ = a_pAFsm.pFsm.Event(upgradeEvWaitEndDownload)
412 }(pBaseFsm)
413}
414
415func (oFsm *OnuUpgradeFsm) enterWaitEndDL(ctx context.Context, e *fsm.Event) {
416 logger.Infow(ctx, "OnuUpgradeFsm WaitEndDl", log.Fields{
417 "device-id": oFsm.deviceID, "wait delay": oFsm.waitDelayEndSwDl * time.Second, "wait count": oFsm.waitCountEndSwDl})
418 if oFsm.waitCountEndSwDl == 0 {
419 logger.Errorw(ctx, "WaitEndDl abort: max limit of EndSwDL reached", log.Fields{
420 "device-id": oFsm.deviceID})
421 pBaseFsm := oFsm.pAdaptFsm
422 if pBaseFsm == nil {
423 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
424 "device-id": oFsm.deviceID})
425 return
426 }
427 go func(a_pAFsm *AdapterFsm) {
428 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
429 }(pBaseFsm)
430 return
431 }
432
433 oFsm.waitCountEndSwDl--
434 select {
435 case <-time.After(oFsm.waitDelayEndSwDl * time.Second):
436 pBaseFsm := oFsm.pAdaptFsm
437 if pBaseFsm == nil {
438 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
439 "device-id": oFsm.deviceID})
440 //FSM may be reset already from somewhere else, nothing we can do here anymore
441 return
442 }
443 //retry End SW DL
444 oFsm.delayEndSwDl = false //no more extra delay for the request
445 go func(a_pAFsm *AdapterFsm) {
446 _ = a_pAFsm.pFsm.Event(upgradeEvContinueFinalize)
447 }(pBaseFsm)
448 return
449 case success := <-oFsm.chReceiveExpectedResponse:
450 logger.Debugw(ctx, "WaitEndDl stop wait timer", log.Fields{"device-id": oFsm.deviceID})
451 pBaseFsm := oFsm.pAdaptFsm
452 if pBaseFsm == nil {
453 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
454 "device-id": oFsm.deviceID})
455 //FSM may be reset already from somewhere else, nothing we can do here anymore
456 return
457 }
458 if success {
459 //answer received with ready indication
460 go func(a_pAFsm *AdapterFsm) {
461 _ = a_pAFsm.pFsm.Event(upgradeEvRequestActivate)
462 }(pBaseFsm)
463 return
464 }
465 //timer was aborted
466 go func(a_pAFsm *AdapterFsm) {
467 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
468 }(pBaseFsm)
469 return
470 }
mpagenko80622a52021-02-09 16:53:23 +0000471}
472
473func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
474 logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
475 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
476
Girish Gowdra0b235842021-03-09 13:06:46 -0800477 err := oFsm.pOmciCC.sendActivateSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000478 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID)
479 if err != nil {
480 logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
481 "device-id": oFsm.deviceID, "error": err})
482 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
483 pBaseFsm := oFsm.pAdaptFsm
484 // Can't call FSM Event directly, decoupling it
485 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000486 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000487 }(pBaseFsm)
488 return
489 }
490}
491
492func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
mpagenko15ff4a52021-03-02 10:09:20 +0000493 if activeImageID, err := oFsm.pOnuOmciDevice.GetActiveImageMeID(ctx); err == nil {
494 //TODO!!: as long as testing with BBSIM and BBSIM not support upgrade tests following check needs to be deactivated
495 imageFit := true //TODO!!: test workaround as long as BBSIM does not fully support upgrade
496 if imageFit || activeImageID == oFsm.inactiveImageMeID {
497 logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
498 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID}) //more efficient activeImageID with above check
Girish Gowdra0b235842021-03-09 13:06:46 -0800499 err := oFsm.pOmciCC.sendCommitSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko15ff4a52021-03-02 10:09:20 +0000500 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID) //more efficient activeImageID with above check
501 if err != nil {
502 logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
503 "device-id": oFsm.deviceID, "error": err})
504 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
505 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
506 pBaseFsm := oFsm.pAdaptFsm
507 // Can't call FSM Event directly, decoupling it
508 go func(a_pAFsm *AdapterFsm) {
509 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
510 }(pBaseFsm)
511 return
512 }
513 return
514 }
515 logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
516 "device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.inactiveImageMeID})
517 //TODO!!!: possibly send event information for aborted upgrade (not activated)??
518 pBaseFsm := oFsm.pAdaptFsm
519 // Can't call FSM Event directly, decoupling it
520 go func(a_pAFsm *AdapterFsm) {
521 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
522 }(pBaseFsm)
523 return
524 }
525 logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
526 "device-id": oFsm.deviceID})
527 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
528 pBaseFsm := oFsm.pAdaptFsm
529 // Can't call FSM Event directly, decoupling it
530 go func(a_pAFsm *AdapterFsm) {
531 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
532 }(pBaseFsm)
533}
534
535func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
536 logger.Infow(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000537 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
mpagenko15ff4a52021-03-02 10:09:20 +0000538 requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
ozgecanetsiab36ed572021-04-01 10:38:48 +0300539 meInstance, err := oFsm.pOmciCC.sendGetMe(log.WithSpanFromContext(context.TODO(), ctx),
Girish Gowdra0b235842021-03-09 13:06:46 -0800540 me.SoftwareImageClassID, oFsm.inactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false, oFsm.pAdaptFsm.commChan)
mpagenko15ff4a52021-03-02 10:09:20 +0000541 //accept also nil as (error) return value for writing to LastTx
542 // - this avoids misinterpretation of new received OMCI messages
ozgecanetsiab36ed572021-04-01 10:38:48 +0300543 if err != nil {
544 logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
545 log.Fields{"device-id": oFsm.deviceID, "Error": err})
546 pOnuUpgradeFsm := oFsm.pAdaptFsm
547 if pOnuUpgradeFsm != nil {
548 go func(a_pAFsm *AdapterFsm) {
549 _ = a_pAFsm.pFsm.Event(upgradeEvReset)
550 }(pOnuUpgradeFsm)
551 }
552 return
553 }
mpagenko15ff4a52021-03-02 10:09:20 +0000554 oFsm.pLastTxMeInstance = meInstance
mpagenko80622a52021-02-09 16:53:23 +0000555}
556
557func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
558 logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
559
560 pConfigupgradeStateAFsm := oFsm.pAdaptFsm
561 if pConfigupgradeStateAFsm != nil {
562 // abort running message processing
563 fsmAbortMsg := Message{
564 Type: TestMsg,
565 Data: TestMessage{
566 TestMessageVal: AbortMessageProcessing,
567 },
568 }
569 pConfigupgradeStateAFsm.commChan <- fsmAbortMsg
570
571 //try to restart the FSM to 'disabled'
572 // Can't call FSM Event directly, decoupling it
573 go func(a_pAFsm *AdapterFsm) {
574 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
575 _ = a_pAFsm.pFsm.Event(upgradeEvRestart)
576 }
577 }(pConfigupgradeStateAFsm)
578 }
579}
580
581func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
582 logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko59498c12021-03-18 14:15:15 +0000583 //flush possible left-over channels
584 select {
585 case <-oFsm.chReceiveExpectedResponse:
586 logger.Debug(ctx, "OnuUpgradeFsm chReceiveExpectedResponse flushed", log.Fields{"for device-id": oFsm.deviceID})
587 default:
588 }
mpagenko80622a52021-02-09 16:53:23 +0000589 if oFsm.pDeviceHandler != nil {
590 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
591 go oFsm.pDeviceHandler.removeOnuUpgradeFsm(ctx)
592 }
593}
594
595func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
596 logger.Debugw(ctx, "Start OnuUpgradeFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
597loop:
598 for {
599 // case <-ctx.Done():
600 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
601 // break loop
602 message, ok := <-oFsm.pAdaptFsm.commChan
603 if !ok {
604 logger.Info(ctx, "OnuUpgradeFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
605 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
mpagenko15ff4a52021-03-02 10:09:20 +0000606 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000607 break loop
608 }
609 logger.Debugw(ctx, "OnuUpgradeFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
610
611 switch message.Type {
612 case TestMsg:
613 msg, _ := message.Data.(TestMessage)
614 if msg.TestMessageVal == AbortMessageProcessing {
615 logger.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
616 break loop
617 }
618 logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
619 case OMCI:
620 msg, _ := message.Data.(OmciMessage)
621 oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
622 default:
623 logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
624 "message.Type": message.Type})
625 }
626 }
627 logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
628}
629
630//nolint: gocyclo
631func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg OmciMessage) {
632 logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
633 "msgType": msg.OmciMsg.MessageType})
634
635 switch msg.OmciMsg.MessageType {
636 case omci.StartSoftwareDownloadResponseType:
637 {
638 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
639 if msgLayer == nil {
640 logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
641 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000642 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
643 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000644 return
645 }
646 msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
647 if !msgOk {
648 logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
649 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000650 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
651 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000652 return
653 }
654 logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
655 "device-id": oFsm.deviceID, "data-fields": msgObj})
656 if msgObj.Result != me.Success {
657 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
658 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
659 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000660 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
661 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000662 return
663 }
664 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
665 logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
666 if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
667 // also response WindowSize = 0 is a valid number for used Window size 1
668 logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
669 "acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
670 oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
671 }
672 oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
673 if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
674 oFsm.noOfWindows++
675 }
676 logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
677 "windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
678 "at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
679 oFsm.nextDownloadSectionsAbsolute = 0
680 oFsm.nextDownloadSectionsWindow = 0
681 oFsm.nextDownloadWindow = 0
682
683 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRxStartSwDownload)
684 return
685 }
686 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
687 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
688 // TODO!!!: possibly repeat the start request (once)?
mpagenko15ff4a52021-03-02 10:09:20 +0000689 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
690 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000691 return
692 } //StartSoftwareDownloadResponseType
693 case omci.DownloadSectionResponseType:
694 {
mpagenko80622a52021-02-09 16:53:23 +0000695 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
696 if msgLayer == nil {
697 logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
698 log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
mpagenko15ff4a52021-03-02 10:09:20 +0000699 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
700 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000701 return
702 }
703 msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
704 if !msgOk {
705 logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
706 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000707 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
708 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000709 return
710 }
711 logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
712 "device-id": oFsm.deviceID, "data-fields": msgObj})
713 if msgObj.Result != me.Success {
714 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
715 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko15ff4a52021-03-02 10:09:20 +0000716 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
717 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000718 return
719 }
720 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
721 sectionNumber := msgObj.SectionNumber
mpagenko15ff4a52021-03-02 10:09:20 +0000722 logger.Infow(ctx, "DlSectionResponse received", log.Fields{
723 "window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +0000724
mpagenko15ff4a52021-03-02 10:09:20 +0000725 oFsm.nextDownloadWindow++
726 if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
727 if sectionNumber != oFsm.omciDownloadWindowSizeLast {
mpagenko02cf1b22021-03-12 17:30:30 +0000728 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error last window - later: repeat window once?", //TODO!!!
mpagenko15ff4a52021-03-02 10:09:20 +0000729 log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
730 "expected section": oFsm.omciDownloadWindowSizeLast})
731 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
732 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
733 return
734 }
mpagenko59498c12021-03-18 14:15:15 +0000735 oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
736 oFsm.imageCRC = crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //store internal for multiple usage
mpagenko15ff4a52021-03-02 10:09:20 +0000737 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvEndSwDownload)
738 return
739 }
740 if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
741 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
mpagenko02cf1b22021-03-12 17:30:30 +0000742 log.Fields{"device-id": oFsm.deviceID, "actual-section": sectionNumber,
743 "expected section": oFsm.omciDownloadWindowSizeLimit})
mpagenko15ff4a52021-03-02 10:09:20 +0000744 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
745 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
746 return
747 }
748 oFsm.nextDownloadSectionsWindow = 0
749 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvContinueNextWindow)
mpagenko80622a52021-02-09 16:53:23 +0000750 return
751 }
mpagenko80622a52021-02-09 16:53:23 +0000752 logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
753 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +0000754 // TODO!!!: possibly repeat the download (section) (once)?
755 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
756 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000757 return
mpagenko80622a52021-02-09 16:53:23 +0000758 } //DownloadSectionResponseType
759 case omci.EndSoftwareDownloadResponseType:
760 {
761 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
762 if msgLayer == nil {
763 logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
764 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000765 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
766 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000767 return
768 }
769 msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
770 if !msgOk {
771 logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
772 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000773 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
774 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000775 return
776 }
777 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
778 "device-id": oFsm.deviceID, "data-fields": msgObj})
779 if msgObj.Result != me.Success {
mpagenko59498c12021-03-18 14:15:15 +0000780 if msgObj.Result == me.DeviceBusy {
781 //ONU indicates it is still processing the image - let the FSM just wait and then repeat the request
782 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse busy: waiting before sending new request", log.Fields{
783 "device-id": oFsm.deviceID})
784 return
785 }
mpagenko80622a52021-02-09 16:53:23 +0000786 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - later: drive FSM to abort state ?",
787 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
788 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000789 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
790 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000791 return
792 }
793 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
794 logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenko59498c12021-03-18 14:15:15 +0000795 oFsm.chReceiveExpectedResponse <- true //let the FSM proceed from the waitState
mpagenko80622a52021-02-09 16:53:23 +0000796 return
797 }
798 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
799 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
800 // TODO!!!: possibly repeat the end request (once)? or verify ONU upgrade state?
mpagenko15ff4a52021-03-02 10:09:20 +0000801 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
802 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000803 return
804 } //EndSoftwareDownloadResponseType
805 case omci.ActivateSoftwareResponseType:
806 {
807 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
808 if msgLayer == nil {
809 logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
810 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000811 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
812 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000813 return
814 }
815 msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
816 if !msgOk {
817 logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
818 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000819 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
820 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000821 return
822 }
823 logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
824 "device-id": oFsm.deviceID, "data-fields": msgObj})
825 if msgObj.Result != me.Success {
826 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
827 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
828 // TODO!!!: error treatment?, perhaps in the end reset the FSM
mpagenko15ff4a52021-03-02 10:09:20 +0000829 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
830 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000831 return
832 }
833 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenko02cf1b22021-03-12 17:30:30 +0000834 logger.Infow(ctx, "Expected ActivateSwResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +0000835 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
836 return
837 }
838 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
839 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +0000840 // TODO!!!: error treatment?
841 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
842 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000843 return
844 } //ActivateSoftwareResponseType
mpagenko15ff4a52021-03-02 10:09:20 +0000845 case omci.CommitSoftwareResponseType:
846 {
847 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
848 if msgLayer == nil {
849 logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
850 log.Fields{"device-id": oFsm.deviceID})
851 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
852 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
853 return
854 }
855 msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
856 if !msgOk {
857 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
858 log.Fields{"device-id": oFsm.deviceID})
859 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
860 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
861 return
862 }
mpagenkobf67a092021-03-17 09:52:28 +0000863 if msgObj.Result != me.Success {
mpagenko15ff4a52021-03-02 10:09:20 +0000864 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
865 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
866 // TODO!!!: error treatment?, perhaps in the end reset the FSM
867 return
mpagenkobf67a092021-03-17 09:52:28 +0000868 }
mpagenko15ff4a52021-03-02 10:09:20 +0000869 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
870 logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
871 //verifying committed image
872 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvCheckCommitted)
873 return
874 }
875 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse wrong ME instance: abort",
876 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
877 // TODO!!!: error treatment?
878 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
879 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
880 return
881 } //CommitSoftwareResponseType
882 case omci.GetResponseType:
883 {
884 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
885 if msgLayer == nil {
886 logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
887 log.Fields{"device-id": oFsm.deviceID})
888 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
889 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
890 return
891 }
892 msgObj, msgOk := msgLayer.(*omci.GetResponse)
893 if !msgOk {
894 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
895 log.Fields{"device-id": oFsm.deviceID})
896 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
897 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
898 return
899 }
900 logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
901 "device-id": oFsm.deviceID, "data-fields": msgObj})
902 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
903 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
904 if msgObj.Result != me.Success {
905 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
906 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
907 // TODO!!!: error treatment?, perhaps in the end reset the FSM
908 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
909 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
910 return
911 }
912 } else {
913 logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
914 log.Fields{"device-id": oFsm.deviceID})
915 return
916 }
917
918 meAttributes := msgObj.Attributes
919 imageIsCommitted := meAttributes["IsCommitted"].(uint8)
920 imageIsActive := meAttributes["IsActive"].(uint8)
921 imageVersion := trimStringFromInterface(meAttributes["Version"])
mpagenko02cf1b22021-03-12 17:30:30 +0000922 logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
mpagenko15ff4a52021-03-02 10:09:20 +0000923 log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
924 "version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
925
926 //a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
927 // indicated in the download image version string (version must be part of the image content itself)
928 // so checking that might be quite unreliable
mpagenko59498c12021-03-18 14:15:15 +0000929 if msgObj.EntityInstance == oFsm.inactiveImageMeID && imageIsActive == swIsActive &&
930 imageIsCommitted == swIsCommitted {
mpagenko15ff4a52021-03-02 10:09:20 +0000931 logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
932 //releasing the upgrade FSM
933 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvReset)
934 return
935 }
936 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
937 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
938 // TODO!!!: error treatment?
939 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
940 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
941 return
942 } //GetResponseType
mpagenko80622a52021-02-09 16:53:23 +0000943 default:
944 {
945 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
946 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
947 return
948 }
949 }
950}
951
952/*
953func (oFsm *OnuUpgradeFsm) waitforOmciResponse(ctx context.Context) error {
954 select {
955 // maybe be also some outside cancel (but no context modeled for the moment ...)
956 // case <-ctx.Done():
957 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
958 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
959 logger.Warnw(ctx, "OnuUpgradeFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
960 return fmt.Errorf("OnuUpgradeFsm multi entity timeout %s", oFsm.deviceID)
961 case success := <-oFsm.omciMIdsResponseReceived:
962 if success {
963 logger.Debug(ctx, "OnuUpgradeFsm multi entity response received")
964 return nil
965 }
966 // should not happen so far
967 logger.Warnw(ctx, "OnuUpgradeFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
968 return fmt.Errorf("OnuUpgradeFsm multi entity responseError %s", oFsm.deviceID)
969 }
970}
971*/