blob: fd7df97403c36c8ae2aa31f57642c1bdb7a75021 [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
mpagenko02cf1b22021-03-12 17:30:30 +0000110 useSoftReboot bool
mpagenko80622a52021-02-09 16:53:23 +0000111}
112
113//NewOnuUpgradeFsm is the 'constructor' for the state machine to config the PON ANI ports
114// of ONU UNI ports via OMCI
115func NewOnuUpgradeFsm(ctx context.Context, apDeviceHandler *deviceHandler,
mpagenko15ff4a52021-03-02 10:09:20 +0000116 apDevEntry *OnuDeviceEntry, apOnuDB *onuDeviceDB,
mpagenko80622a52021-02-09 16:53:23 +0000117 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message) *OnuUpgradeFsm {
118 instFsm := &OnuUpgradeFsm{
119 pDeviceHandler: apDeviceHandler,
120 deviceID: apDeviceHandler.deviceID,
mpagenko15ff4a52021-03-02 10:09:20 +0000121 pOnuOmciDevice: apDevEntry,
122 pOmciCC: apDevEntry.PDevOmciCC,
mpagenko80622a52021-02-09 16:53:23 +0000123 pOnuDB: apOnuDB,
124 requestEvent: aRequestEvent,
125 omciDownloadWindowSizeLimit: cOmciDownloadWindowSizeLimit,
126 omciSectionInterleaveMilliseconds: cOmciSectionInterleaveMilliseconds,
127 }
128
129 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
130 if instFsm.pAdaptFsm == nil {
131 logger.Errorw(ctx, "OnuUpgradeFsm's AdapterFsm could not be instantiated!!", log.Fields{
132 "device-id": instFsm.deviceID})
133 return nil
134 }
135 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
136 upgradeStDisabled,
137 fsm.Events{
138 {Name: upgradeEvStart, Src: []string{upgradeStDisabled}, Dst: upgradeStStarting},
139 {Name: upgradeEvPrepareSwDownload, Src: []string{upgradeStStarting}, Dst: upgradeStPreparingDL},
140 {Name: upgradeEvRxStartSwDownload, Src: []string{upgradeStPreparingDL}, Dst: upgradeStDLSection},
141 {Name: upgradeEvWaitWindowAck, Src: []string{upgradeStDLSection}, Dst: upgradeStVerifyWindow},
142 {Name: upgradeEvContinueNextWindow, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStDLSection},
143 {Name: upgradeEvEndSwDownload, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStFinalizeDL},
144 {Name: upgradeEvRequestActivate, Src: []string{upgradeStFinalizeDL}, Dst: upgradeStRequestingActivate},
145 {Name: upgradeEvWaitForCommit, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStWaitForCommit},
146 {Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStWaitForCommit},
147 Dst: upgradeStCommitSw},
mpagenko15ff4a52021-03-02 10:09:20 +0000148 {Name: upgradeEvCheckCommitted, Src: []string{upgradeStCommitSw}, Dst: upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000149
150 /*
151 {Name: upgradeEvTimeoutSimple, Src: []string{
152 upgradeStCreatingDot1PMapper, upgradeStCreatingMBPCD, upgradeStSettingTconts, upgradeStSettingDot1PMapper}, Dst: upgradeStStarting},
153 {Name: upgradeEvTimeoutMids, Src: []string{
154 upgradeStCreatingGemNCTPs, upgradeStCreatingGemIWs, upgradeStSettingPQs}, Dst: upgradeStStarting},
155 */
156 // exceptional treatments
157 {Name: upgradeEvReset, Src: []string{upgradeStStarting, upgradeStPreparingDL, upgradeStDLSection,
158 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStRequestingActivate,
mpagenko15ff4a52021-03-02 10:09:20 +0000159 upgradeStCommitSw, upgradeStCheckCommitted}, //upgradeStWaitForCommit is not reset (later perhaps also not upgradeStWaitActivate)
mpagenko80622a52021-02-09 16:53:23 +0000160 Dst: upgradeStResetting},
161 {Name: upgradeEvAbort, Src: []string{upgradeStStarting, upgradeStPreparingDL, upgradeStDLSection,
162 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStRequestingActivate,
mpagenko15ff4a52021-03-02 10:09:20 +0000163 upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000164 Dst: upgradeStResetting},
165 {Name: upgradeEvRestart, Src: []string{upgradeStResetting}, Dst: upgradeStDisabled},
166 },
167 fsm.Callbacks{
168 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
169 "enter_" + upgradeStStarting: func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
170 "enter_" + upgradeStPreparingDL: func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
171 "enter_" + upgradeStDLSection: func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
172 "enter_" + upgradeStVerifyWindow: func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
173 "enter_" + upgradeStFinalizeDL: func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
174 "enter_" + upgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
175 "enter_" + upgradeStCommitSw: func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
mpagenko15ff4a52021-03-02 10:09:20 +0000176 "enter_" + upgradeStCheckCommitted: func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000177 "enter_" + upgradeStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
178 "enter_" + upgradeStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
179 },
180 )
181 if instFsm.pAdaptFsm.pFsm == nil {
182 logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
183 "device-id": instFsm.deviceID})
184 return nil
185 }
186
187 logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
188 return instFsm
189}
190
191//SetDownloadParams configures the needed parameters for a specific download to the ONU
mpagenko15ff4a52021-03-02 10:09:20 +0000192func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
193 apImageDsc *voltha.ImageDownload, apDownloadManager *adapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +0000194 pBaseFsm := oFsm.pAdaptFsm.pFsm
195 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
196 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
197 "device-id": oFsm.deviceID, "image-description": apImageDsc})
mpagenko15ff4a52021-03-02 10:09:20 +0000198 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenko80622a52021-02-09 16:53:23 +0000199 oFsm.pImageDsc = apImageDsc
mpagenko02cf1b22021-03-12 17:30:30 +0000200 //path overwrite for internal test file usage
201 oFsm.useSoftReboot = false
202 if apImageDsc.LocalDir == "/intern" {
203 oFsm.pImageDsc.LocalDir = "/tmp"
204 } else if apImageDsc.LocalDir == "/reboot" {
205 oFsm.useSoftReboot = true
206 oFsm.pImageDsc.LocalDir = "/tmp"
207 }
mpagenko80622a52021-02-09 16:53:23 +0000208 oFsm.pDownloadManager = apDownloadManager
209
210 go func(aPBaseFsm *fsm.FSM) {
211 // let the upgrade FSm proceed to PreparinDL
212 _ = aPBaseFsm.Event(upgradeEvPrepareSwDownload)
213 }(pBaseFsm)
214 return nil
215 }
216 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
217 "device-id": oFsm.deviceID})
218 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
219}
220
221func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
222 logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
223 "device-id": oFsm.deviceID})
224
225 // start go routine for processing of LockState messages
226 go oFsm.processOmciUpgradeMessages(ctx)
227}
228
229func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
230 logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
231 "device-id": oFsm.deviceID})
232
233 fileLen, err := oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
234 if err != nil || fileLen > int64(cMaxUint32) {
235 logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
236 "device-id": oFsm.deviceID, "error": err, "length": fileLen})
237 pBaseFsm := oFsm.pAdaptFsm
238 // Can't call FSM Event directly, decoupling it
239 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000240 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000241 }(pBaseFsm)
242 return
243 }
244
245 oFsm.imageBuffer = make([]byte, fileLen)
246 oFsm.imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
247 if err != nil {
248 logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
249 "device-id": oFsm.deviceID, "error": err})
250 pBaseFsm := oFsm.pAdaptFsm
251 // Can't call FSM Event directly, decoupling it
252 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000253 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000254 }(pBaseFsm)
255 return
256 }
257
258 oFsm.noOfSections = uint32(fileLen / cOmciDownloadSectionSize)
259 if fileLen%cOmciDownloadSectionSize > 0 {
260 bufferPadding := make([]byte, cOmciDownloadSectionSize-uint32(fileLen%cOmciDownloadSectionSize))
261 //expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
262 oFsm.imageBuffer = append(oFsm.imageBuffer[:fileLen], bufferPadding...)
263 oFsm.noOfSections++
264 }
265 oFsm.origImageLength = uint32(fileLen)
266 oFsm.imageLength = uint32(len(oFsm.imageBuffer))
mpagenko80622a52021-02-09 16:53:23 +0000267
268 logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
269 "MeId": oFsm.inactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
270 "ImageSize": oFsm.imageLength, "original file size": fileLen})
271 //"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
Girish Gowdra0b235842021-03-09 13:06:46 -0800272 err = oFsm.pOmciCC.sendStartSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000273 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength)
274 if err != nil {
275 logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
276 "device-id": oFsm.deviceID, "error": err})
277 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
278 pBaseFsm := oFsm.pAdaptFsm
279 // Can't call FSM Event directly, decoupling it
280 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000281 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000282 }(pBaseFsm)
283 return
284 }
285}
286
287func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
288 logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
289 "device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
290
291 var windowAckRequest uint8 = 0
292 var bufferStartOffset uint32
293 var bufferEndOffset uint32
294 var downloadSection []byte
295 framePrint := false //default no printing of downloadSection frames
296 if oFsm.nextDownloadSectionsAbsolute == 0 {
297 //debug print of first section frame
298 framePrint = true
299 }
300
301 for {
302 bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * cOmciDownloadSectionSize
303 bufferEndOffset = bufferStartOffset + cOmciDownloadSectionSize - 1 //for representing cOmciDownloadSectionSizeLimit values
304 logger.Debugw(ctx, "DlSection values are", log.Fields{
305 "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
306 "DlSectionWindow": oFsm.nextDownloadSectionsWindow,
307 "startOffset": bufferStartOffset, "endOffset": bufferEndOffset})
308 if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
309 logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
310 "device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
311 "bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
312 //logical error -- reset the FSM
313 pBaseFsm := oFsm.pAdaptFsm
314 // Can't call FSM Event directly, decoupling it
315 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000316 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000317 }(pBaseFsm)
318 return
319 }
320 downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
321 if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
322 windowAckRequest = 1
323 logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
324 "device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
325 }
326 if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
327 windowAckRequest = 1
328 framePrint = true //debug print of last frame
mpagenko15ff4a52021-03-02 10:09:20 +0000329 oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
330 logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000331 "device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
332 }
Girish Gowdra0b235842021-03-09 13:06:46 -0800333 err := oFsm.pOmciCC.sendDownloadSection(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000334 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, framePrint)
335 if err != nil {
336 logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
mpagenko15ff4a52021-03-02 10:09:20 +0000337 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
mpagenko80622a52021-02-09 16:53:23 +0000338 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
339 pBaseFsm := oFsm.pAdaptFsm
340 // Can't call FSM Event directly, decoupling it
341 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000342 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000343 }(pBaseFsm)
344 return
345 }
mpagenko80622a52021-02-09 16:53:23 +0000346 oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
347 if windowAckRequest == 1 {
348 pBaseFsm := oFsm.pAdaptFsm
349 // Can't call FSM Event directly, decoupling it
350 go func(a_pAFsm *AdapterFsm) {
351 _ = a_pAFsm.pFsm.Event(upgradeEvWaitWindowAck) //state transition to upgradeStVerifyWindow
352 }(pBaseFsm)
353 return
354 }
355 framePrint = false //for the next Section frame (if wanted, can be enabled in logic before sendXXX())
356 oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
357 if oFsm.omciSectionInterleaveMilliseconds > 0 {
358 //ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
359 time.Sleep(oFsm.omciSectionInterleaveMilliseconds * time.Millisecond)
360 }
361 }
362}
363
364func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
365 logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
366 "for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
367}
368
369func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
370 imageCRC := crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //ITU I.363.5 crc
371 logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
372 "device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(imageCRC), 16), "delay": oFsm.delayEndSwDl})
373
374 if oFsm.delayEndSwDl {
375 //give the ONU some time for image evaluation (hoping it does not base that on first EndSwDl itself)
376 // should not be set in case this state is used for real download abort (not yet implemented)
377 time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
378 }
379
Girish Gowdra0b235842021-03-09 13:06:46 -0800380 err := oFsm.pOmciCC.sendEndSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000381 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.origImageLength, imageCRC)
382 if err != nil {
383 logger.Errorw(ctx, "EndSwDl abort: can't send section", log.Fields{
384 "device-id": oFsm.deviceID, "error": err})
385 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
386 pBaseFsm := oFsm.pAdaptFsm
387 // Can't call FSM Event directly, decoupling it
388 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000389 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000390 }(pBaseFsm)
391 return
392 }
393}
394
395func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
396 logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
397 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
398
Girish Gowdra0b235842021-03-09 13:06:46 -0800399 err := oFsm.pOmciCC.sendActivateSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000400 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID)
401 if err != nil {
402 logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
403 "device-id": oFsm.deviceID, "error": err})
404 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
405 pBaseFsm := oFsm.pAdaptFsm
406 // Can't call FSM Event directly, decoupling it
407 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000408 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000409 }(pBaseFsm)
410 return
411 }
412}
413
414func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
mpagenko15ff4a52021-03-02 10:09:20 +0000415 if activeImageID, err := oFsm.pOnuOmciDevice.GetActiveImageMeID(ctx); err == nil {
416 //TODO!!: as long as testing with BBSIM and BBSIM not support upgrade tests following check needs to be deactivated
417 imageFit := true //TODO!!: test workaround as long as BBSIM does not fully support upgrade
418 if imageFit || activeImageID == oFsm.inactiveImageMeID {
419 logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
420 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID}) //more efficient activeImageID with above check
Girish Gowdra0b235842021-03-09 13:06:46 -0800421 err := oFsm.pOmciCC.sendCommitSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko15ff4a52021-03-02 10:09:20 +0000422 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID) //more efficient activeImageID with above check
423 if err != nil {
424 logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
425 "device-id": oFsm.deviceID, "error": err})
426 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
427 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
428 pBaseFsm := oFsm.pAdaptFsm
429 // Can't call FSM Event directly, decoupling it
430 go func(a_pAFsm *AdapterFsm) {
431 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
432 }(pBaseFsm)
433 return
434 }
435 return
436 }
437 logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
438 "device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.inactiveImageMeID})
439 //TODO!!!: possibly send event information for aborted upgrade (not activated)??
440 pBaseFsm := oFsm.pAdaptFsm
441 // Can't call FSM Event directly, decoupling it
442 go func(a_pAFsm *AdapterFsm) {
443 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
444 }(pBaseFsm)
445 return
446 }
447 logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
448 "device-id": oFsm.deviceID})
449 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
450 pBaseFsm := oFsm.pAdaptFsm
451 // Can't call FSM Event directly, decoupling it
452 go func(a_pAFsm *AdapterFsm) {
453 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
454 }(pBaseFsm)
455}
456
457func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
458 logger.Infow(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000459 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
mpagenko15ff4a52021-03-02 10:09:20 +0000460 requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
461 meInstance := oFsm.pOmciCC.sendGetMe(log.WithSpanFromContext(context.TODO(), ctx),
Girish Gowdra0b235842021-03-09 13:06:46 -0800462 me.SoftwareImageClassID, oFsm.inactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false, oFsm.pAdaptFsm.commChan)
mpagenko15ff4a52021-03-02 10:09:20 +0000463 //accept also nil as (error) return value for writing to LastTx
464 // - this avoids misinterpretation of new received OMCI messages
465 oFsm.pLastTxMeInstance = meInstance
mpagenko80622a52021-02-09 16:53:23 +0000466}
467
468func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
469 logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
470
471 pConfigupgradeStateAFsm := oFsm.pAdaptFsm
472 if pConfigupgradeStateAFsm != nil {
473 // abort running message processing
474 fsmAbortMsg := Message{
475 Type: TestMsg,
476 Data: TestMessage{
477 TestMessageVal: AbortMessageProcessing,
478 },
479 }
480 pConfigupgradeStateAFsm.commChan <- fsmAbortMsg
481
482 //try to restart the FSM to 'disabled'
483 // Can't call FSM Event directly, decoupling it
484 go func(a_pAFsm *AdapterFsm) {
485 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
486 _ = a_pAFsm.pFsm.Event(upgradeEvRestart)
487 }
488 }(pConfigupgradeStateAFsm)
489 }
490}
491
492func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
493 logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
494 if oFsm.pDeviceHandler != nil {
495 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
496 go oFsm.pDeviceHandler.removeOnuUpgradeFsm(ctx)
497 }
498}
499
500func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
501 logger.Debugw(ctx, "Start OnuUpgradeFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
502loop:
503 for {
504 // case <-ctx.Done():
505 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
506 // break loop
507 message, ok := <-oFsm.pAdaptFsm.commChan
508 if !ok {
509 logger.Info(ctx, "OnuUpgradeFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
510 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
mpagenko15ff4a52021-03-02 10:09:20 +0000511 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000512 break loop
513 }
514 logger.Debugw(ctx, "OnuUpgradeFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
515
516 switch message.Type {
517 case TestMsg:
518 msg, _ := message.Data.(TestMessage)
519 if msg.TestMessageVal == AbortMessageProcessing {
520 logger.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
521 break loop
522 }
523 logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
524 case OMCI:
525 msg, _ := message.Data.(OmciMessage)
526 oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
527 default:
528 logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
529 "message.Type": message.Type})
530 }
531 }
532 logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
533}
534
535//nolint: gocyclo
536func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg OmciMessage) {
537 logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
538 "msgType": msg.OmciMsg.MessageType})
539
540 switch msg.OmciMsg.MessageType {
541 case omci.StartSoftwareDownloadResponseType:
542 {
543 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
544 if msgLayer == nil {
545 logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
546 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000547 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
548 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000549 return
550 }
551 msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
552 if !msgOk {
553 logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
554 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000555 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
556 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000557 return
558 }
559 logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
560 "device-id": oFsm.deviceID, "data-fields": msgObj})
561 if msgObj.Result != me.Success {
562 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
563 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
564 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000565 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
566 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000567 return
568 }
569 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
570 logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
571 if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
572 // also response WindowSize = 0 is a valid number for used Window size 1
573 logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
574 "acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
575 oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
576 }
577 oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
578 if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
579 oFsm.noOfWindows++
580 }
581 logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
582 "windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
583 "at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
584 oFsm.nextDownloadSectionsAbsolute = 0
585 oFsm.nextDownloadSectionsWindow = 0
586 oFsm.nextDownloadWindow = 0
587
588 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRxStartSwDownload)
589 return
590 }
591 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
592 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
593 // TODO!!!: possibly repeat the start request (once)?
mpagenko15ff4a52021-03-02 10:09:20 +0000594 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
595 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000596 return
597 } //StartSoftwareDownloadResponseType
598 case omci.DownloadSectionResponseType:
599 {
mpagenko80622a52021-02-09 16:53:23 +0000600 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
601 if msgLayer == nil {
602 logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
603 log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
mpagenko15ff4a52021-03-02 10:09:20 +0000604 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
605 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000606 return
607 }
608 msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
609 if !msgOk {
610 logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
611 log.Fields{"device-id": oFsm.deviceID})
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 logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
617 "device-id": oFsm.deviceID, "data-fields": msgObj})
618 if msgObj.Result != me.Success {
619 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
620 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko15ff4a52021-03-02 10:09:20 +0000621 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
622 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000623 return
624 }
625 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
626 sectionNumber := msgObj.SectionNumber
mpagenko15ff4a52021-03-02 10:09:20 +0000627 logger.Infow(ctx, "DlSectionResponse received", log.Fields{
628 "window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +0000629
mpagenko15ff4a52021-03-02 10:09:20 +0000630 oFsm.nextDownloadWindow++
631 if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
632 if sectionNumber != oFsm.omciDownloadWindowSizeLast {
mpagenko02cf1b22021-03-12 17:30:30 +0000633 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error last window - later: repeat window once?", //TODO!!!
mpagenko15ff4a52021-03-02 10:09:20 +0000634 log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
635 "expected section": oFsm.omciDownloadWindowSizeLast})
636 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
637 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
638 return
639 }
640 oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
641 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvEndSwDownload)
642 return
643 }
644 if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
645 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
mpagenko02cf1b22021-03-12 17:30:30 +0000646 log.Fields{"device-id": oFsm.deviceID, "actual-section": sectionNumber,
647 "expected section": oFsm.omciDownloadWindowSizeLimit})
mpagenko15ff4a52021-03-02 10:09:20 +0000648 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
649 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
650 return
651 }
652 oFsm.nextDownloadSectionsWindow = 0
653 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvContinueNextWindow)
mpagenko80622a52021-02-09 16:53:23 +0000654 return
655 }
mpagenko80622a52021-02-09 16:53:23 +0000656 logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
657 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +0000658 // TODO!!!: possibly repeat the download (section) (once)?
659 //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
mpagenko80622a52021-02-09 16:53:23 +0000662 } //DownloadSectionResponseType
663 case omci.EndSoftwareDownloadResponseType:
664 {
665 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
666 if msgLayer == nil {
667 logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
668 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000669 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
670 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000671 return
672 }
673 msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
674 if !msgOk {
675 logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
676 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000677 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
678 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000679 return
680 }
681 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
682 "device-id": oFsm.deviceID, "data-fields": msgObj})
683 if msgObj.Result != me.Success {
684 //TODO!!: Busy must be handled to give the ONU time for internal image storage, perhaps also processing error (CRC incorrect)
685 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - later: drive FSM to abort state ?",
686 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
687 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000688 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
689 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000690 return
691 }
692 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
693 logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
694 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRequestActivate)
695 return
696 }
697 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
698 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
699 // TODO!!!: possibly repeat the end request (once)? or verify ONU upgrade state?
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 } //EndSoftwareDownloadResponseType
704 case omci.ActivateSoftwareResponseType:
705 {
706 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
707 if msgLayer == nil {
708 logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
709 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000710 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
711 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000712 return
713 }
714 msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
715 if !msgOk {
716 logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
717 log.Fields{"device-id": oFsm.deviceID})
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 logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
723 "device-id": oFsm.deviceID, "data-fields": msgObj})
724 if msgObj.Result != me.Success {
725 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
726 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
727 // TODO!!!: error treatment?, perhaps in the end reset the FSM
mpagenko15ff4a52021-03-02 10:09:20 +0000728 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
729 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000730 return
731 }
732 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenko02cf1b22021-03-12 17:30:30 +0000733 logger.Infow(ctx, "Expected ActivateSwResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +0000734 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
mpagenko02cf1b22021-03-12 17:30:30 +0000735 if oFsm.useSoftReboot {
736 //TODO: as long as BBSIM does not fully support upgrade: simulate restart by calling the BBSIM (ONU) reboot
737 go oFsm.pDeviceHandler.rebootDevice(ctx, false, oFsm.pDeviceHandler.device)
738 }
mpagenko80622a52021-02-09 16:53:23 +0000739 return
740 }
741 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
742 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +0000743 // TODO!!!: error treatment?
744 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
745 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000746 return
747 } //ActivateSoftwareResponseType
mpagenko15ff4a52021-03-02 10:09:20 +0000748 case omci.CommitSoftwareResponseType:
749 {
750 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
751 if msgLayer == nil {
752 logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
753 log.Fields{"device-id": oFsm.deviceID})
754 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
755 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
756 return
757 }
758 msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
759 if !msgOk {
760 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
761 log.Fields{"device-id": oFsm.deviceID})
762 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
763 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
764 return
765 }
mpagenkobf67a092021-03-17 09:52:28 +0000766 if msgObj.Result != me.Success {
mpagenko15ff4a52021-03-02 10:09:20 +0000767 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
768 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
769 // TODO!!!: error treatment?, perhaps in the end reset the FSM
770 return
mpagenkobf67a092021-03-17 09:52:28 +0000771 }
mpagenko15ff4a52021-03-02 10:09:20 +0000772 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
773 logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
774 //verifying committed image
775 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvCheckCommitted)
776 return
777 }
778 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse wrong ME instance: abort",
779 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
780 // TODO!!!: error treatment?
781 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
782 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
783 return
784 } //CommitSoftwareResponseType
785 case omci.GetResponseType:
786 {
787 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
788 if msgLayer == nil {
789 logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
790 log.Fields{"device-id": oFsm.deviceID})
791 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
792 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
793 return
794 }
795 msgObj, msgOk := msgLayer.(*omci.GetResponse)
796 if !msgOk {
797 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
798 log.Fields{"device-id": oFsm.deviceID})
799 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
800 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
801 return
802 }
803 logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
804 "device-id": oFsm.deviceID, "data-fields": msgObj})
805 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
806 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
807 if msgObj.Result != me.Success {
808 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
809 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
810 // TODO!!!: error treatment?, perhaps in the end reset the FSM
811 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
812 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
813 return
814 }
815 } else {
816 logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
817 log.Fields{"device-id": oFsm.deviceID})
818 return
819 }
820
821 meAttributes := msgObj.Attributes
822 imageIsCommitted := meAttributes["IsCommitted"].(uint8)
823 imageIsActive := meAttributes["IsActive"].(uint8)
824 imageVersion := trimStringFromInterface(meAttributes["Version"])
mpagenko02cf1b22021-03-12 17:30:30 +0000825 logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
mpagenko15ff4a52021-03-02 10:09:20 +0000826 log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
827 "version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
828
829 //a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
830 // indicated in the download image version string (version must be part of the image content itself)
831 // so checking that might be quite unreliable
mpagenko02cf1b22021-03-12 17:30:30 +0000832 // TODO!! workaround for still not valid bbsim load indications (re-use SoftReboot flag for simplicity)
833 if oFsm.useSoftReboot || (msgObj.EntityInstance == oFsm.inactiveImageMeID && imageIsActive == swIsActive &&
834 imageIsCommitted == swIsCommitted) {
mpagenko15ff4a52021-03-02 10:09:20 +0000835 logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
836 //releasing the upgrade FSM
837 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvReset)
838 return
839 }
840 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
841 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
842 // TODO!!!: error treatment?
843 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
844 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
845 return
846 } //GetResponseType
mpagenko80622a52021-02-09 16:53:23 +0000847 default:
848 {
849 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
850 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
851 return
852 }
853 }
854}
855
856/*
857func (oFsm *OnuUpgradeFsm) waitforOmciResponse(ctx context.Context) error {
858 select {
859 // maybe be also some outside cancel (but no context modeled for the moment ...)
860 // case <-ctx.Done():
861 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
862 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
863 logger.Warnw(ctx, "OnuUpgradeFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
864 return fmt.Errorf("OnuUpgradeFsm multi entity timeout %s", oFsm.deviceID)
865 case success := <-oFsm.omciMIdsResponseReceived:
866 if success {
867 logger.Debug(ctx, "OnuUpgradeFsm multi entity response received")
868 return nil
869 }
870 // should not happen so far
871 logger.Warnw(ctx, "OnuUpgradeFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
872 return fmt.Errorf("OnuUpgradeFsm multi entity responseError %s", oFsm.deviceID)
873 }
874}
875*/