blob: 4150cc5c0dca4d51c1be7bd62deaf522f3b34f62 [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?)
43 //cOmciDownloadCompleteTimeout = 5400 //in s for the complete timeout (may be better scale to image size/ noOfWindows)
44)
45
46const (
47 // events of config PON ANI port FSM
48 upgradeEvStart = "upgradeEvStart"
49 upgradeEvPrepareSwDownload = "upgradeEvPrepareSwDownload"
50 upgradeEvRxStartSwDownload = "upgradeEvRxStartSwDownload"
51 upgradeEvWaitWindowAck = "upgradeEvWaitWindowAck"
52 upgradeEvContinueNextWindow = "upgradeEvContinueNextWindow"
53 upgradeEvEndSwDownload = "upgradeEvEndSwDownload"
54 upgradeEvRequestActivate = "upgradeEvRequestActivate"
55 upgradeEvWaitForCommit = "upgradeEvWaitForCommit"
56 upgradeEvCommitSw = "upgradeEvCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000057 upgradeEvCheckCommitted = "upgradeEvCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000058
59 //upgradeEvTimeoutSimple = "upgradeEvTimeoutSimple"
60 //upgradeEvTimeoutMids = "upgradeEvTimeoutMids"
61 upgradeEvReset = "upgradeEvReset"
62 upgradeEvAbort = "upgradeEvAbort"
63 upgradeEvRestart = "upgradeEvRestart"
64)
65
66const (
67 // states of config PON ANI port FSM
68 upgradeStDisabled = "upgradeStDisabled"
69 upgradeStStarting = "upgradeStStarting"
70 upgradeStPreparingDL = "upgradeStPreparingDL"
71 upgradeStDLSection = "upgradeStDLSection"
72 upgradeStVerifyWindow = "upgradeStVerifyWindow"
73 upgradeStFinalizeDL = "upgradeStFinalizeDL"
74 upgradeStRequestingActivate = "upgradeStRequestingActivate"
75 upgradeStWaitForCommit = "upgradeStWaitForCommit"
76 upgradeStCommitSw = "upgradeStCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000077 upgradeStCheckCommitted = "upgradeStCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000078 upgradeStResetting = "upgradeStResetting"
79)
80
81//required definition for IdleState detection for activities on OMCI
82const cOnuUpgradeFsmIdleState = upgradeStWaitForCommit
83
84//OnuUpgradeFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
85type OnuUpgradeFsm struct {
86 pDeviceHandler *deviceHandler
87 pDownloadManager *adapterDownloadManager
88 deviceID string
mpagenko15ff4a52021-03-02 10:09:20 +000089 pOnuOmciDevice *OnuDeviceEntry
mpagenko80622a52021-02-09 16:53:23 +000090 pOmciCC *omciCC
91 pOnuDB *onuDeviceDB
92 requestEvent OnuDeviceEvent
93 //omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
94 pAdaptFsm *AdapterFsm
95 pImageDsc *voltha.ImageDownload
96 imageBuffer []byte
97 origImageLength uint32 //as also limited by OMCI
98 imageLength uint32 //including last bytes padding
mpagenko15ff4a52021-03-02 10:09:20 +000099 omciDownloadWindowSizeLimit uint8 //windowSize-1 in sections
100 omciDownloadWindowSizeLast uint8 //number of sections in last window
mpagenko80622a52021-02-09 16:53:23 +0000101 noOfSections uint32 //uint32 range for sections should be sufficient for very long images
102 nextDownloadSectionsAbsolute uint32 //number of next section to download in overall image
103 nextDownloadSectionsWindow uint8 //number of next section to download within current window
104 noOfWindows uint32 //uint32 range for windows should be sufficient for very long images
105 nextDownloadWindow uint32 //number of next window to download
106 inactiveImageMeID uint16 //ME-ID of the inactive image
107 omciSectionInterleaveMilliseconds time.Duration //DownloadSectionInterleave delay in milliseconds
108 delayEndSwDl bool //flag to provide a delay between last section and EndSwDl
mpagenko15ff4a52021-03-02 10:09:20 +0000109 pLastTxMeInstance *me.ManagedEntity
mpagenko80622a52021-02-09 16:53:23 +0000110}
111
112//NewOnuUpgradeFsm is the 'constructor' for the state machine to config the PON ANI ports
113// of ONU UNI ports via OMCI
114func NewOnuUpgradeFsm(ctx context.Context, apDeviceHandler *deviceHandler,
mpagenko15ff4a52021-03-02 10:09:20 +0000115 apDevEntry *OnuDeviceEntry, apOnuDB *onuDeviceDB,
mpagenko80622a52021-02-09 16:53:23 +0000116 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message) *OnuUpgradeFsm {
117 instFsm := &OnuUpgradeFsm{
118 pDeviceHandler: apDeviceHandler,
119 deviceID: apDeviceHandler.deviceID,
mpagenko15ff4a52021-03-02 10:09:20 +0000120 pOnuOmciDevice: apDevEntry,
121 pOmciCC: apDevEntry.PDevOmciCC,
mpagenko80622a52021-02-09 16:53:23 +0000122 pOnuDB: apOnuDB,
123 requestEvent: aRequestEvent,
124 omciDownloadWindowSizeLimit: cOmciDownloadWindowSizeLimit,
125 omciSectionInterleaveMilliseconds: cOmciSectionInterleaveMilliseconds,
126 }
127
128 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
129 if instFsm.pAdaptFsm == nil {
130 logger.Errorw(ctx, "OnuUpgradeFsm's AdapterFsm could not be instantiated!!", log.Fields{
131 "device-id": instFsm.deviceID})
132 return nil
133 }
134 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
135 upgradeStDisabled,
136 fsm.Events{
137 {Name: upgradeEvStart, Src: []string{upgradeStDisabled}, Dst: upgradeStStarting},
138 {Name: upgradeEvPrepareSwDownload, Src: []string{upgradeStStarting}, Dst: upgradeStPreparingDL},
139 {Name: upgradeEvRxStartSwDownload, Src: []string{upgradeStPreparingDL}, Dst: upgradeStDLSection},
140 {Name: upgradeEvWaitWindowAck, Src: []string{upgradeStDLSection}, Dst: upgradeStVerifyWindow},
141 {Name: upgradeEvContinueNextWindow, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStDLSection},
142 {Name: upgradeEvEndSwDownload, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStFinalizeDL},
143 {Name: upgradeEvRequestActivate, Src: []string{upgradeStFinalizeDL}, Dst: upgradeStRequestingActivate},
144 {Name: upgradeEvWaitForCommit, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStWaitForCommit},
145 {Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStWaitForCommit},
146 Dst: upgradeStCommitSw},
mpagenko15ff4a52021-03-02 10:09:20 +0000147 {Name: upgradeEvCheckCommitted, Src: []string{upgradeStCommitSw}, Dst: upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000148
149 /*
150 {Name: upgradeEvTimeoutSimple, Src: []string{
151 upgradeStCreatingDot1PMapper, upgradeStCreatingMBPCD, upgradeStSettingTconts, upgradeStSettingDot1PMapper}, Dst: upgradeStStarting},
152 {Name: upgradeEvTimeoutMids, Src: []string{
153 upgradeStCreatingGemNCTPs, upgradeStCreatingGemIWs, upgradeStSettingPQs}, Dst: upgradeStStarting},
154 */
155 // exceptional treatments
156 {Name: upgradeEvReset, Src: []string{upgradeStStarting, upgradeStPreparingDL, upgradeStDLSection,
157 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStRequestingActivate,
mpagenko15ff4a52021-03-02 10:09:20 +0000158 upgradeStCommitSw, upgradeStCheckCommitted}, //upgradeStWaitForCommit is not reset (later perhaps also not upgradeStWaitActivate)
mpagenko80622a52021-02-09 16:53:23 +0000159 Dst: upgradeStResetting},
160 {Name: upgradeEvAbort, Src: []string{upgradeStStarting, upgradeStPreparingDL, upgradeStDLSection,
161 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStRequestingActivate,
mpagenko15ff4a52021-03-02 10:09:20 +0000162 upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000163 Dst: upgradeStResetting},
164 {Name: upgradeEvRestart, Src: []string{upgradeStResetting}, Dst: upgradeStDisabled},
165 },
166 fsm.Callbacks{
167 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
168 "enter_" + upgradeStStarting: func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
169 "enter_" + upgradeStPreparingDL: func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
170 "enter_" + upgradeStDLSection: func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
171 "enter_" + upgradeStVerifyWindow: func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
172 "enter_" + upgradeStFinalizeDL: func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
173 "enter_" + upgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
174 "enter_" + upgradeStCommitSw: func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
mpagenko15ff4a52021-03-02 10:09:20 +0000175 "enter_" + upgradeStCheckCommitted: func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000176 "enter_" + upgradeStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
177 "enter_" + upgradeStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
178 },
179 )
180 if instFsm.pAdaptFsm.pFsm == nil {
181 logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
182 "device-id": instFsm.deviceID})
183 return nil
184 }
185
186 logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
187 return instFsm
188}
189
190//SetDownloadParams configures the needed parameters for a specific download to the ONU
mpagenko15ff4a52021-03-02 10:09:20 +0000191func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
192 apImageDsc *voltha.ImageDownload, apDownloadManager *adapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +0000193 pBaseFsm := oFsm.pAdaptFsm.pFsm
194 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
195 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
196 "device-id": oFsm.deviceID, "image-description": apImageDsc})
mpagenko15ff4a52021-03-02 10:09:20 +0000197 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenko80622a52021-02-09 16:53:23 +0000198 oFsm.pImageDsc = apImageDsc
199 oFsm.pDownloadManager = apDownloadManager
200
201 go func(aPBaseFsm *fsm.FSM) {
202 // let the upgrade FSm proceed to PreparinDL
203 _ = aPBaseFsm.Event(upgradeEvPrepareSwDownload)
204 }(pBaseFsm)
205 return nil
206 }
207 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
208 "device-id": oFsm.deviceID})
209 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
210}
211
212func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
213 logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
214 "device-id": oFsm.deviceID})
215
216 // start go routine for processing of LockState messages
217 go oFsm.processOmciUpgradeMessages(ctx)
218}
219
220func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
221 logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
222 "device-id": oFsm.deviceID})
223
224 fileLen, err := oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
225 if err != nil || fileLen > int64(cMaxUint32) {
226 logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
227 "device-id": oFsm.deviceID, "error": err, "length": fileLen})
228 pBaseFsm := oFsm.pAdaptFsm
229 // Can't call FSM Event directly, decoupling it
230 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000231 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000232 }(pBaseFsm)
233 return
234 }
235
236 oFsm.imageBuffer = make([]byte, fileLen)
237 oFsm.imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
238 if err != nil {
239 logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
240 "device-id": oFsm.deviceID, "error": err})
241 pBaseFsm := oFsm.pAdaptFsm
242 // Can't call FSM Event directly, decoupling it
243 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000244 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000245 }(pBaseFsm)
246 return
247 }
248
249 oFsm.noOfSections = uint32(fileLen / cOmciDownloadSectionSize)
250 if fileLen%cOmciDownloadSectionSize > 0 {
251 bufferPadding := make([]byte, cOmciDownloadSectionSize-uint32(fileLen%cOmciDownloadSectionSize))
252 //expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
253 oFsm.imageBuffer = append(oFsm.imageBuffer[:fileLen], bufferPadding...)
254 oFsm.noOfSections++
255 }
256 oFsm.origImageLength = uint32(fileLen)
257 oFsm.imageLength = uint32(len(oFsm.imageBuffer))
mpagenko80622a52021-02-09 16:53:23 +0000258
259 logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
260 "MeId": oFsm.inactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
261 "ImageSize": oFsm.imageLength, "original file size": fileLen})
262 //"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
Girish Gowdra0b235842021-03-09 13:06:46 -0800263 err = oFsm.pOmciCC.sendStartSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000264 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength)
265 if err != nil {
266 logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
267 "device-id": oFsm.deviceID, "error": err})
268 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
269 pBaseFsm := oFsm.pAdaptFsm
270 // Can't call FSM Event directly, decoupling it
271 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000272 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000273 }(pBaseFsm)
274 return
275 }
276}
277
278func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
279 logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
280 "device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
281
282 var windowAckRequest uint8 = 0
283 var bufferStartOffset uint32
284 var bufferEndOffset uint32
285 var downloadSection []byte
286 framePrint := false //default no printing of downloadSection frames
287 if oFsm.nextDownloadSectionsAbsolute == 0 {
288 //debug print of first section frame
289 framePrint = true
290 }
291
292 for {
293 bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * cOmciDownloadSectionSize
294 bufferEndOffset = bufferStartOffset + cOmciDownloadSectionSize - 1 //for representing cOmciDownloadSectionSizeLimit values
295 logger.Debugw(ctx, "DlSection values are", log.Fields{
296 "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
297 "DlSectionWindow": oFsm.nextDownloadSectionsWindow,
298 "startOffset": bufferStartOffset, "endOffset": bufferEndOffset})
299 if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
300 logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
301 "device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
302 "bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
303 //logical error -- reset the FSM
304 pBaseFsm := oFsm.pAdaptFsm
305 // Can't call FSM Event directly, decoupling it
306 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000307 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000308 }(pBaseFsm)
309 return
310 }
311 downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
312 if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
313 windowAckRequest = 1
314 logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
315 "device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
316 }
317 if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
318 windowAckRequest = 1
319 framePrint = true //debug print of last frame
mpagenko15ff4a52021-03-02 10:09:20 +0000320 oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
321 logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000322 "device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
323 }
Girish Gowdra0b235842021-03-09 13:06:46 -0800324 err := oFsm.pOmciCC.sendDownloadSection(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000325 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, framePrint)
326 if err != nil {
327 logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
mpagenko15ff4a52021-03-02 10:09:20 +0000328 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
mpagenko80622a52021-02-09 16:53:23 +0000329 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
330 pBaseFsm := oFsm.pAdaptFsm
331 // Can't call FSM Event directly, decoupling it
332 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000333 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000334 }(pBaseFsm)
335 return
336 }
mpagenko80622a52021-02-09 16:53:23 +0000337 oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
338 if windowAckRequest == 1 {
339 pBaseFsm := oFsm.pAdaptFsm
340 // Can't call FSM Event directly, decoupling it
341 go func(a_pAFsm *AdapterFsm) {
342 _ = a_pAFsm.pFsm.Event(upgradeEvWaitWindowAck) //state transition to upgradeStVerifyWindow
343 }(pBaseFsm)
344 return
345 }
346 framePrint = false //for the next Section frame (if wanted, can be enabled in logic before sendXXX())
347 oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
348 if oFsm.omciSectionInterleaveMilliseconds > 0 {
349 //ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
350 time.Sleep(oFsm.omciSectionInterleaveMilliseconds * time.Millisecond)
351 }
352 }
353}
354
355func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
356 logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
357 "for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
358}
359
360func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
361 imageCRC := crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //ITU I.363.5 crc
362 logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
363 "device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(imageCRC), 16), "delay": oFsm.delayEndSwDl})
364
365 if oFsm.delayEndSwDl {
366 //give the ONU some time for image evaluation (hoping it does not base that on first EndSwDl itself)
367 // should not be set in case this state is used for real download abort (not yet implemented)
368 time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
369 }
370
Girish Gowdra0b235842021-03-09 13:06:46 -0800371 err := oFsm.pOmciCC.sendEndSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000372 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.origImageLength, imageCRC)
373 if err != nil {
374 logger.Errorw(ctx, "EndSwDl abort: can't send section", log.Fields{
375 "device-id": oFsm.deviceID, "error": err})
376 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
377 pBaseFsm := oFsm.pAdaptFsm
378 // Can't call FSM Event directly, decoupling it
379 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000380 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000381 }(pBaseFsm)
382 return
383 }
384}
385
386func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
387 logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
388 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
389
Girish Gowdra0b235842021-03-09 13:06:46 -0800390 err := oFsm.pOmciCC.sendActivateSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000391 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID)
392 if err != nil {
393 logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
394 "device-id": oFsm.deviceID, "error": err})
395 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
396 pBaseFsm := oFsm.pAdaptFsm
397 // Can't call FSM Event directly, decoupling it
398 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000399 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000400 }(pBaseFsm)
401 return
402 }
403}
404
405func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
mpagenko15ff4a52021-03-02 10:09:20 +0000406 if activeImageID, err := oFsm.pOnuOmciDevice.GetActiveImageMeID(ctx); err == nil {
407 //TODO!!: as long as testing with BBSIM and BBSIM not support upgrade tests following check needs to be deactivated
408 imageFit := true //TODO!!: test workaround as long as BBSIM does not fully support upgrade
409 if imageFit || activeImageID == oFsm.inactiveImageMeID {
410 logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
411 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID}) //more efficient activeImageID with above check
Girish Gowdra0b235842021-03-09 13:06:46 -0800412 err := oFsm.pOmciCC.sendCommitSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko15ff4a52021-03-02 10:09:20 +0000413 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID) //more efficient activeImageID with above check
414 if err != nil {
415 logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
416 "device-id": oFsm.deviceID, "error": err})
417 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
418 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
419 pBaseFsm := oFsm.pAdaptFsm
420 // Can't call FSM Event directly, decoupling it
421 go func(a_pAFsm *AdapterFsm) {
422 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
423 }(pBaseFsm)
424 return
425 }
426 return
427 }
428 logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
429 "device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.inactiveImageMeID})
430 //TODO!!!: possibly send event information for aborted upgrade (not activated)??
431 pBaseFsm := oFsm.pAdaptFsm
432 // Can't call FSM Event directly, decoupling it
433 go func(a_pAFsm *AdapterFsm) {
434 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
435 }(pBaseFsm)
436 return
437 }
438 logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
439 "device-id": oFsm.deviceID})
440 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
441 pBaseFsm := oFsm.pAdaptFsm
442 // Can't call FSM Event directly, decoupling it
443 go func(a_pAFsm *AdapterFsm) {
444 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
445 }(pBaseFsm)
446}
447
448func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
449 logger.Infow(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000450 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
mpagenko15ff4a52021-03-02 10:09:20 +0000451 requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
452 meInstance := oFsm.pOmciCC.sendGetMe(log.WithSpanFromContext(context.TODO(), ctx),
Girish Gowdra0b235842021-03-09 13:06:46 -0800453 me.SoftwareImageClassID, oFsm.inactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false, oFsm.pAdaptFsm.commChan)
mpagenko15ff4a52021-03-02 10:09:20 +0000454 //accept also nil as (error) return value for writing to LastTx
455 // - this avoids misinterpretation of new received OMCI messages
456 oFsm.pLastTxMeInstance = meInstance
mpagenko80622a52021-02-09 16:53:23 +0000457}
458
459func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
460 logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
461
462 pConfigupgradeStateAFsm := oFsm.pAdaptFsm
463 if pConfigupgradeStateAFsm != nil {
464 // abort running message processing
465 fsmAbortMsg := Message{
466 Type: TestMsg,
467 Data: TestMessage{
468 TestMessageVal: AbortMessageProcessing,
469 },
470 }
471 pConfigupgradeStateAFsm.commChan <- fsmAbortMsg
472
473 //try to restart the FSM to 'disabled'
474 // Can't call FSM Event directly, decoupling it
475 go func(a_pAFsm *AdapterFsm) {
476 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
477 _ = a_pAFsm.pFsm.Event(upgradeEvRestart)
478 }
479 }(pConfigupgradeStateAFsm)
480 }
481}
482
483func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
484 logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
485 if oFsm.pDeviceHandler != nil {
486 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
487 go oFsm.pDeviceHandler.removeOnuUpgradeFsm(ctx)
488 }
489}
490
491func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
492 logger.Debugw(ctx, "Start OnuUpgradeFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
493loop:
494 for {
495 // case <-ctx.Done():
496 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
497 // break loop
498 message, ok := <-oFsm.pAdaptFsm.commChan
499 if !ok {
500 logger.Info(ctx, "OnuUpgradeFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
501 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
mpagenko15ff4a52021-03-02 10:09:20 +0000502 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000503 break loop
504 }
505 logger.Debugw(ctx, "OnuUpgradeFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
506
507 switch message.Type {
508 case TestMsg:
509 msg, _ := message.Data.(TestMessage)
510 if msg.TestMessageVal == AbortMessageProcessing {
511 logger.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
512 break loop
513 }
514 logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
515 case OMCI:
516 msg, _ := message.Data.(OmciMessage)
517 oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
518 default:
519 logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
520 "message.Type": message.Type})
521 }
522 }
523 logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
524}
525
526//nolint: gocyclo
527func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg OmciMessage) {
528 logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
529 "msgType": msg.OmciMsg.MessageType})
530
531 switch msg.OmciMsg.MessageType {
532 case omci.StartSoftwareDownloadResponseType:
533 {
534 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
535 if msgLayer == nil {
536 logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
537 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000538 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
539 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000540 return
541 }
542 msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
543 if !msgOk {
544 logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
545 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000546 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
547 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000548 return
549 }
550 logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
551 "device-id": oFsm.deviceID, "data-fields": msgObj})
552 if msgObj.Result != me.Success {
553 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
554 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
555 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000556 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
557 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000558 return
559 }
560 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
561 logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
562 if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
563 // also response WindowSize = 0 is a valid number for used Window size 1
564 logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
565 "acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
566 oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
567 }
568 oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
569 if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
570 oFsm.noOfWindows++
571 }
572 logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
573 "windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
574 "at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
575 oFsm.nextDownloadSectionsAbsolute = 0
576 oFsm.nextDownloadSectionsWindow = 0
577 oFsm.nextDownloadWindow = 0
578
579 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRxStartSwDownload)
580 return
581 }
582 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
583 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
584 // TODO!!!: possibly repeat the start request (once)?
mpagenko15ff4a52021-03-02 10:09:20 +0000585 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
586 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000587 return
588 } //StartSoftwareDownloadResponseType
589 case omci.DownloadSectionResponseType:
590 {
mpagenko80622a52021-02-09 16:53:23 +0000591 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
592 if msgLayer == nil {
593 logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
594 log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
mpagenko15ff4a52021-03-02 10:09:20 +0000595 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
596 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000597 return
598 }
599 msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
600 if !msgOk {
601 logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
602 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000603 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
604 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000605 return
606 }
607 logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
608 "device-id": oFsm.deviceID, "data-fields": msgObj})
609 if msgObj.Result != me.Success {
610 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
611 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko15ff4a52021-03-02 10:09:20 +0000612 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
613 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000614 return
615 }
616 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
617 sectionNumber := msgObj.SectionNumber
mpagenko15ff4a52021-03-02 10:09:20 +0000618 logger.Infow(ctx, "DlSectionResponse received", log.Fields{
619 "window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +0000620
mpagenko15ff4a52021-03-02 10:09:20 +0000621 oFsm.nextDownloadWindow++
622 if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
623 if sectionNumber != oFsm.omciDownloadWindowSizeLast {
624 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
625 log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
626 "expected section": oFsm.omciDownloadWindowSizeLast})
627 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
628 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
629 return
630 }
631 oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
632 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvEndSwDownload)
633 return
634 }
635 if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
636 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
637 log.Fields{"device-id": oFsm.deviceID, "window-section-limit": oFsm.omciDownloadWindowSizeLimit})
638 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
639 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
640 return
641 }
642 oFsm.nextDownloadSectionsWindow = 0
643 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvContinueNextWindow)
mpagenko80622a52021-02-09 16:53:23 +0000644 return
645 }
mpagenko80622a52021-02-09 16:53:23 +0000646 logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
647 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +0000648 // TODO!!!: possibly repeat the download (section) (once)?
649 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
650 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000651 return
mpagenko80622a52021-02-09 16:53:23 +0000652 } //DownloadSectionResponseType
653 case omci.EndSoftwareDownloadResponseType:
654 {
655 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
656 if msgLayer == nil {
657 logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
658 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000659 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
660 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000661 return
662 }
663 msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
664 if !msgOk {
665 logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
666 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000667 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
668 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000669 return
670 }
671 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
672 "device-id": oFsm.deviceID, "data-fields": msgObj})
673 if msgObj.Result != me.Success {
674 //TODO!!: Busy must be handled to give the ONU time for internal image storage, perhaps also processing error (CRC incorrect)
675 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - later: drive FSM to abort state ?",
676 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
677 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000678 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
679 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000680 return
681 }
682 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
683 logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
684 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRequestActivate)
685 return
686 }
687 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
688 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
689 // TODO!!!: possibly repeat the end request (once)? or verify ONU upgrade state?
mpagenko15ff4a52021-03-02 10:09:20 +0000690 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
691 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000692 return
693 } //EndSoftwareDownloadResponseType
694 case omci.ActivateSoftwareResponseType:
695 {
696 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
697 if msgLayer == nil {
698 logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
699 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000700 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
701 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000702 return
703 }
704 msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
705 if !msgOk {
706 logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
707 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000708 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
709 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000710 return
711 }
712 logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
713 "device-id": oFsm.deviceID, "data-fields": msgObj})
714 if msgObj.Result != me.Success {
715 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
716 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
717 // TODO!!!: error treatment?, perhaps in the end reset the FSM
mpagenko15ff4a52021-03-02 10:09:20 +0000718 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
719 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000720 return
721 }
722 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
723 logger.Debugw(ctx, "Expected ActivateSwResponse received", log.Fields{"device-id": oFsm.deviceID})
724 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
mpagenko15ff4a52021-03-02 10:09:20 +0000725 //TODO: as long as BBSIM does not fully support upgrade: simulate restart by calling the BBSIM (ONU) reboot
726 go oFsm.pDeviceHandler.rebootDevice(ctx, false, oFsm.pDeviceHandler.device)
mpagenko80622a52021-02-09 16:53:23 +0000727 return
728 }
729 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
730 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +0000731 // TODO!!!: error treatment?
732 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
733 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000734 return
735 } //ActivateSoftwareResponseType
mpagenko15ff4a52021-03-02 10:09:20 +0000736 case omci.CommitSoftwareResponseType:
737 {
738 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
739 if msgLayer == nil {
740 logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
741 log.Fields{"device-id": oFsm.deviceID})
742 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
743 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
744 return
745 }
746 msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
747 if !msgOk {
748 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
749 log.Fields{"device-id": oFsm.deviceID})
750 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
751 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
752 return
753 }
754 // TODO!!: not yet implemented by omci-lib:
755 /*if msgObj.Result != me.Success {
756 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
757 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
758 // TODO!!!: error treatment?, perhaps in the end reset the FSM
759 return
760 }*/
761 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
762 logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
763 //verifying committed image
764 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvCheckCommitted)
765 return
766 }
767 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse wrong ME instance: abort",
768 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
769 // TODO!!!: error treatment?
770 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
771 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
772 return
773 } //CommitSoftwareResponseType
774 case omci.GetResponseType:
775 {
776 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
777 if msgLayer == nil {
778 logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
779 log.Fields{"device-id": oFsm.deviceID})
780 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
781 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
782 return
783 }
784 msgObj, msgOk := msgLayer.(*omci.GetResponse)
785 if !msgOk {
786 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
787 log.Fields{"device-id": oFsm.deviceID})
788 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
789 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
790 return
791 }
792 logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
793 "device-id": oFsm.deviceID, "data-fields": msgObj})
794 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
795 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
796 if msgObj.Result != me.Success {
797 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
798 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
799 // TODO!!!: error treatment?, perhaps in the end reset the FSM
800 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
801 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
802 return
803 }
804 } else {
805 logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
806 log.Fields{"device-id": oFsm.deviceID})
807 return
808 }
809
810 meAttributes := msgObj.Attributes
811 imageIsCommitted := meAttributes["IsCommitted"].(uint8)
812 imageIsActive := meAttributes["IsActive"].(uint8)
813 imageVersion := trimStringFromInterface(meAttributes["Version"])
814 logger.Infow(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
815 log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
816 "version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
817
818 //a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
819 // indicated in the download image version string (version must be part of the image content itself)
820 // so checking that might be quite unreliable
821 if msgObj.EntityInstance == oFsm.inactiveImageMeID && imageIsActive == swIsActive &&
822 imageIsCommitted == swIsCommitted {
823 logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
824 //releasing the upgrade FSM
825 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvReset)
826 return
827 }
828 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
829 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
830 // TODO!!!: error treatment?
831 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
832 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
833 return
834 } //GetResponseType
mpagenko80622a52021-02-09 16:53:23 +0000835 default:
836 {
837 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
838 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
839 return
840 }
841 }
842}
843
844/*
845func (oFsm *OnuUpgradeFsm) waitforOmciResponse(ctx context.Context) error {
846 select {
847 // maybe be also some outside cancel (but no context modeled for the moment ...)
848 // case <-ctx.Done():
849 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
850 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
851 logger.Warnw(ctx, "OnuUpgradeFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
852 return fmt.Errorf("OnuUpgradeFsm multi entity timeout %s", oFsm.deviceID)
853 case success := <-oFsm.omciMIdsResponseReceived:
854 if success {
855 logger.Debug(ctx, "OnuUpgradeFsm multi entity response received")
856 return nil
857 }
858 // should not happen so far
859 logger.Warnw(ctx, "OnuUpgradeFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
860 return fmt.Errorf("OnuUpgradeFsm multi entity responseError %s", oFsm.deviceID)
861 }
862}
863*/