blob: 5c54762302192551b4e0180b13914f3af96c2939 [file] [log] [blame]
mpagenko80622a52021-02-09 16:53:23 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
mpagenko80622a52021-02-09 16:53:23 +00003 *
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
Joey Armstrong89c812c2024-01-12 19:00:20 -050017// Package swupg provides the utilities for onu sw upgrade
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package swupg
mpagenko80622a52021-02-09 16:53:23 +000019
20import (
21 "context"
mpagenkoc26d4c02021-05-06 14:27:57 +000022 "encoding/binary"
mpagenko80622a52021-02-09 16:53:23 +000023 "fmt"
24 "strconv"
mpagenkoc26d4c02021-05-06 14:27:57 +000025 "sync"
mpagenko80622a52021-02-09 16:53:23 +000026 "time"
27
28 "github.com/boguslaw-wojcik/crc32a"
29 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000030 "github.com/opencord/omci-lib-go/v2"
31 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040032 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000033 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
34 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
kesavand011d5162021-11-25 19:21:06 +053035 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040036 "github.com/opencord/voltha-protos/v5/go/voltha"
mpagenko80622a52021-02-09 16:53:23 +000037)
38
39const cMaxUint32 = ^uint32(0)
40
41const (
42 // internal predefined values - some off them should later be configurable (perhaps with theses as defaults)
Holger Hildebrandt5458d892022-05-31 09:52:06 +000043 cOmciDownloadSectionSizeBaseLine = 31 //in bytes
44 cOmciDownloadWindowSizeLimitBaseLine = 31 //in sections for window offset (windowSize(32)-1)
45 cOmciDownloadSectionSizeExtLine = 1965 //in bytes
46 cOmciDownloadWindowSizeLimitExtLine = 7 //in sections for window offset (windowSize(8)-1)
mpagenko80622a52021-02-09 16:53:23 +000047 //cOmciDownloadWindowRetryMax = 2 // max attempts for a specific window
mpagenkoc26d4c02021-05-06 14:27:57 +000048 cOmciSectionInterleaveMilliseconds = 0 //DownloadSection interleave time in milliseconds (0 for no delay)
49 cOmciEndSwDlDelaySeconds = 1 //End Software Download delay after last section (may be also configurable?)
50 cWaitCountEndSwDl = 6 //maximum number of EndSwDl requests
51 cWaitDelayEndSwDlSeconds = 10 //duration, how long is waited before next request on EndSwDl
mpagenko80622a52021-02-09 16:53:23 +000052 //cOmciDownloadCompleteTimeout = 5400 //in s for the complete timeout (may be better scale to image size/ noOfWindows)
53)
54
mpagenko45586762021-10-01 08:30:22 +000055// tEndSwDlResponseResult - Response result from EndSwDownload as used in channel indication
56type tUpgradePhase uint8
57
58const (
59 // undefined phase
60 cUpgradeUndefined tUpgradePhase = iota
61 // downloading image
62 cUpgradeDownloading
63 // image downloaded
64 cUpgradeDownloaded
65 // activating image
66 cUpgradeActivating
67 // image activated
68 cUpgradeActivated
69 // committing image
70 cUpgradeCommitting
71 // image committed
72 cUpgradeCommitted
73)
74
75// tEndSwDlResponseResult - Response result from EndSwDownload as used in channel indication
76type tEndSwDlResponseResult uint8
77
78const (
79 // response success
80 cEndSwDlResponseSuccess tEndSwDlResponseResult = iota
81 // response busy (repeat)
82 cEndSwDlResponseBusy
83 // response error or abort waiting for response
84 cEndSwDlResponseAbort
85)
86
87// upgrade FSM related events
mpagenko80622a52021-02-09 16:53:23 +000088const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000089 UpgradeEvStart = "UpgradeEvStart"
90 UpgradeEvDisable = "UpgradeEvDisable"
91 UpgradeEvAdapterDownload = "UpgradeEvAdapterDownload"
92 UpgradeEvPrepareSwDownload = "UpgradeEvPrepareSwDownload"
93 UpgradeEvRxStartSwDownload = "UpgradeEvRxStartSwDownload"
94 UpgradeEvWaitWindowAck = "UpgradeEvWaitWindowAck"
95 UpgradeEvContinueNextWindow = "UpgradeEvContinueNextWindow"
96 UpgradeEvEndSwDownload = "UpgradeEvEndSwDownload"
97 UpgradeEvWaitEndDownload = "UpgradeEvWaitEndDownload"
98 UpgradeEvContinueFinalize = "UpgradeEvContinueFinalize"
99 UpgradeEvCheckImageName = "UpgradeEvCheckImageName"
100 UpgradeEvWaitForActivate = "UpgradeEvWaitForActivate"
101 UpgradeEvRequestActivate = "UpgradeEvRequestActivate"
102 UpgradeEvActivationDone = "UpgradeEvActivationDone"
103 UpgradeEvWaitForCommit = "UpgradeEvWaitForCommit"
104 UpgradeEvCommitSw = "UpgradeEvCommitSw"
105 UpgradeEvCheckCommitted = "UpgradeEvCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +0000106
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000107 //UpgradeEvTimeoutSimple = "UpgradeEvTimeoutSimple"
108 //UpgradeEvTimeoutMids = "UpgradeEvTimeoutMids"
109 UpgradeEvReset = "UpgradeEvReset"
110 UpgradeEvAbort = "UpgradeEvAbort"
111 UpgradeEvRestart = "UpgradeEvRestart"
112 UpgradeEvAbortSwDownload = "UpgradeEvAbortSwDownload"
mpagenko80622a52021-02-09 16:53:23 +0000113)
114
mpagenko45586762021-10-01 08:30:22 +0000115// upgrade FSM related states
mpagenko80622a52021-02-09 16:53:23 +0000116const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117 UpgradeStDisabled = "UpgradeStDisabled"
118 UpgradeStStarting = "UpgradeStStarting"
119 UpgradeStWaitingAdapterDL = "UpgradeStWaitingAdapterDL"
120 UpgradeStPreparingDL = "UpgradeStPreparingDL"
121 UpgradeStDLSection = "UpgradeStDLSection"
122 UpgradeStVerifyWindow = "UpgradeStVerifyWindow"
123 UpgradeStFinalizeDL = "UpgradeStFinalizeDL"
124 UpgradeStWaitEndDL = "UpgradeStWaitEndDL"
125 UpgradeStCheckImageName = "UpgradeStCheckImageName"
126 UpgradeStWaitForActivate = "UpgradeStWaitForActivate"
127 UpgradeStRequestingActivate = "UpgradeStRequestingActivate"
128 UpgradeStActivated = "UpgradeStActivated"
129 UpgradeStWaitForCommit = "UpgradeStWaitForCommit"
130 UpgradeStCommitSw = "UpgradeStCommitSw"
131 UpgradeStCheckCommitted = "UpgradeStCheckCommitted"
132 UpgradeStResetting = "UpgradeStResetting"
133 UpgradeStRestarting = "UpgradeStRestarting"
134 UpgradeStAbortingDL = "UpgradeStAbortingDL"
mpagenko80622a52021-02-09 16:53:23 +0000135)
136
Joey Armstrong89c812c2024-01-12 19:00:20 -0500137// COnuUpgradeFsmIdleState - required definition for IdleState detection for activities on OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000138const COnuUpgradeFsmIdleState = UpgradeStWaitForCommit
mpagenko80622a52021-02-09 16:53:23 +0000139
Joey Armstrong89c812c2024-01-12 19:00:20 -0500140// OnuUpgradeFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
mpagenko80622a52021-02-09 16:53:23 +0000141type OnuUpgradeFsm struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000142 pDeviceHandler cmn.IdeviceHandler
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530143 pDevEntry cmn.IonuDeviceEntry
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000144 pDownloadManager *AdapterDownloadManager
145 pFileManager *FileDownloadManager //used from R2.8 with new API version
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000146 pOmciCC *cmn.OmciCC
147 pOnuDB *devdb.OnuDeviceDB
mpagenko80622a52021-02-09 16:53:23 +0000148 //omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000149 PAdaptFsm *cmn.AdapterFsm
mpagenkoc26d4c02021-05-06 14:27:57 +0000150 pImageDsc *voltha.ImageDownload
mpagenkoc26d4c02021-05-06 14:27:57 +0000151 pLastTxMeInstance *me.ManagedEntity
mpagenkoc26d4c02021-05-06 14:27:57 +0000152 chReceiveExpectedResponse chan bool
mpagenkoc26d4c02021-05-06 14:27:57 +0000153 chAdapterDlReady chan bool
mpagenko609a69a2021-12-02 08:12:58 +0000154 chAbortDelayEndSwDl chan struct{}
mpagenkoc26d4c02021-05-06 14:27:57 +0000155 chOnuDlReady chan bool
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530156 chReceiveAbortEndSwDlResponse chan tEndSwDlResponseResult
157 deviceID string
158 imageVersion string //name of the image as used within OMCI (and on extrenal API interface)
159 imageIdentifier string //name of the image as used in the adapter
160 imageBuffer []byte
161 requestEvent cmn.OnuDeviceEvent
162 downloadToOnuTimeout4MB time.Duration //timeout for downloading the image to the ONU for a 4MB image slice
163 omciSectionInterleaveDelay time.Duration //DownloadSectionInterleave delay in milliseconds
164 waitDelayEndSwDl time.Duration //duration, how long is waited before next request on EndSwDl
165 omciDownloadSectionSize int64
166 mutexUpgradeParams sync.RWMutex //mutex to protect members for parallel function requests and omci response processing
167 mutexIsAwaitingAdapterDlResponse sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000168 mutexAbortRequest sync.RWMutex
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530169 origImageLength uint32 //as also limited by OMCI
170 imageCRC uint32 //as per OMCI - ITU I.363.5 crc
171 imageLength uint32 //including last bytes padding
172 noOfSections uint32 //uint32 range for sections should be sufficient for very long images
173 nextDownloadSectionsAbsolute uint32 //number of next section to download in overall image
174 noOfWindows uint32 //uint32 range for windows should be sufficient for very long images
175 nextDownloadWindow uint32 //number of next window to download
mpagenko38662d02021-08-11 09:45:19 +0000176 abortRequested voltha.ImageState_ImageFailureReason
mpagenkoaa3afe92021-05-21 16:20:58 +0000177 volthaDownloadState voltha.ImageState_ImageDownloadState
178 volthaDownloadReason voltha.ImageState_ImageFailureReason
179 volthaImageState voltha.ImageState_ImageActivationState
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530180 InactiveImageMeID uint16 //ME-ID of the inactive image
181 omciDownloadWindowSizeLimit uint8 //windowSize-1 in sections
182 omciDownloadWindowSizeLast uint8 //number of sections in last window
183 nextDownloadSectionsWindow uint8 //number of next section to download within current window
184 delayEndSwDl bool //flag to provide a delay between last section and EndSwDl
185 repeatAbort bool //flag to indicate if OMCI EndSwDownload (abort) is to be repeated
186 waitCountEndSwDl uint8 //number, how often is waited for EndSwDl at maximum
187 useAPIVersion43 bool //flag for indication on which API version is used (and accordingly which specific methods)
188 isWaitingForAdapterDlResponse bool
189 activateImage bool
190 commitImage bool
191 conditionalCancelRequested bool
192 upgradePhase tUpgradePhase
Holger Hildebrandt288d9472021-09-06 10:47:53 +0000193 isEndSwDlOpen bool
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000194 isExtendedOmci bool
mpagenko80622a52021-02-09 16:53:23 +0000195}
196
Joey Armstrong89c812c2024-01-12 19:00:20 -0500197// NewOnuUpgradeFsm is the 'constructor' for the state machine to config the PON ANI ports
198//
199// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000200func NewOnuUpgradeFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler,
201 apDevEntry cmn.IonuDeviceEntry, apOnuDB *devdb.OnuDeviceDB,
202 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message) *OnuUpgradeFsm {
mpagenko80622a52021-02-09 16:53:23 +0000203 instFsm := &OnuUpgradeFsm{
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000204 pDeviceHandler: apDeviceHandler,
205 deviceID: apDeviceHandler.GetDeviceID(),
206 pDevEntry: apDevEntry,
207 pOmciCC: apDevEntry.GetDevOmciCC(),
208 pOnuDB: apOnuDB,
209 requestEvent: aRequestEvent,
210 omciSectionInterleaveDelay: cOmciSectionInterleaveMilliseconds,
211 downloadToOnuTimeout4MB: apDeviceHandler.GetDlToOnuTimeout4M(),
212 waitCountEndSwDl: cWaitCountEndSwDl,
213 waitDelayEndSwDl: cWaitDelayEndSwDlSeconds,
214 upgradePhase: cUpgradeUndefined,
215 volthaDownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
216 volthaDownloadReason: voltha.ImageState_NO_ERROR,
217 volthaImageState: voltha.ImageState_IMAGE_UNKNOWN,
218 abortRequested: voltha.ImageState_NO_ERROR,
mpagenko80622a52021-02-09 16:53:23 +0000219 }
mpagenko59498c12021-03-18 14:15:15 +0000220 instFsm.chReceiveExpectedResponse = make(chan bool)
mpagenkoc26d4c02021-05-06 14:27:57 +0000221 instFsm.chAdapterDlReady = make(chan bool)
mpagenko609a69a2021-12-02 08:12:58 +0000222 instFsm.chAbortDelayEndSwDl = make(chan struct{})
mpagenkoc26d4c02021-05-06 14:27:57 +0000223 instFsm.chOnuDlReady = make(chan bool)
mpagenko45586762021-10-01 08:30:22 +0000224 instFsm.chReceiveAbortEndSwDlResponse = make(chan tEndSwDlResponseResult)
mpagenko80622a52021-02-09 16:53:23 +0000225
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000226 instFsm.isExtendedOmci = instFsm.pDevEntry.GetPersIsExtOmciSupported()
227 if instFsm.isExtendedOmci {
228 instFsm.omciDownloadSectionSize = cOmciDownloadSectionSizeExtLine
229 instFsm.omciDownloadWindowSizeLimit = cOmciDownloadWindowSizeLimitExtLine
230 } else {
231 instFsm.omciDownloadSectionSize = cOmciDownloadSectionSizeBaseLine
232 instFsm.omciDownloadWindowSizeLimit = cOmciDownloadWindowSizeLimitBaseLine
233 }
234
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000235 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
236 if instFsm.PAdaptFsm == nil {
mpagenko80622a52021-02-09 16:53:23 +0000237 logger.Errorw(ctx, "OnuUpgradeFsm's AdapterFsm could not be instantiated!!", log.Fields{
238 "device-id": instFsm.deviceID})
239 return nil
240 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000241 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
242 UpgradeStDisabled,
mpagenko80622a52021-02-09 16:53:23 +0000243 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000244 {Name: UpgradeEvStart, Src: []string{UpgradeStDisabled}, Dst: UpgradeStStarting},
245 {Name: UpgradeEvAdapterDownload, Src: []string{UpgradeStStarting}, Dst: UpgradeStWaitingAdapterDL},
246 {Name: UpgradeEvPrepareSwDownload, Src: []string{UpgradeStStarting, UpgradeStWaitingAdapterDL}, Dst: UpgradeStPreparingDL},
247 {Name: UpgradeEvRxStartSwDownload, Src: []string{UpgradeStPreparingDL}, Dst: UpgradeStDLSection},
248 {Name: UpgradeEvWaitWindowAck, Src: []string{UpgradeStDLSection}, Dst: UpgradeStVerifyWindow},
249 {Name: UpgradeEvContinueNextWindow, Src: []string{UpgradeStVerifyWindow}, Dst: UpgradeStDLSection},
250 {Name: UpgradeEvEndSwDownload, Src: []string{UpgradeStVerifyWindow}, Dst: UpgradeStFinalizeDL},
251 {Name: UpgradeEvWaitEndDownload, Src: []string{UpgradeStFinalizeDL}, Dst: UpgradeStWaitEndDL},
252 {Name: UpgradeEvContinueFinalize, Src: []string{UpgradeStWaitEndDL}, Dst: UpgradeStFinalizeDL},
253 //UpgradeStCheckImageName only used with useAPIVersion43
254 {Name: UpgradeEvCheckImageName, Src: []string{UpgradeStWaitEndDL}, Dst: UpgradeStCheckImageName},
255 //UpgradeEvWaitForActivate state transitions depend on useAPIVersion43
256 {Name: UpgradeEvWaitForActivate, Src: []string{UpgradeStWaitEndDL, UpgradeStCheckImageName}, Dst: UpgradeStWaitForActivate},
257 //UpgradeEvRequestActivate state transitions depend on useAPIVersion43
258 {Name: UpgradeEvRequestActivate, Src: []string{UpgradeStStarting, UpgradeStWaitEndDL, UpgradeStCheckImageName,
259 UpgradeStWaitForActivate}, Dst: UpgradeStRequestingActivate}, //allows also for direct activation (without download) [TODO!!!]
260 {Name: UpgradeEvActivationDone, Src: []string{UpgradeStRequestingActivate}, Dst: UpgradeStActivated},
261 {Name: UpgradeEvWaitForCommit, Src: []string{UpgradeStRequestingActivate}, Dst: UpgradeStWaitForCommit},
262 {Name: UpgradeEvCommitSw, Src: []string{UpgradeStStarting, UpgradeStRequestingActivate, UpgradeStWaitForCommit,
263 UpgradeStActivated}, Dst: UpgradeStCommitSw}, //allows also for direct commitment (without download) [TODO!!!]
264 {Name: UpgradeEvCheckCommitted, Src: []string{UpgradeStCommitSw}, Dst: UpgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000265
266 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000267 {Name: UpgradeEvTimeoutSimple, Src: []string{
268 UpgradeStCreatingDot1PMapper, UpgradeStCreatingMBPCD, UpgradeStSettingTconts, UpgradeStSettingDot1PMapper}, Dst: UpgradeStStarting},
269 {Name: UpgradeEvTimeoutMids, Src: []string{
270 UpgradeStCreatingGemNCTPs, UpgradeStCreatingGemIWs, UpgradeStSettingPQs}, Dst: UpgradeStStarting},
mpagenko80622a52021-02-09 16:53:23 +0000271 */
272 // exceptional treatments
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000273 //on UpgradeEvReset: UpgradeStRequestingActivate, UpgradeStWaitForCommit and UpgradeStActivated are not reset
mpagenko1f8e8822021-06-25 14:10:21 +0000274 // (to let the FSM survive the expected OnuDown indication)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000275 {Name: UpgradeEvReset, Src: []string{UpgradeStStarting, UpgradeStWaitingAdapterDL, UpgradeStPreparingDL, UpgradeStDLSection,
276 UpgradeStVerifyWindow, UpgradeStDLSection, UpgradeStFinalizeDL, UpgradeStWaitEndDL, UpgradeStCheckImageName,
277 UpgradeStWaitForActivate,
mpagenko45586762021-10-01 08:30:22 +0000278 UpgradeStCommitSw, UpgradeStCheckCommitted, UpgradeStAbortingDL},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000279 Dst: UpgradeStResetting},
280 {Name: UpgradeEvAbort, Src: []string{UpgradeStStarting, UpgradeStWaitingAdapterDL, UpgradeStPreparingDL, UpgradeStDLSection,
281 UpgradeStVerifyWindow, UpgradeStDLSection, UpgradeStFinalizeDL, UpgradeStWaitEndDL, UpgradeStCheckImageName,
282 UpgradeStWaitForActivate,
283 UpgradeStRequestingActivate, UpgradeStActivated, UpgradeStWaitForCommit,
284 UpgradeStCommitSw, UpgradeStCheckCommitted},
285 Dst: UpgradeStResetting},
286 {Name: UpgradeEvAbortSwDownload, Src: []string{UpgradeStResetting}, Dst: UpgradeStAbortingDL},
287 {Name: UpgradeEvRestart, Src: []string{UpgradeStResetting, UpgradeStAbortingDL}, Dst: UpgradeStRestarting},
288 {Name: UpgradeEvDisable, Src: []string{UpgradeStRestarting}, Dst: UpgradeStDisabled},
mpagenko80622a52021-02-09 16:53:23 +0000289 },
290 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000291 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
292 "enter_" + UpgradeStStarting: func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
293 "enter_" + UpgradeStWaitingAdapterDL: func(e *fsm.Event) { instFsm.enterWaitingAdapterDL(ctx, e) },
294 "enter_" + UpgradeStPreparingDL: func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
295 "enter_" + UpgradeStDLSection: func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
296 "enter_" + UpgradeStVerifyWindow: func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
297 "enter_" + UpgradeStFinalizeDL: func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
298 "enter_" + UpgradeStWaitEndDL: func(e *fsm.Event) { instFsm.enterWaitEndDL(ctx, e) },
299 "enter_" + UpgradeStCheckImageName: func(e *fsm.Event) { instFsm.enterCheckImageName(ctx, e) },
300 "enter_" + UpgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
301 "enter_" + UpgradeStCommitSw: func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
302 "enter_" + UpgradeStCheckCommitted: func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
303 "enter_" + UpgradeStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
304 "enter_" + UpgradeStAbortingDL: func(e *fsm.Event) { instFsm.enterAbortingDL(ctx, e) },
305 "enter_" + UpgradeStRestarting: func(e *fsm.Event) { instFsm.enterRestarting(ctx, e) },
306 "enter_" + UpgradeStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000307 },
308 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000309 if instFsm.PAdaptFsm.PFsm == nil {
mpagenko80622a52021-02-09 16:53:23 +0000310 logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
311 "device-id": instFsm.deviceID})
312 return nil
313 }
314
315 logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
316 return instFsm
317}
318
Joey Armstrong89c812c2024-01-12 19:00:20 -0500319// SetDownloadParams configures the needed parameters for a specific download to the ONU
320//
321// called from 'old' API Activate_image_update()
mpagenko15ff4a52021-03-02 10:09:20 +0000322func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000323 apImageDsc *voltha.ImageDownload, apDownloadManager *AdapterDownloadManager) error {
324 pBaseFsm := oFsm.PAdaptFsm.PFsm
325 if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000326 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000327 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
328 "device-id": oFsm.deviceID, "image-description": apImageDsc})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000329 oFsm.InactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenko80622a52021-02-09 16:53:23 +0000330 oFsm.pImageDsc = apImageDsc
331 oFsm.pDownloadManager = apDownloadManager
Holger Hildebrandtac1e0592021-06-03 15:16:49 +0000332 oFsm.activateImage = true
333 oFsm.commitImage = true
mpagenkoaa3afe92021-05-21 16:20:58 +0000334 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000335
336 go func(aPBaseFsm *fsm.FSM) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000337 // let the upgrade FSM proceed to PreparingDL
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000338 _ = aPBaseFsm.Event(UpgradeEvPrepareSwDownload)
mpagenko80622a52021-02-09 16:53:23 +0000339 }(pBaseFsm)
340 return nil
341 }
342 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
343 "device-id": oFsm.deviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530344 return fmt.Errorf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID)
mpagenko80622a52021-02-09 16:53:23 +0000345}
346
Joey Armstrong89c812c2024-01-12 19:00:20 -0500347// SetDownloadParamsAfterDownload configures the needed parameters for a specific download to the ONU according to
348//
349// updated API interface with R2.8: start download to ONU if the image is downloaded to the adapter
350// called from 'new' API Download_onu_image
mpagenkoc26d4c02021-05-06 14:27:57 +0000351func (oFsm *OnuUpgradeFsm) SetDownloadParamsAfterDownload(ctx context.Context, aInactiveImageID uint16,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 apImageRequest *voltha.DeviceImageDownloadRequest, apDownloadManager *FileDownloadManager,
Holger Hildebrandtac010732021-06-02 13:35:39 +0000353 aImageIdentifier string) error {
mpagenkoc26d4c02021-05-06 14:27:57 +0000354 oFsm.mutexUpgradeParams.Lock()
355 var pBaseFsm *fsm.FSM = nil
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 if oFsm.PAdaptFsm != nil {
357 pBaseFsm = oFsm.PAdaptFsm.PFsm
mpagenkoc26d4c02021-05-06 14:27:57 +0000358 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000359 if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000360 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
361 "device-id": oFsm.deviceID, "image-description": apImageRequest})
362 oFsm.useAPIVersion43 = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000363 oFsm.InactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenkoc26d4c02021-05-06 14:27:57 +0000364 oFsm.pFileManager = apDownloadManager
365 oFsm.imageIdentifier = aImageIdentifier
366 oFsm.imageVersion = apImageRequest.Image.Version
367 oFsm.activateImage = apImageRequest.ActivateOnSuccess
368 oFsm.commitImage = apImageRequest.CommitOnSuccess
mpagenko45586762021-10-01 08:30:22 +0000369 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_STARTED //state change indication for download request
mpagenkoc26d4c02021-05-06 14:27:57 +0000370 oFsm.mutexUpgradeParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 _ = pBaseFsm.Event(UpgradeEvAdapterDownload) //no need to call the FSM event in background here
mpagenkoc26d4c02021-05-06 14:27:57 +0000372 return nil
373 }
374 oFsm.mutexUpgradeParams.Unlock()
375 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
376 "device-id": oFsm.deviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530377 return fmt.Errorf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +0000378}
379
Joey Armstrong89c812c2024-01-12 19:00:20 -0500380// SetActivationParamsRunning sets the activate and commit flags for a running download to the ONU according to adapters rpc call
381//
382// called from 'new' API Activate_onu_image
mpagenkoc26d4c02021-05-06 14:27:57 +0000383func (oFsm *OnuUpgradeFsm) SetActivationParamsRunning(ctx context.Context,
384 aImageIdentifier string, aCommit bool) error {
mpagenko45586762021-10-01 08:30:22 +0000385 logger.Debugw(ctx, "OnuUpgradeFsm activate/commit parameter setting", log.Fields{
386 "device-id": oFsm.deviceID, "image-id": aImageIdentifier, "commit": aCommit})
mpagenkoc26d4c02021-05-06 14:27:57 +0000387 oFsm.mutexUpgradeParams.Lock()
388 //set activate/commit independent from state, if FSM is already beyond concerned states, then it does not matter anyway
389 // (as long as the Imageidentifier is correct)
mpagenkoc26d4c02021-05-06 14:27:57 +0000390 if aImageIdentifier != oFsm.imageIdentifier {
391 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
392 "device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
393 oFsm.mutexUpgradeParams.Unlock()
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530394 return fmt.Errorf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
395 oFsm.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +0000396 }
397 oFsm.activateImage = true
398 oFsm.commitImage = aCommit
mpagenko45586762021-10-01 08:30:22 +0000399 oFsm.mutexUpgradeParams.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +0000400 var pBaseFsm *fsm.FSM = nil
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000401 if oFsm.PAdaptFsm != nil {
402 pBaseFsm = oFsm.PAdaptFsm.PFsm
mpagenkoc26d4c02021-05-06 14:27:57 +0000403 }
404 if pBaseFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000405 if pBaseFsm.Is(UpgradeStWaitForActivate) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000406 logger.Debugw(ctx, "OnuUpgradeFsm finish waiting for activate", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 _ = pBaseFsm.Event(UpgradeEvRequestActivate) //no need to call the FSM event in background here
mpagenko38662d02021-08-11 09:45:19 +0000408 } else {
mpagenko38662d02021-08-11 09:45:19 +0000409 logger.Debugw(ctx, "OnuUpgradeFsm not (yet?) waiting for activate", log.Fields{
410 "device-id": oFsm.deviceID, "current FsmState": pBaseFsm.Current()})
mpagenkoc26d4c02021-05-06 14:27:57 +0000411 }
412 return nil
413 }
414 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
415 "device-id": oFsm.deviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530416 return fmt.Errorf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +0000417}
418
Joey Armstrong89c812c2024-01-12 19:00:20 -0500419// SetActivationParamsStart starts upgrade processing with immediate activation
420//
421// called from 'new' API Activate_onu_image
mpagenkoc26d4c02021-05-06 14:27:57 +0000422func (oFsm *OnuUpgradeFsm) SetActivationParamsStart(ctx context.Context, aImageVersion string, aInactiveImageID uint16, aCommit bool) error {
423 oFsm.mutexUpgradeParams.Lock()
424 var pBaseFsm *fsm.FSM = nil
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000425 if oFsm.PAdaptFsm != nil {
426 pBaseFsm = oFsm.PAdaptFsm.PFsm
mpagenkoc26d4c02021-05-06 14:27:57 +0000427 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000428 if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000429 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with activation", log.Fields{
430 "device-id": oFsm.deviceID, "image-version": aImageVersion})
431 oFsm.useAPIVersion43 = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000432 oFsm.InactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenkoc26d4c02021-05-06 14:27:57 +0000433 oFsm.imageVersion = aImageVersion
434 oFsm.activateImage = true
435 oFsm.commitImage = aCommit
mpagenko38662d02021-08-11 09:45:19 +0000436 // indicate start of the upgrade activity
mpagenko45586762021-10-01 08:30:22 +0000437 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVATING //state change indication for activate request
mpagenkoc26d4c02021-05-06 14:27:57 +0000438 oFsm.mutexUpgradeParams.Unlock()
439 //directly request the FSM to activate the image
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000440 _ = pBaseFsm.Event(UpgradeEvRequestActivate) //no need to call the FSM event in background here
mpagenkoc26d4c02021-05-06 14:27:57 +0000441 return nil
442 }
443 oFsm.mutexUpgradeParams.Unlock()
444 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
445 "device-id": oFsm.deviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530446 return fmt.Errorf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +0000447}
448
Joey Armstrong89c812c2024-01-12 19:00:20 -0500449// SetCommitmentParamsRunning sets the commit flag for a running download to the ONU according to adapters rpc call
450//
451// called from 'new' API Commit_onu_image
mpagenko38662d02021-08-11 09:45:19 +0000452func (oFsm *OnuUpgradeFsm) SetCommitmentParamsRunning(ctx context.Context,
453 aImageIdentifier string, aImageVersion string) error {
mpagenkoc26d4c02021-05-06 14:27:57 +0000454 oFsm.mutexUpgradeParams.Lock()
455 //set commit independent from state, if FSM is already beyond commit state (just ready), then it does not matter anyway
456 // (as long as the Imageidentifier is correct)
457 logger.Debugw(ctx, "OnuUpgradeFsm commit parameter setting", log.Fields{
mpagenkoa2b288f2021-10-21 11:25:27 +0000458 "device-id": oFsm.deviceID, "image-id": aImageIdentifier, "image-version": aImageVersion})
mpagenko38662d02021-08-11 09:45:19 +0000459 if (aImageIdentifier != oFsm.imageIdentifier) && (aImageVersion != oFsm.imageVersion) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000460 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
mpagenko38662d02021-08-11 09:45:19 +0000461 "device-id": oFsm.deviceID, "request-identifier": aImageIdentifier, "fsm-identifier": oFsm.imageIdentifier,
462 "request-version": aImageVersion, "fsm-version": oFsm.imageVersion})
mpagenkoc26d4c02021-05-06 14:27:57 +0000463 oFsm.mutexUpgradeParams.Unlock()
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530464 return fmt.Errorf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
465 oFsm.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +0000466 }
467 oFsm.commitImage = true
468 oFsm.mutexUpgradeParams.Unlock()
469 var pBaseFsm *fsm.FSM = nil
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000470 if oFsm.PAdaptFsm != nil {
471 pBaseFsm = oFsm.PAdaptFsm.PFsm
mpagenkoc26d4c02021-05-06 14:27:57 +0000472 }
473 if pBaseFsm != nil {
mpagenko183647c2021-06-08 15:25:04 +0000474 //let the FSM decide if it is ready to process the event
475 logger.Debugw(ctx, "OnuUpgradeFsm requesting commit",
476 log.Fields{"device-id": oFsm.deviceID, "current FsmState": pBaseFsm.Current()})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000477 _ = pBaseFsm.Event(UpgradeEvCommitSw) //no need to call the FSM event in background here
mpagenkoc26d4c02021-05-06 14:27:57 +0000478 return nil
479 }
mpagenko38662d02021-08-11 09:45:19 +0000480 //should never occur
mpagenkoc26d4c02021-05-06 14:27:57 +0000481 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
482 "device-id": oFsm.deviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530483 return fmt.Errorf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +0000484}
485
Joey Armstrong89c812c2024-01-12 19:00:20 -0500486// SetCommitmentParamsStart starts upgrade processing with immediate commitment
487//
488// called from 'new' API Commit_onu_image
mpagenkoc26d4c02021-05-06 14:27:57 +0000489func (oFsm *OnuUpgradeFsm) SetCommitmentParamsStart(ctx context.Context, aImageVersion string, aActiveImageID uint16) error {
490 oFsm.mutexUpgradeParams.Lock()
491 var pBaseFsm *fsm.FSM = nil
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 if oFsm.PAdaptFsm != nil {
493 pBaseFsm = oFsm.PAdaptFsm.PFsm
mpagenkoc26d4c02021-05-06 14:27:57 +0000494 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000495 if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000496 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with commitment", log.Fields{
497 "device-id": oFsm.deviceID, "image-version": aImageVersion})
498 oFsm.useAPIVersion43 = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000499 oFsm.InactiveImageMeID = aActiveImageID //upgrade state machines inactive ImageId is the new active ImageId
mpagenkoc26d4c02021-05-06 14:27:57 +0000500 oFsm.imageVersion = aImageVersion
501 oFsm.commitImage = true
mpagenko45586762021-10-01 08:30:22 +0000502 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTING //state change indication for activate request
mpagenkoc26d4c02021-05-06 14:27:57 +0000503 oFsm.mutexUpgradeParams.Unlock()
mpagenko38662d02021-08-11 09:45:19 +0000504 //directly request the FSM to commit the image
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 _ = pBaseFsm.Event(UpgradeEvCommitSw) //no need to call the FSM event in background here
mpagenkoc26d4c02021-05-06 14:27:57 +0000506 return nil
507 }
508 oFsm.mutexUpgradeParams.Unlock()
509 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
510 "device-id": oFsm.deviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530511 return fmt.Errorf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +0000512}
513
Joey Armstrong89c812c2024-01-12 19:00:20 -0500514// GetCommitFlag delivers the commit flag that was configured here
mpagenko1f8e8822021-06-25 14:10:21 +0000515func (oFsm *OnuUpgradeFsm) GetCommitFlag(ctx context.Context) bool {
516 oFsm.mutexUpgradeParams.RLock()
517 defer oFsm.mutexUpgradeParams.RUnlock()
518 return oFsm.commitImage
519}
520
Joey Armstrong89c812c2024-01-12 19:00:20 -0500521// GetImageStates delivers the download/image states as per device proto buf definition
mpagenkoaa3afe92021-05-21 16:20:58 +0000522func (oFsm *OnuUpgradeFsm) GetImageStates(ctx context.Context,
mpagenko38662d02021-08-11 09:45:19 +0000523 aImageIdentifier string, aVersion string) *voltha.ImageState {
mpagenkoaa3afe92021-05-21 16:20:58 +0000524 pImageState := &voltha.ImageState{}
mpagenko38662d02021-08-11 09:45:19 +0000525 pImageState.Version = aVersion //version as requested
mpagenkoaa3afe92021-05-21 16:20:58 +0000526 // check if the request refers to some active image/version of the processing
527 oFsm.mutexUpgradeParams.RLock()
528 if (aImageIdentifier == oFsm.imageIdentifier) || (aVersion == oFsm.imageVersion) {
529 pImageState.DownloadState = oFsm.volthaDownloadState
530 pImageState.Reason = oFsm.volthaDownloadReason
531 pImageState.ImageState = oFsm.volthaImageState
532 } else {
533 pImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
534 pImageState.Reason = voltha.ImageState_NO_ERROR
535 pImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
536 }
537 oFsm.mutexUpgradeParams.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +0000538 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +0000539}
540
Joey Armstrong89c812c2024-01-12 19:00:20 -0500541// SetImageStateActive sets the FSM internal volthaImageState to ImageState_IMAGE_ACTIVE
mpagenko38662d02021-08-11 09:45:19 +0000542func (oFsm *OnuUpgradeFsm) SetImageStateActive(ctx context.Context) {
mpagenko183647c2021-06-08 15:25:04 +0000543 oFsm.mutexUpgradeParams.Lock()
544 defer oFsm.mutexUpgradeParams.Unlock()
mpagenko45586762021-10-01 08:30:22 +0000545 oFsm.upgradePhase = cUpgradeActivated
mpagenko38662d02021-08-11 09:45:19 +0000546 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVE
mpagenko38662d02021-08-11 09:45:19 +0000547}
548
Joey Armstrong89c812c2024-01-12 19:00:20 -0500549// CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko38662d02021-08-11 09:45:19 +0000550func (oFsm *OnuUpgradeFsm) CancelProcessing(ctx context.Context, abCompleteAbort bool,
551 aReason voltha.ImageState_ImageFailureReason) {
mpagenkoa2b288f2021-10-21 11:25:27 +0000552 pAdaptFsm := oFsm.PAdaptFsm
Holger Hildebrandt12609a12022-03-25 13:23:25 +0000553 logger.Debugw(ctx, "CancelProcessing entered", log.Fields{"device-id": oFsm.deviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +0000554 if pAdaptFsm == nil || pAdaptFsm.PFsm == nil {
555 logger.Warnw(ctx, "OnuUpgradeFsm cancel, but FSM invalid", log.Fields{
556 "device-id": oFsm.deviceID})
557 return
558 }
559 logger.Debugw(ctx, "OnuUpgradeFsm start canceling", log.Fields{
560 "device-id": oFsm.deviceID, "in fsm-state": pAdaptFsm.PFsm.Current()})
mpagenko38662d02021-08-11 09:45:19 +0000561 oFsm.mutexAbortRequest.Lock()
562 oFsm.abortRequested = aReason //possibly abort the sectionDownload loop
563 oFsm.mutexAbortRequest.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +0000564 //mutex protection is required for possible concurrent access to FSM members
565 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
566 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
567 oFsm.mutexIsAwaitingAdapterDlResponse.RLock()
568 if oFsm.isWaitingForAdapterDlResponse {
569 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
570 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
571 oFsm.chAdapterDlReady <- false
572 } else {
573 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
574 }
mpagenko609a69a2021-12-02 08:12:58 +0000575
576 //abort a possible delaying of sending EndSwDl
577 //use asynchronous channel sending to avoid blocking here in case no receiver is waiting
578 select {
579 case oFsm.chAbortDelayEndSwDl <- struct{}{}:
580 default:
581 }
582
mpagenkoc26d4c02021-05-06 14:27:57 +0000583 //chOnuDlReady is cleared as part of the FSM reset processing (from enterResetting())
584
585 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
mpagenko1f8e8822021-06-25 14:10:21 +0000586 // specific here: See definition of state changes: some states are excluded from reset for possible later commit
mpagenkoa2b288f2021-10-21 11:25:27 +0000587 pAdaptFsm = oFsm.PAdaptFsm
mpagenko59862f02021-10-11 08:53:18 +0000588 if pAdaptFsm != nil && pAdaptFsm.PFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +0000589 // calling FSM events in background to avoid blocking of the caller
mpagenko59862f02021-10-11 08:53:18 +0000590 go func(apFsm *fsm.FSM) {
591 if apFsm.Is(UpgradeStWaitEndDL) {
592 oFsm.chReceiveExpectedResponse <- false //which aborts the FSM in WaitEndDL state
593 } else if apFsm.Is(UpgradeStAbortingDL) {
594 oFsm.chReceiveAbortEndSwDlResponse <- cEndSwDlResponseAbort //abort waiting on EndDownloadResponse
595 }
mpagenko38662d02021-08-11 09:45:19 +0000596
mpagenko59862f02021-10-11 08:53:18 +0000597 var err error
598 if abCompleteAbort {
599 // in case of unconditional abort request the ImageState is set immediately
600 oFsm.mutexUpgradeParams.Lock()
601 //any previous lingering conditional cancelRequest is superseded by this abortion
602 oFsm.conditionalCancelRequested = false
603 oFsm.volthaDownloadReason = aReason
604 oFsm.mutexUpgradeParams.Unlock()
605 err = apFsm.Event(UpgradeEvAbort) //as unconditional default FSM cancellation
606 } else {
607 //at conditional abort request the image states are set when reaching the reset state
mpagenkoa2b288f2021-10-21 11:25:27 +0000608 oFsm.mutexUpgradeParams.Lock()
mpagenko59862f02021-10-11 08:53:18 +0000609 oFsm.conditionalCancelRequested = true
mpagenkoa2b288f2021-10-21 11:25:27 +0000610 oFsm.mutexUpgradeParams.Unlock()
mpagenko59862f02021-10-11 08:53:18 +0000611 err = apFsm.Event(UpgradeEvReset) //as state-conditional default FSM cleanup
612 }
613 if err != nil {
614 //error return is expected in case of conditional request and no state transition
615 logger.Debugw(ctx, "onu upgrade fsm could not cancel with abort/reset event", log.Fields{
616 "device-id": oFsm.deviceID, "error": err})
617 }
mpagenkoa2b288f2021-10-21 11:25:27 +0000618 logger.Debugw(ctx, "OnuUpgradeFsm canceling done", log.Fields{
619 "device-id": oFsm.deviceID})
mpagenko59862f02021-10-11 08:53:18 +0000620 }(pAdaptFsm.PFsm)
mpagenkoa2b288f2021-10-21 11:25:27 +0000621 } else { //the FSM seems already to be in some released state
622 logger.Warnw(ctx, "OnuUpgradeFsm canceling without FSM event", log.Fields{
623 "device-id": oFsm.deviceID})
624 }
mpagenkoc26d4c02021-05-06 14:27:57 +0000625}
626
mpagenko80622a52021-02-09 16:53:23 +0000627func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
628 logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
629 "device-id": oFsm.deviceID})
630
631 // start go routine for processing of LockState messages
632 go oFsm.processOmciUpgradeMessages(ctx)
633}
634
Joey Armstrong89c812c2024-01-12 19:00:20 -0500635// enterWaitingAdapterDL state can only be reached with useAPIVersion43
mpagenkoc26d4c02021-05-06 14:27:57 +0000636func (oFsm *OnuUpgradeFsm) enterWaitingAdapterDL(ctx context.Context, e *fsm.Event) {
637 logger.Debugw(ctx, "OnuUpgradeFsm waiting for adapter download", log.Fields{"in state": e.FSM.Current(),
638 "device-id": oFsm.deviceID})
mpagenko38662d02021-08-11 09:45:19 +0000639 syncChannel := make(chan struct{})
640 go oFsm.waitOnDownloadToAdapterReady(ctx, syncChannel, oFsm.chAdapterDlReady)
641 //block until the wait routine is really blocked on chAdapterDlReady
642 <-syncChannel
mpagenkoc26d4c02021-05-06 14:27:57 +0000643 go oFsm.pFileManager.RequestDownloadReady(ctx, oFsm.imageIdentifier, oFsm.chAdapterDlReady)
644}
645
mpagenko80622a52021-02-09 16:53:23 +0000646func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
647 logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
648 "device-id": oFsm.deviceID})
649
mpagenkoc26d4c02021-05-06 14:27:57 +0000650 var fileLen int64
651 var err error
mpagenkoaa3afe92021-05-21 16:20:58 +0000652 oFsm.mutexUpgradeParams.Lock()
mpagenkoc26d4c02021-05-06 14:27:57 +0000653 if oFsm.useAPIVersion43 {
654 //with the new API structure download to adapter is implicit and we have to wait until the image is available
655 fileLen, err = oFsm.pFileManager.GetImageBufferLen(ctx, oFsm.imageIdentifier)
656 } else {
657 fileLen, err = oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
658 }
mpagenkoc497ee32021-11-10 17:30:20 +0000659 if err != nil || fileLen == 0 || fileLen > int64(cMaxUint32) {
mpagenko39b703e2021-08-25 13:38:40 +0000660 oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'LOCAL_FILE_ERROR' would be better (proto)
mpagenkoaa3afe92021-05-21 16:20:58 +0000661 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000662 logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
663 "device-id": oFsm.deviceID, "error": err, "length": fileLen})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 pBaseFsm := oFsm.PAdaptFsm
mpagenko80622a52021-02-09 16:53:23 +0000665 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000666 go func(a_pAFsm *cmn.AdapterFsm) {
667 _ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000668 }(pBaseFsm)
669 return
670 }
671
mpagenkoc26d4c02021-05-06 14:27:57 +0000672 //copy file content to buffer
mpagenkoc497ee32021-11-10 17:30:20 +0000673 var imageBuffer []byte
mpagenkoc26d4c02021-05-06 14:27:57 +0000674 if oFsm.useAPIVersion43 {
mpagenkoc497ee32021-11-10 17:30:20 +0000675 imageBuffer, err = oFsm.pFileManager.GetDownloadImageBuffer(ctx, oFsm.imageIdentifier)
mpagenkoc26d4c02021-05-06 14:27:57 +0000676 } else {
mpagenkoc497ee32021-11-10 17:30:20 +0000677 imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
mpagenkoc26d4c02021-05-06 14:27:57 +0000678 }
mpagenko80622a52021-02-09 16:53:23 +0000679 if err != nil {
mpagenko39b703e2021-08-25 13:38:40 +0000680 oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'LOCAL_FILE_ERROR' would be better (proto)
mpagenkoaa3afe92021-05-21 16:20:58 +0000681 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000682 logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
683 "device-id": oFsm.deviceID, "error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000684 pBaseFsm := oFsm.PAdaptFsm
mpagenko80622a52021-02-09 16:53:23 +0000685 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000686 go func(a_pAFsm *cmn.AdapterFsm) {
687 _ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000688 }(pBaseFsm)
689 return
690 }
mpagenkoc497ee32021-11-10 17:30:20 +0000691 //provide slice capacity already with the reserve of one section to avoid inflation of the slice to double size at append
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000692 oFsm.imageBuffer = make([]byte, fileLen, fileLen+oFsm.omciDownloadSectionSize)
mpagenkoc497ee32021-11-10 17:30:20 +0000693 //better use a copy of the read image buffer in case the buffer/file is modified from outside,
694 // this also limits the slice len to the expected maximum fileLen
695 copy(oFsm.imageBuffer, imageBuffer)
mpagenko80622a52021-02-09 16:53:23 +0000696
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000697 oFsm.noOfSections = uint32(fileLen / oFsm.omciDownloadSectionSize)
698 if fileLen%oFsm.omciDownloadSectionSize > 0 {
699 // Because the extended message format allows for variable length,
700 // software image sections are only padded in baseline message format
701 if !oFsm.isExtendedOmci {
702 bufferPadding := make([]byte, oFsm.omciDownloadSectionSize-fileLen%oFsm.omciDownloadSectionSize)
703 //expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
704 oFsm.imageBuffer = append(oFsm.imageBuffer, bufferPadding...)
705 }
mpagenko80622a52021-02-09 16:53:23 +0000706 oFsm.noOfSections++
707 }
708 oFsm.origImageLength = uint32(fileLen)
709 oFsm.imageLength = uint32(len(oFsm.imageBuffer))
mpagenko80622a52021-02-09 16:53:23 +0000710 logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000711 "MeId": oFsm.InactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
mpagenko80622a52021-02-09 16:53:23 +0000712 "ImageSize": oFsm.imageLength, "original file size": fileLen})
713 //"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
mpagenkoaa3afe92021-05-21 16:20:58 +0000714
715 oFsm.mutexUpgradeParams.Unlock()
mpagenko39b703e2021-08-25 13:38:40 +0000716
mpagenkoa2b288f2021-10-21 11:25:27 +0000717 // flush chOnuDlReady
mpagenko39b703e2021-08-25 13:38:40 +0000718 select {
719 case <-oFsm.chOnuDlReady:
720 logger.Debug(ctx, "flushed OnuDlReady channel")
721 default:
722 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000723 go oFsm.waitOnDownloadToOnuReady(ctx, oFsm.chOnuDlReady) // start supervision of the complete download-to-ONU procedure
724
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725 err = oFsm.pOmciCC.SendStartSoftwareDownload(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000726 oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength, oFsm.isExtendedOmci)
mpagenko80622a52021-02-09 16:53:23 +0000727 if err != nil {
728 logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
729 "device-id": oFsm.deviceID, "error": err})
mpagenko45586762021-10-01 08:30:22 +0000730 oFsm.abortOnOmciError(ctx, true)
mpagenko80622a52021-02-09 16:53:23 +0000731 return
732 }
Holger Hildebrandt288d9472021-09-06 10:47:53 +0000733 oFsm.isEndSwDlOpen = true
mpagenko80622a52021-02-09 16:53:23 +0000734}
735
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530736//nolint:unparam
mpagenko80622a52021-02-09 16:53:23 +0000737func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
738 logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
739 "device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
mpagenkoa2b288f2021-10-21 11:25:27 +0000740 //use a background routine to send the multiple download sections frames in a loop
mpagenko609a69a2021-12-02 08:12:58 +0000741 // in order to avoid blocking on synchronous event calls for the entire (long) processing time
mpagenkoa2b288f2021-10-21 11:25:27 +0000742 go oFsm.runSwDlSectionWindow(ctx)
743}
mpagenko80622a52021-02-09 16:53:23 +0000744
Joey Armstrong89c812c2024-01-12 19:00:20 -0500745// runSwDlSectionWindow runs a loop to send all DlSection frames of one window in background
746//
747// may be aborted by parallel change of abortRequested
mpagenkoa2b288f2021-10-21 11:25:27 +0000748func (oFsm *OnuUpgradeFsm) runSwDlSectionWindow(ctx context.Context) {
mpagenko80622a52021-02-09 16:53:23 +0000749 var windowAckRequest uint8 = 0
750 var bufferStartOffset uint32
751 var bufferEndOffset uint32
752 var downloadSection []byte
kesavand011d5162021-11-25 19:21:06 +0530753
mpagenkoaa3afe92021-05-21 16:20:58 +0000754 oFsm.mutexUpgradeParams.Lock()
mpagenko45586762021-10-01 08:30:22 +0000755 oFsm.upgradePhase = cUpgradeDownloading //start of downloading image to ONU
mpagenko80622a52021-02-09 16:53:23 +0000756 if oFsm.nextDownloadSectionsAbsolute == 0 {
mpagenkoaa3afe92021-05-21 16:20:58 +0000757 oFsm.volthaImageState = voltha.ImageState_IMAGE_DOWNLOADING
mpagenko80622a52021-02-09 16:53:23 +0000758 }
kesavand011d5162021-11-25 19:21:06 +0530759 //var omuTxSecPerWindow []*common.OmciTransferStructure
760 omciMsgsPerSection := &ia.OmciMessages{}
761 //take the TID mutex
762 //To ensure the insequesnce of TIDS for all the onusw sections within a window
763 oFsm.pOmciCC.LockMutexTID()
764 defer oFsm.pOmciCC.UnLockMutexTID()
mpagenko80622a52021-02-09 16:53:23 +0000765 for {
mpagenko38662d02021-08-11 09:45:19 +0000766 oFsm.mutexAbortRequest.RLock()
767 // this way out of the section download loop on abort request
768 if oFsm.abortRequested != voltha.ImageState_NO_ERROR {
mpagenko45586762021-10-01 08:30:22 +0000769 //states are updated when entering the reset state ...
mpagenko38662d02021-08-11 09:45:19 +0000770 oFsm.volthaDownloadReason = oFsm.abortRequested
771 oFsm.mutexAbortRequest.RUnlock()
772 oFsm.mutexUpgradeParams.Unlock()
mpagenkoa2b288f2021-10-21 11:25:27 +0000773 pUpgradeFsm := oFsm.PAdaptFsm
774 if pUpgradeFsm != nil {
775 _ = pUpgradeFsm.PFsm.Event(UpgradeEvAbort)
776 logger.Debugw(ctx, "aborting runSwDlSectionWindow", log.Fields{
777 "device-id": oFsm.deviceID, "reason": oFsm.volthaDownloadReason})
778 return
779 }
780 logger.Warnw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
mpagenko38662d02021-08-11 09:45:19 +0000781 return
782 }
783 oFsm.mutexAbortRequest.RUnlock()
784
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000785 bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * uint32(oFsm.omciDownloadSectionSize)
786 bufferEndOffset = bufferStartOffset + uint32(oFsm.omciDownloadSectionSize) - 1
787 if oFsm.isExtendedOmci {
788 if bufferEndOffset > oFsm.origImageLength-1 {
789 bufferEndOffset = oFsm.origImageLength - 1
790 }
791 }
mpagenko80622a52021-02-09 16:53:23 +0000792 logger.Debugw(ctx, "DlSection values are", log.Fields{
793 "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
794 "DlSectionWindow": oFsm.nextDownloadSectionsWindow,
795 "startOffset": bufferStartOffset, "endOffset": bufferEndOffset})
796 if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
797 logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
798 "device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
799 "bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
mpagenko39b703e2021-08-25 13:38:40 +0000800 oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'LOCAL_FILE_ERROR' would be better (proto)
mpagenkoaa3afe92021-05-21 16:20:58 +0000801 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000802 //logical error -- reset the FSM
mpagenkoa2b288f2021-10-21 11:25:27 +0000803 pUpgradeFsm := oFsm.PAdaptFsm
804 if pUpgradeFsm != nil {
805 _ = pUpgradeFsm.PFsm.Event(UpgradeEvAbort)
806 return
807 }
808 logger.Warnw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +0000809 return
810 }
811 downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
812 if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
813 windowAckRequest = 1
814 logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
815 "device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
816 }
817 if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
818 windowAckRequest = 1
kesavand011d5162021-11-25 19:21:06 +0530819
mpagenko15ff4a52021-03-02 10:09:20 +0000820 oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
821 logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000822 "device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
823 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000824 oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
kesavand011d5162021-11-25 19:21:06 +0530825 omciTxReq, err := oFsm.pOmciCC.PrepareOnuSectionsOfWindow(log.WithSpanFromContext(context.Background(), ctx),
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000826 oFsm.InactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, omciMsgsPerSection, oFsm.isExtendedOmci)
mpagenko80622a52021-02-09 16:53:23 +0000827 if err != nil {
828 logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
mpagenko15ff4a52021-03-02 10:09:20 +0000829 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
mpagenkoa2b288f2021-10-21 11:25:27 +0000830 oFsm.abortOnOmciError(ctx, false)
mpagenko80622a52021-02-09 16:53:23 +0000831 return
832 }
kesavand011d5162021-11-25 19:21:06 +0530833
mpagenkoaa3afe92021-05-21 16:20:58 +0000834 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000835 oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
836 if windowAckRequest == 1 {
mpagenkoaa3afe92021-05-21 16:20:58 +0000837 oFsm.mutexUpgradeParams.Unlock()
kesavand011d5162021-11-25 19:21:06 +0530838
839 if omciTxReq.OnuSwWindow == nil {
840 logger.Errorw(ctx, "fail to send sections in a window", log.Fields{
841 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
842 oFsm.abortOnOmciError(ctx, false)
843 return
844 }
845
mpagenkoa2b288f2021-10-21 11:25:27 +0000846 pUpgradeFsm := oFsm.PAdaptFsm
847 if pUpgradeFsm != nil {
848 _ = pUpgradeFsm.PFsm.Event(UpgradeEvWaitWindowAck) //state transition to upgradeStVerifyWindow
Balaji Seenivasana52fb0c2024-12-18 07:50:42 +0530849 err := oFsm.pOmciCC.SendOnuSwSectionsWindowWithRxSupervision(ctx, omciTxReq, oFsm.pDeviceHandler.GetOmciTimeout(), oFsm.PAdaptFsm.CommChan)
850 if err != nil {
851 logger.Errorw(ctx, "DlSection abort: can't send window acknowledgement request to ONU ", log.Fields{
852 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
853 oFsm.abortOnOmciError(ctx, false)
854 }
mpagenkoa2b288f2021-10-21 11:25:27 +0000855 return
856 }
857 logger.Warnw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +0000858 return
859 }
kesavand011d5162021-11-25 19:21:06 +0530860
mpagenko80622a52021-02-09 16:53:23 +0000861 oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
mpagenko59498c12021-03-18 14:15:15 +0000862 if oFsm.omciSectionInterleaveDelay > 0 {
mpagenko80622a52021-02-09 16:53:23 +0000863 //ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
mpagenkoaa3afe92021-05-21 16:20:58 +0000864 oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
mpagenko59498c12021-03-18 14:15:15 +0000865 time.Sleep(oFsm.omciSectionInterleaveDelay * time.Millisecond)
mpagenkoaa3afe92021-05-21 16:20:58 +0000866 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000867 }
868 }
mpagenkoa2b288f2021-10-21 11:25:27 +0000869} //runSwDlSectionWindow
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530870//nolint:unparam
mpagenko80622a52021-02-09 16:53:23 +0000871func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
872 logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
873 "for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
874}
875
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530876//nolint:unparam
mpagenko80622a52021-02-09 16:53:23 +0000877func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
mpagenko80622a52021-02-09 16:53:23 +0000878 logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
mpagenko59498c12021-03-18 14:15:15 +0000879 "device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(oFsm.imageCRC), 16), "delay": oFsm.delayEndSwDl})
mpagenko609a69a2021-12-02 08:12:58 +0000880 //use a background routine to wait EndSwDlDelay and then send the EndSwDl request
881 // in order to avoid blocking on synchronous event calls for the complete wait time
882 // and to allow for state transition before sending the EndSwDl request
883 go oFsm.delayAndSendEndSwDl(ctx)
884}
mpagenko80622a52021-02-09 16:53:23 +0000885
Joey Armstrong89c812c2024-01-12 19:00:20 -0500886// delayAndSendEndSwDl ensures a delay before sending the EndSwDl request
887//
888// may also be aborted by parallel channel reception on chAbortEndSwDl
mpagenko609a69a2021-12-02 08:12:58 +0000889func (oFsm *OnuUpgradeFsm) delayAndSendEndSwDl(ctx context.Context) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000890 oFsm.mutexUpgradeParams.RLock()
mpagenko80622a52021-02-09 16:53:23 +0000891 if oFsm.delayEndSwDl {
mpagenkoaa3afe92021-05-21 16:20:58 +0000892 oFsm.mutexUpgradeParams.RUnlock()
mpagenko609a69a2021-12-02 08:12:58 +0000893 //give the ONU some time for image evaluation (hoping it does not only start this evaluation on first EndSwDl itself)
894 logger.Debugw(ctx, "OnuUpgradeFsm delay EndSwDl", log.Fields{"device-id": oFsm.deviceID,
895 "duration_s": cOmciEndSwDlDelaySeconds})
896 select {
897 case <-time.After(cOmciEndSwDlDelaySeconds * time.Second):
898 logger.Warnw(ctx, "OnuUpgradeFsm start sending EndSwDl", log.Fields{
899 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier})
900 case <-oFsm.chAbortDelayEndSwDl:
901 logger.Debugw(ctx, "OnuUpgradeFsm abort request to send EndSwDl", log.Fields{"device-id": oFsm.deviceID})
902 //according further state transition is ensured by the entity that sent the abort
903 return
904 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000905 } else {
906 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +0000907 }
908
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 pBaseFsm := oFsm.PAdaptFsm
mpagenko59498c12021-03-18 14:15:15 +0000910 if pBaseFsm == nil {
mpagenko38662d02021-08-11 09:45:19 +0000911 logger.Errorw(ctx, "EndSwDl abort: BaseFsm invalid", log.Fields{"device-id": oFsm.deviceID})
912 oFsm.mutexUpgradeParams.Lock()
mpagenko38662d02021-08-11 09:45:19 +0000913 oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR
914 oFsm.mutexUpgradeParams.Unlock()
mpagenko59498c12021-03-18 14:15:15 +0000915 // Can't call FSM Event directly, decoupling it
mpagenko609a69a2021-12-02 08:12:58 +0000916 _ = pBaseFsm.PFsm.Event(UpgradeEvAbort)
mpagenko59498c12021-03-18 14:15:15 +0000917 return
918 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000919 err := oFsm.pOmciCC.SendEndSoftwareDownload(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
Holger Hildebrandt5458d892022-05-31 09:52:06 +0000920 oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, oFsm.origImageLength, oFsm.imageCRC, oFsm.isExtendedOmci)
Holger Hildebrandt288d9472021-09-06 10:47:53 +0000921
mpagenko80622a52021-02-09 16:53:23 +0000922 if err != nil {
mpagenkoa2b288f2021-10-21 11:25:27 +0000923 logger.Errorw(ctx, "EndSwDl abort: error sending EndSwDl", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000924 "device-id": oFsm.deviceID, "error": err})
mpagenko45586762021-10-01 08:30:22 +0000925 oFsm.abortOnOmciError(ctx, true)
mpagenko80622a52021-02-09 16:53:23 +0000926 return
927 }
mpagenko609a69a2021-12-02 08:12:58 +0000928 //from here on sending of EndSwDl(Abort) is not needed anymore (even though response is not yet received)
929 // this avoids sending of both EndSwDl(Success) and EndSwDl(Abort) when cancellation falls just into this window
930 // the ONU must theoretically be prepared to receive none of them (in case of OMCI transfer issues) e.g. by timeout
931 oFsm.isEndSwDlOpen = false
932 // wait for the EndSwDLResponse and check, if the ONU is ready for activation
933 _ = pBaseFsm.PFsm.Event(UpgradeEvWaitEndDownload)
934} //delayAndSendEndSwDl
mpagenko59498c12021-03-18 14:15:15 +0000935
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530936//nolint:unparam
mpagenko59498c12021-03-18 14:15:15 +0000937func (oFsm *OnuUpgradeFsm) enterWaitEndDL(ctx context.Context, e *fsm.Event) {
938 logger.Infow(ctx, "OnuUpgradeFsm WaitEndDl", log.Fields{
939 "device-id": oFsm.deviceID, "wait delay": oFsm.waitDelayEndSwDl * time.Second, "wait count": oFsm.waitCountEndSwDl})
940 if oFsm.waitCountEndSwDl == 0 {
941 logger.Errorw(ctx, "WaitEndDl abort: max limit of EndSwDL reached", log.Fields{
942 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000943 pBaseFsm := oFsm.PAdaptFsm
mpagenko59498c12021-03-18 14:15:15 +0000944 if pBaseFsm == nil {
945 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
946 "device-id": oFsm.deviceID})
947 return
948 }
mpagenko38662d02021-08-11 09:45:19 +0000949 oFsm.mutexUpgradeParams.Lock()
mpagenko39b703e2021-08-25 13:38:40 +0000950 oFsm.volthaDownloadReason = voltha.ImageState_IMAGE_REFUSED_BY_ONU //something like 'END_DOWNLOAD_TIMEOUT' would be better (proto)
mpagenko38662d02021-08-11 09:45:19 +0000951 oFsm.mutexUpgradeParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 go func(a_pAFsm *cmn.AdapterFsm) {
953 _ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
mpagenko59498c12021-03-18 14:15:15 +0000954 }(pBaseFsm)
955 return
956 }
957
958 oFsm.waitCountEndSwDl--
959 select {
960 case <-time.After(oFsm.waitDelayEndSwDl * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000961 pBaseFsm := oFsm.PAdaptFsm
mpagenko59498c12021-03-18 14:15:15 +0000962 if pBaseFsm == nil {
963 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
964 "device-id": oFsm.deviceID})
965 //FSM may be reset already from somewhere else, nothing we can do here anymore
966 return
967 }
968 //retry End SW DL
mpagenkoaa3afe92021-05-21 16:20:58 +0000969 oFsm.mutexUpgradeParams.Lock()
mpagenko59498c12021-03-18 14:15:15 +0000970 oFsm.delayEndSwDl = false //no more extra delay for the request
mpagenkoaa3afe92021-05-21 16:20:58 +0000971 oFsm.mutexUpgradeParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000972 go func(a_pAFsm *cmn.AdapterFsm) {
973 _ = a_pAFsm.PFsm.Event(UpgradeEvContinueFinalize)
mpagenko59498c12021-03-18 14:15:15 +0000974 }(pBaseFsm)
975 return
976 case success := <-oFsm.chReceiveExpectedResponse:
977 logger.Debugw(ctx, "WaitEndDl stop wait timer", log.Fields{"device-id": oFsm.deviceID})
mpagenko45586762021-10-01 08:30:22 +0000978 oFsm.isEndSwDlOpen = false //no request to abort of download (already finished or immediate abort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 pBaseFsm := oFsm.PAdaptFsm
mpagenko59498c12021-03-18 14:15:15 +0000980 if pBaseFsm == nil {
981 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
982 "device-id": oFsm.deviceID})
983 //FSM may be reset already from somewhere else, nothing we can do here anymore
984 return
985 }
986 if success {
987 //answer received with ready indication
mpagenko38662d02021-08-11 09:45:19 +0000988 //useAPIVersion43 may not conflict in concurrency in this state function
989 if oFsm.useAPIVersion43 { // newer API usage requires verification of downloaded image version
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 go func(a_pAFsm *cmn.AdapterFsm) {
991 _ = a_pAFsm.PFsm.Event(UpgradeEvCheckImageName)
mpagenkoc26d4c02021-05-06 14:27:57 +0000992 }(pBaseFsm)
mpagenko38662d02021-08-11 09:45:19 +0000993 } else { // elder API usage does not support image version check -immediately consider download as successful
994 if oFsm.activateImage {
995 //immediate activation requested
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000996 go func(a_pAFsm *cmn.AdapterFsm) {
997 _ = a_pAFsm.PFsm.Event(UpgradeEvRequestActivate)
mpagenko38662d02021-08-11 09:45:19 +0000998 }(pBaseFsm)
999 } else {
1000 //have to wait on explicit activation request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001001 go func(a_pAFsm *cmn.AdapterFsm) {
1002 _ = a_pAFsm.PFsm.Event(UpgradeEvWaitForActivate)
mpagenko38662d02021-08-11 09:45:19 +00001003 }(pBaseFsm)
1004 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001005 }
mpagenko59498c12021-03-18 14:15:15 +00001006 return
1007 }
1008 //timer was aborted
mpagenko45586762021-10-01 08:30:22 +00001009 oFsm.abortOnOmciError(ctx, true)
mpagenko59498c12021-03-18 14:15:15 +00001010 return
1011 }
mpagenko80622a52021-02-09 16:53:23 +00001012}
1013
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301014//nolint:unparam
mpagenko38662d02021-08-11 09:45:19 +00001015func (oFsm *OnuUpgradeFsm) enterCheckImageName(ctx context.Context, e *fsm.Event) {
1016 logger.Debugw(ctx, "OnuUpgradeFsm checking downloaded image name", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017 "device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001018 requestedAttributes := me.AttributeValueMap{me.SoftwareImage_IsCommitted: 0, me.SoftwareImage_IsActive: 0, me.SoftwareImage_Version: ""}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001019 meInstance, err := oFsm.pOmciCC.SendGetMe(log.WithSpanFromContext(context.Background(), ctx),
1020 me.SoftwareImageClassID, oFsm.InactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.GetOmciTimeout(),
Holger Hildebrandtd930cb22022-06-17 09:24:50 +00001021 false, oFsm.PAdaptFsm.CommChan, oFsm.isExtendedOmci)
mpagenko38662d02021-08-11 09:45:19 +00001022 if err != nil {
1023 logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
1024 log.Fields{"device-id": oFsm.deviceID, "Error": err})
mpagenko45586762021-10-01 08:30:22 +00001025 oFsm.abortOnOmciError(ctx, true)
mpagenko38662d02021-08-11 09:45:19 +00001026 return
1027 }
1028 oFsm.pLastTxMeInstance = meInstance
1029}
1030
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301031//nolint:unparam
mpagenko80622a52021-02-09 16:53:23 +00001032func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
1033 logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001034 "device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
mpagenko80622a52021-02-09 16:53:23 +00001035
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 err := oFsm.pOmciCC.SendActivateSoftware(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
Holger Hildebrandt5458d892022-05-31 09:52:06 +00001037 oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, oFsm.isExtendedOmci)
mpagenko80622a52021-02-09 16:53:23 +00001038 if err != nil {
1039 logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
1040 "device-id": oFsm.deviceID, "error": err})
mpagenko45586762021-10-01 08:30:22 +00001041 oFsm.abortOnOmciError(ctx, true)
mpagenko80622a52021-02-09 16:53:23 +00001042 return
1043 }
mpagenko38662d02021-08-11 09:45:19 +00001044 oFsm.mutexUpgradeParams.Lock()
mpagenko45586762021-10-01 08:30:22 +00001045 oFsm.upgradePhase = cUpgradeActivating //start of image activation for ONU
mpagenko38662d02021-08-11 09:45:19 +00001046 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVATING
1047 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001048}
1049
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301050//nolint:unparam
mpagenko80622a52021-02-09 16:53:23 +00001051func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
mpagenko38662d02021-08-11 09:45:19 +00001052 logger.Debugw(ctx, "OnuUpgradeFsm start commit SW", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 "device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
mpagenko38662d02021-08-11 09:45:19 +00001054 //any abort request (also conditional) is still regarded as valid as the commit indication might not be possible to verify
1055 // (which is a bit problematic as the ONU might already be in committed state,
1056 // in this case (committing failed) always 'onuimage list' should be used to verify the real state (if ONU is reachable))
1057 if activeImageID, err := oFsm.pDevEntry.GetActiveImageMeID(ctx); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001058 oFsm.mutexUpgradeParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 if activeImageID == oFsm.InactiveImageMeID {
1060 inactiveImageID := oFsm.InactiveImageMeID
mpagenko15ff4a52021-03-02 10:09:20 +00001061 logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
mpagenkoaa3afe92021-05-21 16:20:58 +00001062 "device-id": oFsm.deviceID, "me-id": inactiveImageID}) //more efficient activeImageID with above check
1063 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTING
mpagenko45586762021-10-01 08:30:22 +00001064 oFsm.upgradePhase = cUpgradeCommitting //start of image commitment for ONU
mpagenkoaa3afe92021-05-21 16:20:58 +00001065 oFsm.mutexUpgradeParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001066 err := oFsm.pOmciCC.SendCommitSoftware(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
Holger Hildebrandt5458d892022-05-31 09:52:06 +00001067 oFsm.PAdaptFsm.CommChan, inactiveImageID, oFsm.isExtendedOmci) //more efficient activeImageID with above check
mpagenko15ff4a52021-03-02 10:09:20 +00001068 if err != nil {
1069 logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
1070 "device-id": oFsm.deviceID, "error": err})
mpagenko45586762021-10-01 08:30:22 +00001071 oFsm.abortOnOmciError(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001072 return
1073 }
1074 return
1075 }
mpagenko38662d02021-08-11 09:45:19 +00001076 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001077 logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001078 "device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.InactiveImageMeID})
mpagenko38662d02021-08-11 09:45:19 +00001079 } else {
1080 logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
1081 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001082 }
mpagenko38662d02021-08-11 09:45:19 +00001083 oFsm.mutexUpgradeParams.Lock()
1084 oFsm.conditionalCancelRequested = false //any lingering conditional cancelRequest is superseded by this error
mpagenko38662d02021-08-11 09:45:19 +00001085 oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
mpagenko38662d02021-08-11 09:45:19 +00001086 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001087 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001088 pBaseFsm := oFsm.PAdaptFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001089 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001090 go func(a_pAFsm *cmn.AdapterFsm) {
1091 _ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
mpagenko15ff4a52021-03-02 10:09:20 +00001092 }(pBaseFsm)
1093}
1094
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301095//nolint:unparam
mpagenko15ff4a52021-03-02 10:09:20 +00001096func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
mpagenko38662d02021-08-11 09:45:19 +00001097 logger.Debugw(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001098 "device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001099 requestedAttributes := me.AttributeValueMap{me.SoftwareImage_IsCommitted: 0, me.SoftwareImage_IsActive: 0, me.SoftwareImage_Version: ""}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001100 meInstance, err := oFsm.pOmciCC.SendGetMe(log.WithSpanFromContext(context.Background(), ctx),
Holger Hildebrandtd930cb22022-06-17 09:24:50 +00001101 me.SoftwareImageClassID, oFsm.InactiveImageMeID, requestedAttributes,
1102 oFsm.pDeviceHandler.GetOmciTimeout(), false, oFsm.PAdaptFsm.CommChan, oFsm.isExtendedOmci)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001103 if err != nil {
1104 logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
1105 log.Fields{"device-id": oFsm.deviceID, "Error": err})
mpagenko45586762021-10-01 08:30:22 +00001106 oFsm.abortOnOmciError(ctx, true)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001107 return
1108 }
mpagenko15ff4a52021-03-02 10:09:20 +00001109 oFsm.pLastTxMeInstance = meInstance
mpagenko80622a52021-02-09 16:53:23 +00001110}
1111
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301112//nolint:unparam
mpagenko80622a52021-02-09 16:53:23 +00001113func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1114 logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
1115
mpagenko45586762021-10-01 08:30:22 +00001116 oFsm.stateUpdateOnReset(ctx)
mpagenko38662d02021-08-11 09:45:19 +00001117
mpagenkoa2b288f2021-10-21 11:25:27 +00001118 oFsm.mutexAbortRequest.Lock()
1119 //to be sure to abort a possibly still running runSwDlSectionWindow()
1120 // in case the reset was not received from cancel() and download not finished correctly
1121 oFsm.abortRequested = oFsm.volthaDownloadReason
1122 oFsm.mutexAbortRequest.Unlock()
1123
mpagenkoc26d4c02021-05-06 14:27:57 +00001124 // in case the download-to-ONU timer is still running - cancel it
mpagenko39b703e2021-08-25 13:38:40 +00001125 //use non-blocking channel (to be independent from receiver state)
1126 select {
1127 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
1128 case oFsm.chOnuDlReady <- false:
1129 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001130 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001131 pConfigUpgradeStateAFsm := oFsm.PAdaptFsm
1132 if pConfigUpgradeStateAFsm != nil {
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001133 var nextEvent string
1134 if oFsm.isEndSwDlOpen {
mpagenko45586762021-10-01 08:30:22 +00001135 if oFsm.repeatAbort {
1136 oFsm.delayEndSwDl = true //run next abort with delay
1137 } else { //initial request
1138 oFsm.delayEndSwDl = false //run next abort with no delay
1139 oFsm.waitCountEndSwDl = cWaitCountEndSwDl //init for possible repetitions
1140 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001141 nextEvent = UpgradeEvAbortSwDownload
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001142 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001143 nextEvent = UpgradeEvRestart
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001144 }
1145 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001146 go func(a_pAFsm *cmn.AdapterFsm) {
1147 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1148 _ = a_pAFsm.PFsm.Event(nextEvent)
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001149 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001150 }(pConfigUpgradeStateAFsm)
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001151 }
1152}
mpagenkoc26d4c02021-05-06 14:27:57 +00001153
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301154//nolint:unparam
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001155func (oFsm *OnuUpgradeFsm) enterAbortingDL(ctx context.Context, e *fsm.Event) {
1156 logger.Debugw(ctx, "OnuUpgradeFsm aborting download to ONU", log.Fields{"device-id": oFsm.deviceID})
1157
mpagenko45586762021-10-01 08:30:22 +00001158 oFsm.mutexUpgradeParams.RLock()
1159 if oFsm.delayEndSwDl {
1160 oFsm.mutexUpgradeParams.RUnlock()
1161 //give the ONU some time for image discard activities
1162 time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
1163 } else {
1164 oFsm.mutexUpgradeParams.RUnlock()
1165 }
1166
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001167 pBaseFsm := oFsm.PAdaptFsm
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001168 if pBaseFsm == nil {
1169 logger.Errorw(ctx, "OnuUpgradeFsm aborting download: BaseFsm invalid", log.Fields{"device-id": oFsm.deviceID})
1170 return
1171 }
1172 // abort the download operation by sending an end software download message with invalid CRC and image size
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001173 err := oFsm.pOmciCC.SendEndSoftwareDownload(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
Holger Hildebrandt5458d892022-05-31 09:52:06 +00001174 oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, 0, 0xFFFFFFFF, oFsm.isExtendedOmci)
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001175
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001176 if err != nil {
1177 logger.Errorw(ctx, "OnuUpgradeFsm aborting download: can't send EndSwDl request", log.Fields{"device-id": oFsm.deviceID})
1178 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001179 go func(a_pAFsm *cmn.AdapterFsm) {
1180 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1181 _ = a_pAFsm.PFsm.Event(UpgradeEvRestart)
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001182 }
1183 }(pBaseFsm)
1184 return
1185 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001186
1187 //avoid waiting in the enterXXX function here,
1188 // otherwise synchronous event calls (like from RxMessage processing) may block and block complete Rx processing then
1189 go oFsm.waitOnAbortEndSwDlResponse(ctx)
mpagenko45586762021-10-01 08:30:22 +00001190}
1191
Joey Armstrong89c812c2024-01-12 19:00:20 -05001192// abortingDlEvaluateResponse waits for a channel indication with decision to proceed the FSM processing
mpagenko45586762021-10-01 08:30:22 +00001193func (oFsm *OnuUpgradeFsm) abortingDlEvaluateResponse(ctx context.Context,
1194 pBaseFsm *cmn.AdapterFsm, aResponseResult tEndSwDlResponseResult) bool {
1195 switch aResponseResult {
1196 case cEndSwDlResponseBusy: // indication for device busy, needs repetition
1197 if oFsm.waitCountEndSwDl == 0 {
1198 logger.Errorw(ctx, "aborting download: max limit of EndSwDl reached", log.Fields{
1199 "device-id": oFsm.deviceID})
1200 go func(a_pAFsm *cmn.AdapterFsm) {
1201 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1202 _ = a_pAFsm.PFsm.Event(UpgradeEvRestart) //give up and let FSM terminate
1203 }
1204 }(pBaseFsm)
1205 } else {
1206 logger.Debugw(ctx, "aborting download: re-trigger sending abort SwDl", log.Fields{
1207 "device-id": oFsm.deviceID, "counter": oFsm.waitCountEndSwDl})
1208 oFsm.waitCountEndSwDl--
1209 oFsm.repeatAbort = true //repeated request in next round
1210 go func(a_pAFsm *cmn.AdapterFsm) {
1211 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1212 _ = a_pAFsm.PFsm.Event(UpgradeEvReset) //which then re-triggers sending AbortSwDL
1213 }
1214 }(pBaseFsm)
1215 }
1216 return true
1217 case cEndSwDlResponseSuccess: // indication for success response
1218 logger.Infow(ctx, "aborting download: success response, terminating FSM", log.Fields{
1219 "device-id": oFsm.deviceID})
1220 case cEndSwDlResponseAbort: // indication for request to abort waiting for response
1221 logger.Infow(ctx, "aborting download: request to abort waiting, terminating FSM", log.Fields{
1222 "device-id": oFsm.deviceID})
1223 default:
1224 logger.Errorw(ctx, "aborting download: unknown channel indication, terminating FSM", log.Fields{
1225 "device-id": oFsm.deviceID})
1226 } //switch
1227 return false
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001228}
1229
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301230//nolint:unparam
Holger Hildebrandt288d9472021-09-06 10:47:53 +00001231func (oFsm *OnuUpgradeFsm) enterRestarting(ctx context.Context, e *fsm.Event) {
1232 logger.Debugw(ctx, "OnuUpgradeFsm restarting", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001233 pConfigUpgradeStateAFsm := oFsm.PAdaptFsm
1234 if pConfigUpgradeStateAFsm != nil {
mpagenko80622a52021-02-09 16:53:23 +00001235 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001236 fsmAbortMsg := cmn.Message{
1237 Type: cmn.TestMsg,
1238 Data: cmn.TestMessage{
1239 TestMessageVal: cmn.AbortMessageProcessing,
mpagenko80622a52021-02-09 16:53:23 +00001240 },
1241 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001242 pConfigUpgradeStateAFsm.CommChan <- fsmAbortMsg
mpagenko80622a52021-02-09 16:53:23 +00001243
1244 //try to restart the FSM to 'disabled'
1245 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001246 go func(a_pAFsm *cmn.AdapterFsm) {
1247 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1248 _ = a_pAFsm.PFsm.Event(UpgradeEvDisable)
mpagenko80622a52021-02-09 16:53:23 +00001249 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001250 }(pConfigUpgradeStateAFsm)
mpagenko80622a52021-02-09 16:53:23 +00001251 }
1252}
1253
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301254//nolint:unparam
mpagenko80622a52021-02-09 16:53:23 +00001255func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1256 logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001257 // no need to flush possible channels here, Upgrade FSM will be completely removed, garbage collector should find its way
mpagenko80622a52021-02-09 16:53:23 +00001258 if oFsm.pDeviceHandler != nil {
1259 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
mpagenko38662d02021-08-11 09:45:19 +00001260 pLastUpgradeImageState := &voltha.ImageState{
1261 Version: oFsm.imageVersion,
1262 DownloadState: oFsm.volthaDownloadState,
1263 Reason: oFsm.volthaDownloadReason,
1264 ImageState: oFsm.volthaImageState,
1265 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001266 go oFsm.pDeviceHandler.RemoveOnuUpgradeFsm(ctx, pLastUpgradeImageState)
mpagenko80622a52021-02-09 16:53:23 +00001267 }
1268}
1269
1270func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
1271 logger.Debugw(ctx, "Start OnuUpgradeFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
1272loop:
1273 for {
1274 // case <-ctx.Done():
1275 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
1276 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001277 message, ok := <-oFsm.PAdaptFsm.CommChan
mpagenko80622a52021-02-09 16:53:23 +00001278 if !ok {
1279 logger.Info(ctx, "OnuUpgradeFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
1280 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
mpagenko45586762021-10-01 08:30:22 +00001281 oFsm.abortOnOmciError(ctx, true)
mpagenko80622a52021-02-09 16:53:23 +00001282 break loop
1283 }
1284 logger.Debugw(ctx, "OnuUpgradeFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
1285
1286 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001287 case cmn.TestMsg:
1288 msg, _ := message.Data.(cmn.TestMessage)
1289 if msg.TestMessageVal == cmn.AbortMessageProcessing {
mpagenko80622a52021-02-09 16:53:23 +00001290 logger.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
1291 break loop
1292 }
1293 logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 case cmn.OMCI:
1295 msg, _ := message.Data.(cmn.OmciMessage)
mpagenko80622a52021-02-09 16:53:23 +00001296 oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
1297 default:
1298 logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
1299 "message.Type": message.Type})
1300 }
1301 }
1302 logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
1303}
1304
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001305func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg cmn.OmciMessage) {
mpagenko80622a52021-02-09 16:53:23 +00001306 logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
1307 "msgType": msg.OmciMsg.MessageType})
1308
1309 switch msg.OmciMsg.MessageType {
1310 case omci.StartSoftwareDownloadResponseType:
1311 {
mpagenko45586762021-10-01 08:30:22 +00001312 oFsm.handleRxStartSwDownloadResponse(ctx, msg)
mpagenko80622a52021-02-09 16:53:23 +00001313 return
1314 } //StartSoftwareDownloadResponseType
1315 case omci.DownloadSectionResponseType:
1316 {
mpagenko45586762021-10-01 08:30:22 +00001317 oFsm.handleRxSwSectionResponse(ctx, msg)
mpagenko80622a52021-02-09 16:53:23 +00001318 return
mpagenko80622a52021-02-09 16:53:23 +00001319 } //DownloadSectionResponseType
1320 case omci.EndSoftwareDownloadResponseType:
1321 {
mpagenko45586762021-10-01 08:30:22 +00001322 oFsm.handleRxEndSwDownloadResponse(ctx, msg)
mpagenko80622a52021-02-09 16:53:23 +00001323 return
1324 } //EndSoftwareDownloadResponseType
1325 case omci.ActivateSoftwareResponseType:
1326 {
1327 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
1328 if msgLayer == nil {
1329 logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
1330 log.Fields{"device-id": oFsm.deviceID})
mpagenko45586762021-10-01 08:30:22 +00001331 oFsm.abortOnOmciError(ctx, false)
mpagenko80622a52021-02-09 16:53:23 +00001332 return
1333 }
1334 msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
1335 if !msgOk {
1336 logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
1337 log.Fields{"device-id": oFsm.deviceID})
mpagenko45586762021-10-01 08:30:22 +00001338 oFsm.abortOnOmciError(ctx, false)
mpagenko80622a52021-02-09 16:53:23 +00001339 return
1340 }
1341 logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
1342 "device-id": oFsm.deviceID, "data-fields": msgObj})
1343 if msgObj.Result != me.Success {
1344 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
1345 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko45586762021-10-01 08:30:22 +00001346 oFsm.abortOnOmciError(ctx, false)
mpagenko80622a52021-02-09 16:53:23 +00001347 return
1348 }
mpagenko183647c2021-06-08 15:25:04 +00001349 oFsm.mutexUpgradeParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 if msgObj.EntityInstance == oFsm.InactiveImageMeID {
mpagenko38662d02021-08-11 09:45:19 +00001351 // the image is regarded as active really only after ONU reboot and according indication (ONU down/up procedure)
mpagenko183647c2021-06-08 15:25:04 +00001352 oFsm.mutexUpgradeParams.Unlock()
1353 logger.Infow(ctx, "Expected ActivateSwResponse received",
1354 log.Fields{"device-id": oFsm.deviceID, "commit": oFsm.commitImage})
1355 if oFsm.commitImage {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001356 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvWaitForCommit)
mpagenko183647c2021-06-08 15:25:04 +00001357 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvActivationDone) // let the FSM wait for external commit request
mpagenko183647c2021-06-08 15:25:04 +00001359 }
mpagenko80622a52021-02-09 16:53:23 +00001360 return
1361 }
mpagenko183647c2021-06-08 15:25:04 +00001362 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001363 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
1364 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko45586762021-10-01 08:30:22 +00001365 oFsm.abortOnOmciError(ctx, false)
mpagenko80622a52021-02-09 16:53:23 +00001366 return
1367 } //ActivateSoftwareResponseType
mpagenko15ff4a52021-03-02 10:09:20 +00001368 case omci.CommitSoftwareResponseType:
1369 {
1370 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
1371 if msgLayer == nil {
1372 logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
1373 log.Fields{"device-id": oFsm.deviceID})
mpagenko45586762021-10-01 08:30:22 +00001374 oFsm.abortOnOmciError(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00001375 return
1376 }
1377 msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
1378 if !msgOk {
1379 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
1380 log.Fields{"device-id": oFsm.deviceID})
mpagenko45586762021-10-01 08:30:22 +00001381 oFsm.abortOnOmciError(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00001382 return
1383 }
mpagenkobf67a092021-03-17 09:52:28 +00001384 if msgObj.Result != me.Success {
mpagenko15ff4a52021-03-02 10:09:20 +00001385 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
1386 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko45586762021-10-01 08:30:22 +00001387 oFsm.abortOnOmciError(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00001388 return
mpagenkobf67a092021-03-17 09:52:28 +00001389 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001390 oFsm.mutexUpgradeParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 if msgObj.EntityInstance == oFsm.InactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +00001392 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001393 logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
1394 //verifying committed image
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001395 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvCheckCommitted)
mpagenko15ff4a52021-03-02 10:09:20 +00001396 return
1397 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001398 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001399 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse wrong ME instance: abort",
1400 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko45586762021-10-01 08:30:22 +00001401 oFsm.abortOnOmciError(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00001402 return
1403 } //CommitSoftwareResponseType
1404 case omci.GetResponseType:
1405 {
mpagenko45586762021-10-01 08:30:22 +00001406 oFsm.handleRxSwGetResponse(ctx, msg)
mpagenko15ff4a52021-03-02 10:09:20 +00001407 return
1408 } //GetResponseType
mpagenko80622a52021-02-09 16:53:23 +00001409 default:
1410 {
1411 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
1412 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
1413 return
1414 }
1415 }
1416}
1417
mpagenko45586762021-10-01 08:30:22 +00001418func (oFsm *OnuUpgradeFsm) handleRxStartSwDownloadResponse(ctx context.Context, msg cmn.OmciMessage) {
1419 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
1420 if msgLayer == nil {
1421 logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
1422 log.Fields{"device-id": oFsm.deviceID})
1423 oFsm.abortOnOmciError(ctx, false)
1424 return
1425 }
1426 msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
1427 if !msgOk {
1428 logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
1429 log.Fields{"device-id": oFsm.deviceID})
1430 oFsm.abortOnOmciError(ctx, false)
1431 return
1432 }
1433 logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
1434 "device-id": oFsm.deviceID, "data-fields": msgObj})
1435 if msgObj.Result != me.Success {
1436 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
1437 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1438 oFsm.abortOnOmciError(ctx, false)
1439 return
1440 }
1441
1442 oFsm.mutexUpgradeParams.Lock()
1443 if msgObj.EntityInstance == oFsm.InactiveImageMeID {
1444 logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
1445 if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
1446 // also response WindowSize = 0 is a valid number for used Window size 1
1447 logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
1448 "acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
1449 oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
1450 }
1451 oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
1452 if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
1453 oFsm.noOfWindows++
1454 }
1455 logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
1456 "windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
1457 "at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
1458 oFsm.nextDownloadSectionsAbsolute = 0
1459 oFsm.nextDownloadSectionsWindow = 0
1460 oFsm.nextDownloadWindow = 0
1461
1462 oFsm.mutexUpgradeParams.Unlock()
1463 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvRxStartSwDownload)
1464 return
1465 }
1466 oFsm.mutexUpgradeParams.Unlock()
1467 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
1468 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1469 oFsm.abortOnOmciError(ctx, false)
1470} //handleRxStartSwDownloadResponse
1471
1472func (oFsm *OnuUpgradeFsm) handleRxSwSectionResponse(ctx context.Context, msg cmn.OmciMessage) {
mpagenkoa2b288f2021-10-21 11:25:27 +00001473 if oFsm.PAdaptFsm == nil {
1474 logger.Infow(ctx, "DlSectionResponse received - but FSM not really valid anymore", log.Fields{
1475 "device-id": oFsm.deviceID})
1476 return
1477 }
1478 if !oFsm.PAdaptFsm.PFsm.Is(UpgradeStVerifyWindow) {
1479 //all the processing here is only relevant if the FSM is in state upgradeStVerifyWindow
1480 // otherwise this response can be ignored (may stem from a long-processing window send activity,
1481 // which is not anymore relevant based on intermediate (cancel) state transitions)
1482 logger.Infow(ctx, "DlSectionResponse received - but ignored", log.Fields{
1483 "device-id": oFsm.deviceID, "fsm-state": oFsm.PAdaptFsm.PFsm.Current()})
1484 return
1485 }
mpagenko45586762021-10-01 08:30:22 +00001486 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
1487 if msgLayer == nil {
1488 logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
1489 log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
1490 oFsm.abortOnOmciError(ctx, false)
1491 return
1492 }
1493 msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
1494 if !msgOk {
1495 logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
1496 log.Fields{"device-id": oFsm.deviceID})
1497 oFsm.abortOnOmciError(ctx, false)
1498 return
1499 }
1500 logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
1501 "device-id": oFsm.deviceID, "data-fields": msgObj})
1502 if msgObj.Result != me.Success {
1503 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
1504 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1505 oFsm.abortOnOmciError(ctx, false)
1506 return
1507 }
1508 oFsm.mutexUpgradeParams.Lock()
1509 if msgObj.EntityInstance == oFsm.InactiveImageMeID {
1510 sectionNumber := msgObj.SectionNumber
1511 logger.Infow(ctx, "DlSectionResponse received", log.Fields{
1512 "window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
1513
1514 oFsm.nextDownloadWindow++
1515 if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
1516 if sectionNumber != oFsm.omciDownloadWindowSizeLast {
1517 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error last window - later: repeat window once?", //TODO!!!
1518 log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
1519 "expected section": oFsm.omciDownloadWindowSizeLast})
1520 oFsm.mutexUpgradeParams.Unlock()
1521 oFsm.abortOnOmciError(ctx, false)
1522 return
1523 }
1524 oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
1525 //CRC computation for all data bytes of the file
1526 imageCRC := crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //store internal for multiple usage
1527 //revert the retrieved CRC Byte Order (seems not to deliver NetworkByteOrder)
1528 var byteSlice []byte = make([]byte, 4)
1529 binary.LittleEndian.PutUint32(byteSlice, uint32(imageCRC))
1530 oFsm.imageCRC = binary.BigEndian.Uint32(byteSlice)
1531 oFsm.mutexUpgradeParams.Unlock()
1532 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvEndSwDownload)
1533 return
1534 }
1535 if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
1536 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
1537 log.Fields{"device-id": oFsm.deviceID, "actual-section": sectionNumber,
1538 "expected section": oFsm.omciDownloadWindowSizeLimit})
1539 oFsm.mutexUpgradeParams.Unlock()
1540 oFsm.abortOnOmciError(ctx, false)
1541 return
1542 }
1543 oFsm.nextDownloadSectionsWindow = 0
1544 oFsm.mutexUpgradeParams.Unlock()
1545 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvContinueNextWindow)
1546 return
1547 }
1548 oFsm.mutexUpgradeParams.Unlock()
1549 logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
1550 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1551 oFsm.abortOnOmciError(ctx, false)
1552} //handleRxSwSectionResponse
1553
1554func (oFsm *OnuUpgradeFsm) handleRxEndSwDownloadResponse(ctx context.Context, msg cmn.OmciMessage) {
1555 inAbortingState := oFsm.PAdaptFsm.PFsm.Is(UpgradeStAbortingDL)
1556
1557 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
1558 if msgLayer == nil {
1559 logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
1560 log.Fields{"device-id": oFsm.deviceID})
1561 if !inAbortingState {
1562 oFsm.abortOnOmciError(ctx, false)
1563 } //else using error log and wait for another response or 'aborting' state timeout
1564 return
1565 }
1566 msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
1567 if !msgOk {
1568 logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
1569 log.Fields{"device-id": oFsm.deviceID})
1570 if !inAbortingState {
1571 oFsm.abortOnOmciError(ctx, false)
1572 } //else using error log and wait for another response or 'aborting' state timeout
1573 return
1574 }
1575 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
1576 "device-id": oFsm.deviceID, "data-fields": msgObj})
1577 if msgObj.Result != me.Success {
1578 if msgObj.Result == me.DeviceBusy {
1579 //ONU indicates it is still processing the image - let the FSM just wait and then repeat the request
1580 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse busy: waiting before sending new request", log.Fields{
1581 "device-id": oFsm.deviceID})
1582 if inAbortingState {
1583 //if the EndSwDl was requested from state AbortingDL then use channel to indicate ONU busy/repeat indication
1584 oFsm.chReceiveAbortEndSwDlResponse <- cEndSwDlResponseBusy //repeat abort request
1585 }
mpagenko45586762021-10-01 08:30:22 +00001586 return
1587 }
mpagenko45586762021-10-01 08:30:22 +00001588 if inAbortingState {
1589 //if the EndSwDl was requested from state AbortingDL and response is error indication
mpagenkoa2b288f2021-10-21 11:25:27 +00001590 // that would be quite strange ONU behavior, no resolution from OnuAdapter, just let the FSM go on to disabled
1591 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - aborting anyway",
1592 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1593 oFsm.chReceiveAbortEndSwDlResponse <- cEndSwDlResponseAbort //error indication to stop waiting on EndDownloadResponse(abort)
1594 return
1595 }
1596 //else: ONU rejects the previous download, complete upgrade is immediately aborted with error
1597 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - abort upgrade",
1598 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1599 oFsm.mutexUpgradeParams.Lock()
1600 oFsm.conditionalCancelRequested = false //any conditional cancelRequest is superseded by this abortion
1601 oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
1602 oFsm.mutexUpgradeParams.Unlock()
1603 select {
1604 case oFsm.chOnuDlReady <- false:
1605 default:
1606 }
1607 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
mpagenko45586762021-10-01 08:30:22 +00001608 return
1609 }
1610 oFsm.mutexUpgradeParams.Lock()
1611 if msgObj.EntityInstance == oFsm.InactiveImageMeID {
1612 logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenko45586762021-10-01 08:30:22 +00001613 if inAbortingState {
1614 oFsm.mutexUpgradeParams.Unlock()
1615 //if the EndSwDl was requested from state AbortingDL then use channel to indicate abort acceptance
1616 oFsm.chReceiveAbortEndSwDlResponse <- cEndSwDlResponseSuccess //success
1617 return
1618 }
1619 if !oFsm.useAPIVersion43 {
1620 //in the older API version the image version check was not possible
1621 // - assume new loaded image as valid-inactive immediately
1622 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1623 oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE
1624 oFsm.mutexUpgradeParams.Unlock()
mpagenkoa2b288f2021-10-21 11:25:27 +00001625 //use non-blocking channel (to be independent from receiver state) to indicate that the download to ONU was successful
mpagenko45586762021-10-01 08:30:22 +00001626 select {
mpagenko45586762021-10-01 08:30:22 +00001627 case oFsm.chOnuDlReady <- true:
1628 default:
1629 }
1630 } else {
1631 oFsm.mutexUpgradeParams.Unlock()
1632 }
1633 //use asynchronous channel sending to let the FSM proceed
1634 select {
1635 case oFsm.chReceiveExpectedResponse <- true:
1636 default:
1637 }
1638 return
1639 }
1640 oFsm.mutexUpgradeParams.Unlock()
1641 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: ignoring",
1642 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1643 // no state abort in case of unexpected ImageId, just keep waiting for the correct one
1644} //handleRxEndSwDownloadResponse
1645
1646func (oFsm *OnuUpgradeFsm) handleRxSwGetResponse(ctx context.Context, msg cmn.OmciMessage) {
1647 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
1648 if msgLayer == nil {
1649 logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
1650 log.Fields{"device-id": oFsm.deviceID})
1651 oFsm.abortOnOmciError(ctx, false)
1652 return
1653 }
1654 msgObj, msgOk := msgLayer.(*omci.GetResponse)
1655 if !msgOk {
1656 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
1657 log.Fields{"device-id": oFsm.deviceID})
1658 oFsm.abortOnOmciError(ctx, false)
1659 return
1660 }
Akash Sonif80a6e62024-12-11 10:48:53 +05301661 if msgObj.EntityClass != me.SoftwareImageClassID {
1662 logger.Errorw(ctx, "Class id mismatch for software image upgrade",
1663 log.Fields{"device-id": oFsm.deviceID, "received ClassId": msgObj.EntityClass, "expected ClassId": me.SoftwareImageClassID})
1664 oFsm.abortOnOmciError(ctx, false)
1665 return
1666 }
mpagenko45586762021-10-01 08:30:22 +00001667 logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
1668 "device-id": oFsm.deviceID, "data-fields": msgObj})
1669 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1670 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1671 if msgObj.Result != me.Success {
1672 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
1673 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1674 oFsm.abortOnOmciError(ctx, false)
1675 return
1676 }
1677 } else {
1678 logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
1679 log.Fields{"device-id": oFsm.deviceID})
1680 return
1681 }
mpagenko45586762021-10-01 08:30:22 +00001682 meAttributes := msgObj.Attributes
Holger Hildebrandtfdb4bba2022-03-10 12:12:59 +00001683 var imageVersion string
1684 var imageIsCommitted, imageIsActive uint8
mpagenko45586762021-10-01 08:30:22 +00001685
Holger Hildebrandtfdb4bba2022-03-10 12:12:59 +00001686 if softwareImageIsCommitted, ok := meAttributes[me.SoftwareImage_IsCommitted]; ok {
1687 if softwareImageIsActiveimage, ok := meAttributes[me.SoftwareImage_IsActive]; ok {
1688 if softwareImageVersion, ok := meAttributes[me.SoftwareImage_Version]; ok {
1689 imageIsCommitted = softwareImageIsCommitted.(uint8)
1690 imageIsActive = softwareImageIsActiveimage.(uint8)
1691 imageVersion = cmn.TrimStringFromMeOctet(softwareImageVersion)
1692 logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
1693 log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
1694 "version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
1695 } else {
1696 logger.Errorw(ctx,
1697 "OnuUpgradeFsm - Not all mandatory attributes present in in SoftwareImage instance - handling stopped!",
1698 log.Fields{"device-id": oFsm.deviceID})
1699 oFsm.abortOnOmciError(ctx, false)
1700 return
1701 }
1702 }
1703 }
mpagenko45586762021-10-01 08:30:22 +00001704 if oFsm.PAdaptFsm.PFsm.Current() == UpgradeStCheckImageName {
1705 //image name check after EndSwDownload, this state (and block) can only be taken if APIVersion43 is used
1706 oFsm.verifyOnuSwStatusAfterDownload(ctx, msgObj.EntityInstance, imageVersion, imageIsActive, imageIsCommitted)
1707 return
1708 }
1709
1710 //assumed only relevant state here is upgradeStCheckCommitted
1711 oFsm.mutexUpgradeParams.Lock()
1712 oFsm.conditionalCancelRequested = false //getting here any set (conditional) cancelRequest is not relevant anymore
1713 if msgObj.EntityInstance == oFsm.InactiveImageMeID && imageIsActive == cmn.SwIsActive {
1714 //a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
1715 // indicated in the download image version string (version must be part of the image content itself)
1716 // so checking that might be quite unreliable
1717 //but with new API this was changed, assumption is that omci image version is known at download request and exactly that is used
1718 // in all the API references, so it can and should be checked here now
1719 if oFsm.useAPIVersion43 {
1720 if imageVersion != oFsm.imageVersion {
1721 //new active version indicated on OMCI from ONU is not the expected version
1722 logger.Errorw(ctx, "OnuUpgradeFsm image-version not matching the requested upgrade",
1723 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance,
1724 "onu-version": imageVersion, "expected-version": oFsm.imageVersion})
1725 // TODO!!!: error treatment?
1726 //TODO!!!: possibly send event information for aborted upgrade (aborted by wrong version)?
1727 oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE //something like 'UNEXPECTED_VERSION' would be better - proto def
1728 oFsm.mutexUpgradeParams.Unlock()
1729 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
1730 return
1731 }
1732 logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU",
1733 log.Fields{"device-id": oFsm.deviceID})
1734 }
1735 if imageIsCommitted == cmn.SwIsCommitted {
1736 oFsm.upgradePhase = cUpgradeCommitted
1737 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTED
1738 //store the new commit flag to onuSwImageIndications (to keep them in sync)
1739 oFsm.pDevEntry.ModifySwImageActiveCommit(ctx, imageIsCommitted)
1740 logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
1741 //deviceProcStatusUpdate not used anymore,
1742 // replaced by transferring the last (more) upgrade state information within removeOnuUpgradeFsm
1743 oFsm.mutexUpgradeParams.Unlock()
1744 //releasing the upgrade FSM on success
1745 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
1746 return
1747 }
1748 //if not committed, abort upgrade as failed. There is no implementation here that would trigger this test again
1749 }
1750 oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
1751 oFsm.mutexUpgradeParams.Unlock()
1752 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1753 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1754 // TODO!!!: error treatment?
1755 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1756 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
1757} //handleRxSwGetResponse
1758
1759func (oFsm *OnuUpgradeFsm) verifyOnuSwStatusAfterDownload(ctx context.Context, aInstanceID uint16,
1760 aImageVersion string, aImageIsActive uint8, aImageIsCommitted uint8) {
1761 oFsm.mutexUpgradeParams.Lock()
1762 if aInstanceID == oFsm.InactiveImageMeID && aImageIsActive == cmn.SwIsInactive &&
1763 aImageIsCommitted == cmn.SwIsUncommitted {
1764 if aImageVersion != oFsm.imageVersion {
1765 //new stored inactive version indicated on OMCI from ONU is not the expected version
1766 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse version indication not matching requested upgrade",
1767 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": aInstanceID,
1768 "onu-version": aImageVersion, "expected-version": oFsm.imageVersion})
1769 //download state is set when entering the reset state
1770 oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE //something like 'UNEXPECTED_VERSION' would be better - proto def
1771 oFsm.mutexUpgradeParams.Unlock()
1772 //stop the running ONU download timer
1773 //use non-blocking channel (to be independent from receiver state)
1774 select {
1775 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
1776 case oFsm.chOnuDlReady <- false:
1777 default:
1778 }
1779 // TODO!!!: error treatment?
1780 //TODO!!!: possibly send event information for aborted upgrade (aborted by wrong version)?
1781 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
1782 return
1783 }
1784 //with APIVersion43 this is the point to consider the newly loaded image as valid (and inactive)
1785 oFsm.upgradePhase = cUpgradeDownloaded
1786 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1787 oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE
1788 //store the new inactive version to onuSwImageIndications (to keep them in sync)
1789 oFsm.pDevEntry.ModifySwImageInactiveVersion(ctx, oFsm.imageVersion)
1790 //proceed within upgrade FSM
1791 if oFsm.activateImage {
1792 //immediate activation requested
1793 oFsm.mutexUpgradeParams.Unlock()
1794 logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU, continue with activation",
1795 log.Fields{"device-id": oFsm.deviceID})
1796 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvRequestActivate)
1797 } else {
1798 //have to wait on explicit activation request
1799 oFsm.mutexUpgradeParams.Unlock()
1800 logger.Infow(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU, wait for activate request",
1801 log.Fields{"device-id": oFsm.deviceID})
1802 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvWaitForActivate)
1803 }
1804 //use non-blocking channel (to be independent from receiver state)
1805 select {
1806 //use non-blocking channel to indicate that the download to ONU was successful
1807 case oFsm.chOnuDlReady <- true:
1808 default:
1809 }
1810 return
1811 }
1812 //not the expected image/image state
1813 oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
1814 oFsm.mutexUpgradeParams.Unlock()
1815 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1816 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": aInstanceID})
1817 // TODO!!!: error treatment?
1818 //TODO!!!: possibly send event information for aborted upgrade (aborted by ONU state indication)?
1819 _ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
1820} //verifyOnuSwStatusAfterDownload
1821
Joey Armstrong89c812c2024-01-12 19:00:20 -05001822// abortOnOmciError aborts the upgrade processing with evAbort
1823//
1824// asynchronous/synchronous based on parameter aAsync
mpagenko45586762021-10-01 08:30:22 +00001825func (oFsm *OnuUpgradeFsm) abortOnOmciError(ctx context.Context, aAsync bool) {
mpagenko38662d02021-08-11 09:45:19 +00001826 oFsm.mutexUpgradeParams.Lock()
1827 oFsm.conditionalCancelRequested = false //any conditional cancelRequest is superseded by this abortion
mpagenko38662d02021-08-11 09:45:19 +00001828 oFsm.volthaDownloadReason = voltha.ImageState_OMCI_TRANSFER_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001829 oFsm.mutexUpgradeParams.Unlock()
1830 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001831 if oFsm.PAdaptFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001832 var err error
1833 if aAsync { //asynchronous call requested to ensure state transition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001834 go func(a_pAFsm *cmn.AdapterFsm) {
1835 if a_pAFsm.PFsm != nil {
1836 err = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
mpagenko38662d02021-08-11 09:45:19 +00001837 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838 }(oFsm.PAdaptFsm)
mpagenko38662d02021-08-11 09:45:19 +00001839 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001840 if oFsm.PAdaptFsm.PFsm != nil {
1841 err = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
mpagenko38662d02021-08-11 09:45:19 +00001842 }
1843 }
1844 if err != nil {
1845 logger.Warnw(ctx, "onu upgrade fsm could not abort on omci error", log.Fields{
1846 "device-id": oFsm.deviceID, "error": err})
1847 }
1848 }
1849}
1850
Joey Armstrong89c812c2024-01-12 19:00:20 -05001851// waitOnDownloadToAdapterReady state can only be reached with useAPIVersion43 (usage of pFileManager)
1852//
1853// precondition: mutexIsAwaitingAdapterDlResponse is lockek on call
mpagenko38662d02021-08-11 09:45:19 +00001854func (oFsm *OnuUpgradeFsm) waitOnDownloadToAdapterReady(ctx context.Context, aSyncChannel chan<- struct{},
1855 aWaitChannel chan bool) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001856 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
mpagenko38662d02021-08-11 09:45:19 +00001857 downloadToAdapterTimeout := oFsm.pFileManager.GetDownloadTimeout(ctx)
mpagenkoc26d4c02021-05-06 14:27:57 +00001858 oFsm.isWaitingForAdapterDlResponse = true
1859 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001860 aSyncChannel <- struct{}{}
mpagenko80622a52021-02-09 16:53:23 +00001861 select {
1862 // maybe be also some outside cancel (but no context modeled for the moment ...)
1863 // case <-ctx.Done():
mpagenkoc26d4c02021-05-06 14:27:57 +00001864 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToAdapterReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1865 case <-time.After(downloadToAdapterTimeout): //10s should be enough for downloading some image to the adapter
1866 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-adapter-download timeout", log.Fields{
1867 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToAdapterTimeout})
1868 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
mpagenko39b703e2021-08-25 13:38:40 +00001869 //running into timeout here may still have the download to adapter active -> abort
1870 oFsm.pFileManager.CancelDownload(ctx, oFsm.imageIdentifier)
mpagenkoc26d4c02021-05-06 14:27:57 +00001871 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1872 oFsm.isWaitingForAdapterDlResponse = false
1873 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
mpagenko39b703e2021-08-25 13:38:40 +00001874 oFsm.mutexUpgradeParams.Lock()
mpagenko45586762021-10-01 08:30:22 +00001875 oFsm.conditionalCancelRequested = false //any conditional cancelRequest is superseded by this abortion
mpagenko39b703e2021-08-25 13:38:40 +00001876 oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'DOWNLOAD_TO_ADAPTER_TIMEOUT' would be better (proto)
mpagenko39b703e2021-08-25 13:38:40 +00001877 oFsm.mutexUpgradeParams.Unlock()
1878 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001879 if oFsm.PAdaptFsm != nil && oFsm.PAdaptFsm.PFsm != nil {
1880 err := oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
mpagenko39b703e2021-08-25 13:38:40 +00001881 if err != nil {
1882 logger.Warnw(ctx, "onu upgrade fsm could not abort on omci error", log.Fields{
1883 "device-id": oFsm.deviceID, "error": err})
1884 }
1885 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001886 return
1887
1888 case success := <-aWaitChannel:
1889 if success {
1890 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded received", log.Fields{"device-id": oFsm.deviceID})
1891 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1892 oFsm.isWaitingForAdapterDlResponse = false
1893 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1894 //let the upgrade process proceed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001895 pUpgradeFsm := oFsm.PAdaptFsm
mpagenkoc26d4c02021-05-06 14:27:57 +00001896 if pUpgradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001897 _ = pUpgradeFsm.PFsm.Event(UpgradeEvPrepareSwDownload)
mpagenkoc26d4c02021-05-06 14:27:57 +00001898 } else {
1899 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1900 }
1901 return
1902 }
mpagenko39b703e2021-08-25 13:38:40 +00001903 // waiting was aborted (assumed here to be caused by
1904 // error detection or cancel at download after upgrade FSM reset/abort with according image states set there)
mpagenkoc26d4c02021-05-06 14:27:57 +00001905 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-adapter-download aborted", log.Fields{"device-id": oFsm.deviceID})
1906 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
1907 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1908 oFsm.isWaitingForAdapterDlResponse = false
1909 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001910 return
mpagenko80622a52021-02-09 16:53:23 +00001911 }
1912}
mpagenkoc26d4c02021-05-06 14:27:57 +00001913
Joey Armstrong89c812c2024-01-12 19:00:20 -05001914// waitOnDownloadToOnuReady state can only be reached with useAPIVersion43 (usage of pFileManager)
mpagenkoc26d4c02021-05-06 14:27:57 +00001915func (oFsm *OnuUpgradeFsm) waitOnDownloadToOnuReady(ctx context.Context, aWaitChannel chan bool) {
1916 downloadToOnuTimeout := time.Duration(1+(oFsm.imageLength/0x400000)) * oFsm.downloadToOnuTimeout4MB
1917 logger.Debugw(ctx, "OnuUpgradeFsm start download-to-ONU timer", log.Fields{"device-id": oFsm.deviceID,
1918 "duration": downloadToOnuTimeout})
mpagenkoc26d4c02021-05-06 14:27:57 +00001919 select {
1920 // maybe be also some outside cancel (but no context modeled for the moment ...)
1921 // case <-ctx.Done():
1922 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToOnuReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1923 case <-time.After(downloadToOnuTimeout): //using an image-size depending timout (in minutes)
1924 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-ONU-download timeout", log.Fields{
1925 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToOnuTimeout})
mpagenkoc26d4c02021-05-06 14:27:57 +00001926 //the upgrade process has to be aborted
mpagenko45586762021-10-01 08:30:22 +00001927 oFsm.abortOnOmciError(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001928 return
1929
1930 case success := <-aWaitChannel:
1931 if success {
1932 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded on ONU received", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001933 //all fine, let the FSM proceed like defined from the sender of this event
1934 return
1935 }
1936 // waiting was aborted (assumed here to be caused by
mpagenko39b703e2021-08-25 13:38:40 +00001937 // error detection or cancel at download after upgrade FSM reset/abort with according image states set there)
mpagenkoc26d4c02021-05-06 14:27:57 +00001938 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-ONU-download aborted", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001939 return
1940 }
1941}
mpagenko45586762021-10-01 08:30:22 +00001942
Joey Armstrong89c812c2024-01-12 19:00:20 -05001943// waitOnAbortEndSwDlResponse waits for either abort/success or timeout of EndSwDownload (for abortion)
mpagenkoa2b288f2021-10-21 11:25:27 +00001944func (oFsm *OnuUpgradeFsm) waitOnAbortEndSwDlResponse(ctx context.Context) {
1945 logger.Debugw(ctx, "OnuUpgradeFsm start wait for EndSwDl response (abort)", log.Fields{"device-id": oFsm.deviceID})
1946 select {
1947 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
1948 logger.Warnw(ctx, "OnuUpgradeFsm aborting download: timeout - no response received", log.Fields{"device-id": oFsm.deviceID})
1949 pUpgradeFsm := oFsm.PAdaptFsm
1950 if pUpgradeFsm != nil {
1951 _ = pUpgradeFsm.PFsm.Event(UpgradeEvRestart)
1952 } else {
1953 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1954 }
1955 return
1956 case response := <-oFsm.chReceiveAbortEndSwDlResponse:
1957 logger.Debugw(ctx, "OnuUpgradeFsm aborting download: response received",
1958 log.Fields{"device-id": oFsm.deviceID, "response": response})
1959 pUpgradeFsm := oFsm.PAdaptFsm
1960 if pUpgradeFsm != nil {
1961 if oFsm.abortingDlEvaluateResponse(ctx, pUpgradeFsm, response) {
1962 return //event sent from function already
1963 }
1964 _ = pUpgradeFsm.PFsm.Event(UpgradeEvRestart)
1965 } else {
1966 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1967 }
1968 return
1969 } //select
1970}
1971
Joey Armstrong89c812c2024-01-12 19:00:20 -05001972// stateUpdateOnReset writes the download and/or image state on entering the reset state according to FSM internal indications
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301973//
1974//nolint:unparam
mpagenko45586762021-10-01 08:30:22 +00001975func (oFsm *OnuUpgradeFsm) stateUpdateOnReset(ctx context.Context) {
1976 oFsm.mutexUpgradeParams.Lock()
1977 defer oFsm.mutexUpgradeParams.Unlock()
1978 if !oFsm.conditionalCancelRequested {
1979 switch oFsm.upgradePhase {
1980 case cUpgradeUndefined, cUpgradeDownloading: //coming from downloading
1981 //make sure the download state is only changed in case the device has still been downloading
1982 if oFsm.volthaDownloadReason == voltha.ImageState_CANCELLED_ON_REQUEST {
1983 // indication for termination on request
1984 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1985 } else if oFsm.volthaDownloadReason != voltha.ImageState_NO_ERROR {
1986 // indication for termination on failure
1987 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
1988 }
1989 //reset the image state from Downloading in this case
Balaji Seenivasana52fb0c2024-12-18 07:50:42 +05301990 oFsm.volthaImageState = voltha.ImageState_IMAGE_DOWNLOADING_ABORTED
mpagenko45586762021-10-01 08:30:22 +00001991 //in all other upgrade phases the last set download state remains valid
1992 case cUpgradeActivating:
1993 //reset the image state from Activating in this case
1994 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVATION_ABORTED
1995 case cUpgradeCommitting: // indication for request to abort waiting for response
1996 //reset the image state from Activating in this case
1997 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
1998 //default: in all other upgrade phases keep the last set imageState
1999 } //switch
2000 } else {
2001 //when reaching reset state with conditional cancel that can only result from ONU related problems
2002 // (mostly ONU down indication) - derived from resetFsms call
2003 // and it can only be related to the downloading-to-ONU phase (no need to check that additionally)
2004 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
2005 oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
2006 //reset the image state from Downloading in this case
Balaji Seenivasana52fb0c2024-12-18 07:50:42 +05302007 oFsm.volthaImageState = voltha.ImageState_IMAGE_DOWNLOADING_ABORTED
mpagenko45586762021-10-01 08:30:22 +00002008 }
2009}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00002010
2011// PrepareForGarbageCollection - remove references to prepare for garbage collection
2012func (oFsm *OnuUpgradeFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
2013 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
2014 oFsm.pDeviceHandler = nil
2015 oFsm.pDownloadManager = nil
2016 oFsm.pFileManager = nil
2017 oFsm.pDevEntry = nil
2018 oFsm.pOmciCC = nil
2019}