blob: b21291f05cf29123c54e22de5b3889bd42967db5 [file] [log] [blame]
mpagenko80622a52021-02-09 16:53:23 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
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"
30 "github.com/opencord/omci-lib-go"
31 me "github.com/opencord/omci-lib-go/generated"
32 "github.com/opencord/voltha-lib-go/v4/pkg/log"
33 "github.com/opencord/voltha-protos/v4/go/voltha"
34)
35
36const cMaxUint32 = ^uint32(0)
37
38const (
39 // internal predefined values - some off them should later be configurable (perhaps with theses as defaults)
40 cOmciDownloadSectionSize = 31 //in bytes
41 cOmciDownloadWindowSizeLimit = 31 //in sections for window offset (windowSize(32)-1)
42 //cOmciDownloadWindowRetryMax = 2 // max attempts for a specific window
mpagenkoc26d4c02021-05-06 14:27:57 +000043 cOmciSectionInterleaveMilliseconds = 0 //DownloadSection interleave time in milliseconds (0 for no delay)
44 cOmciEndSwDlDelaySeconds = 1 //End Software Download delay after last section (may be also configurable?)
45 cWaitCountEndSwDl = 6 //maximum number of EndSwDl requests
46 cWaitDelayEndSwDlSeconds = 10 //duration, how long is waited before next request on EndSwDl
mpagenko80622a52021-02-09 16:53:23 +000047 //cOmciDownloadCompleteTimeout = 5400 //in s for the complete timeout (may be better scale to image size/ noOfWindows)
48)
49
50const (
51 // events of config PON ANI port FSM
52 upgradeEvStart = "upgradeEvStart"
mpagenkoc26d4c02021-05-06 14:27:57 +000053 upgradeEvAdapterDownload = "upgradeEvAdapterDownload"
mpagenko80622a52021-02-09 16:53:23 +000054 upgradeEvPrepareSwDownload = "upgradeEvPrepareSwDownload"
55 upgradeEvRxStartSwDownload = "upgradeEvRxStartSwDownload"
56 upgradeEvWaitWindowAck = "upgradeEvWaitWindowAck"
57 upgradeEvContinueNextWindow = "upgradeEvContinueNextWindow"
58 upgradeEvEndSwDownload = "upgradeEvEndSwDownload"
mpagenko59498c12021-03-18 14:15:15 +000059 upgradeEvWaitEndDownload = "upgradeEvWaitEndDownload"
60 upgradeEvContinueFinalize = "upgradeEvContinueFinalize"
mpagenkoc26d4c02021-05-06 14:27:57 +000061 upgradeEvWaitForActivate = "upgradeEvWaitForActivate"
mpagenko80622a52021-02-09 16:53:23 +000062 upgradeEvRequestActivate = "upgradeEvRequestActivate"
mpagenko183647c2021-06-08 15:25:04 +000063 upgradeEvActivationDone = "upgradeEvActivationDone"
mpagenko80622a52021-02-09 16:53:23 +000064 upgradeEvWaitForCommit = "upgradeEvWaitForCommit"
65 upgradeEvCommitSw = "upgradeEvCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000066 upgradeEvCheckCommitted = "upgradeEvCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000067
68 //upgradeEvTimeoutSimple = "upgradeEvTimeoutSimple"
69 //upgradeEvTimeoutMids = "upgradeEvTimeoutMids"
70 upgradeEvReset = "upgradeEvReset"
71 upgradeEvAbort = "upgradeEvAbort"
72 upgradeEvRestart = "upgradeEvRestart"
73)
74
75const (
76 // states of config PON ANI port FSM
77 upgradeStDisabled = "upgradeStDisabled"
78 upgradeStStarting = "upgradeStStarting"
mpagenkoc26d4c02021-05-06 14:27:57 +000079 upgradeStWaitingAdapterDL = "upgradeStWaitingAdapterDL"
mpagenko80622a52021-02-09 16:53:23 +000080 upgradeStPreparingDL = "upgradeStPreparingDL"
81 upgradeStDLSection = "upgradeStDLSection"
82 upgradeStVerifyWindow = "upgradeStVerifyWindow"
83 upgradeStFinalizeDL = "upgradeStFinalizeDL"
mpagenko59498c12021-03-18 14:15:15 +000084 upgradeStWaitEndDL = "upgradeStWaitEndDL"
mpagenkoc26d4c02021-05-06 14:27:57 +000085 upgradeStWaitForActivate = "upgradeStWaitForActivate"
mpagenko80622a52021-02-09 16:53:23 +000086 upgradeStRequestingActivate = "upgradeStRequestingActivate"
mpagenko183647c2021-06-08 15:25:04 +000087 upgradeStActivated = "upgradeStActivated"
mpagenko80622a52021-02-09 16:53:23 +000088 upgradeStWaitForCommit = "upgradeStWaitForCommit"
89 upgradeStCommitSw = "upgradeStCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000090 upgradeStCheckCommitted = "upgradeStCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000091 upgradeStResetting = "upgradeStResetting"
92)
93
94//required definition for IdleState detection for activities on OMCI
95const cOnuUpgradeFsmIdleState = upgradeStWaitForCommit
96
97//OnuUpgradeFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
98type OnuUpgradeFsm struct {
99 pDeviceHandler *deviceHandler
100 pDownloadManager *adapterDownloadManager
mpagenkoc26d4c02021-05-06 14:27:57 +0000101 pFileManager *fileDownloadManager //used from R2.8 with new API version
mpagenko80622a52021-02-09 16:53:23 +0000102 deviceID string
mpagenko15ff4a52021-03-02 10:09:20 +0000103 pOnuOmciDevice *OnuDeviceEntry
mpagenko80622a52021-02-09 16:53:23 +0000104 pOmciCC *omciCC
105 pOnuDB *onuDeviceDB
106 requestEvent OnuDeviceEvent
107 //omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
mpagenkoc26d4c02021-05-06 14:27:57 +0000108 pAdaptFsm *AdapterFsm
109 pImageDsc *voltha.ImageDownload
110 imageBuffer []byte
111 origImageLength uint32 //as also limited by OMCI
112 imageCRC uint32 //as per OMCI - ITU I.363.5 crc
113 imageLength uint32 //including last bytes padding
114 omciDownloadWindowSizeLimit uint8 //windowSize-1 in sections
115 omciDownloadWindowSizeLast uint8 //number of sections in last window
116 noOfSections uint32 //uint32 range for sections should be sufficient for very long images
117 nextDownloadSectionsAbsolute uint32 //number of next section to download in overall image
118 nextDownloadSectionsWindow uint8 //number of next section to download within current window
119 noOfWindows uint32 //uint32 range for windows should be sufficient for very long images
120 nextDownloadWindow uint32 //number of next window to download
121 inactiveImageMeID uint16 //ME-ID of the inactive image
122 downloadToOnuTimeout4MB time.Duration //timeout for downloading the image to the ONU for a 4MB image slice
123 omciSectionInterleaveDelay time.Duration //DownloadSectionInterleave delay in milliseconds
124 delayEndSwDl bool //flag to provide a delay between last section and EndSwDl
125 pLastTxMeInstance *me.ManagedEntity
126 waitCountEndSwDl uint8 //number, how often is waited for EndSwDl at maximum
127 waitDelayEndSwDl time.Duration //duration, how long is waited before next request on EndSwDl
128 chReceiveExpectedResponse chan bool
mpagenkoaa3afe92021-05-21 16:20:58 +0000129 useAPIVersion43 bool //flag for indication on which API version is used (and accordingly which specific methods)
130 mutexUpgradeParams sync.RWMutex //mutex to protect members for parallel function requests and omci response processing
131 imageVersion string //name of the image as used within OMCI (and on extrenal API interface)
132 imageIdentifier string //name of the image as used in the adapter
mpagenkoc26d4c02021-05-06 14:27:57 +0000133 mutexIsAwaitingAdapterDlResponse sync.RWMutex
134 chAdapterDlReady chan bool
135 isWaitingForAdapterDlResponse bool
136 mutexIsAwaitingOnuDlResponse sync.RWMutex
137 chOnuDlReady chan bool
138 isWaitingForOnuDlResponse bool
139 activateImage bool
140 commitImage bool
mpagenkoaa3afe92021-05-21 16:20:58 +0000141 volthaDownloadState voltha.ImageState_ImageDownloadState
142 volthaDownloadReason voltha.ImageState_ImageFailureReason
143 volthaImageState voltha.ImageState_ImageActivationState
mpagenko80622a52021-02-09 16:53:23 +0000144}
145
146//NewOnuUpgradeFsm is the 'constructor' for the state machine to config the PON ANI ports
147// of ONU UNI ports via OMCI
148func NewOnuUpgradeFsm(ctx context.Context, apDeviceHandler *deviceHandler,
mpagenko15ff4a52021-03-02 10:09:20 +0000149 apDevEntry *OnuDeviceEntry, apOnuDB *onuDeviceDB,
mpagenko80622a52021-02-09 16:53:23 +0000150 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message) *OnuUpgradeFsm {
151 instFsm := &OnuUpgradeFsm{
mpagenko59498c12021-03-18 14:15:15 +0000152 pDeviceHandler: apDeviceHandler,
153 deviceID: apDeviceHandler.deviceID,
154 pOnuOmciDevice: apDevEntry,
155 pOmciCC: apDevEntry.PDevOmciCC,
156 pOnuDB: apOnuDB,
157 requestEvent: aRequestEvent,
158 omciDownloadWindowSizeLimit: cOmciDownloadWindowSizeLimit,
159 omciSectionInterleaveDelay: cOmciSectionInterleaveMilliseconds,
Holger Hildebrandtac010732021-06-02 13:35:39 +0000160 downloadToOnuTimeout4MB: apDeviceHandler.pOpenOnuAc.dlToOnuTimeout4M,
mpagenko59498c12021-03-18 14:15:15 +0000161 waitCountEndSwDl: cWaitCountEndSwDl,
162 waitDelayEndSwDl: cWaitDelayEndSwDlSeconds,
mpagenkoaa3afe92021-05-21 16:20:58 +0000163 volthaDownloadState: voltha.ImageState_DOWNLOAD_STARTED, //if FSM created we can assume that the download (to adapter) really started
164 volthaDownloadReason: voltha.ImageState_NO_ERROR,
165 volthaImageState: voltha.ImageState_IMAGE_UNKNOWN,
mpagenko80622a52021-02-09 16:53:23 +0000166 }
mpagenko59498c12021-03-18 14:15:15 +0000167 instFsm.chReceiveExpectedResponse = make(chan bool)
mpagenkoc26d4c02021-05-06 14:27:57 +0000168 instFsm.chAdapterDlReady = make(chan bool)
169 instFsm.chOnuDlReady = make(chan bool)
mpagenko80622a52021-02-09 16:53:23 +0000170
171 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
172 if instFsm.pAdaptFsm == nil {
173 logger.Errorw(ctx, "OnuUpgradeFsm's AdapterFsm could not be instantiated!!", log.Fields{
174 "device-id": instFsm.deviceID})
175 return nil
176 }
177 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
178 upgradeStDisabled,
179 fsm.Events{
180 {Name: upgradeEvStart, Src: []string{upgradeStDisabled}, Dst: upgradeStStarting},
mpagenkoc26d4c02021-05-06 14:27:57 +0000181 {Name: upgradeEvAdapterDownload, Src: []string{upgradeStStarting}, Dst: upgradeStWaitingAdapterDL},
182 {Name: upgradeEvPrepareSwDownload, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL}, Dst: upgradeStPreparingDL},
mpagenko80622a52021-02-09 16:53:23 +0000183 {Name: upgradeEvRxStartSwDownload, Src: []string{upgradeStPreparingDL}, Dst: upgradeStDLSection},
184 {Name: upgradeEvWaitWindowAck, Src: []string{upgradeStDLSection}, Dst: upgradeStVerifyWindow},
185 {Name: upgradeEvContinueNextWindow, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStDLSection},
186 {Name: upgradeEvEndSwDownload, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStFinalizeDL},
mpagenko59498c12021-03-18 14:15:15 +0000187 {Name: upgradeEvWaitEndDownload, Src: []string{upgradeStFinalizeDL}, Dst: upgradeStWaitEndDL},
188 {Name: upgradeEvContinueFinalize, Src: []string{upgradeStWaitEndDL}, Dst: upgradeStFinalizeDL},
mpagenkoc26d4c02021-05-06 14:27:57 +0000189 {Name: upgradeEvWaitForActivate, Src: []string{upgradeStWaitEndDL}, Dst: upgradeStWaitForActivate},
190 {Name: upgradeEvRequestActivate, Src: []string{upgradeStStarting, upgradeStWaitEndDL, upgradeStWaitForActivate},
191 Dst: upgradeStRequestingActivate}, //allows also for direct activation (without download) [TODO!!!]
mpagenko183647c2021-06-08 15:25:04 +0000192 {Name: upgradeEvActivationDone, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStActivated},
mpagenko80622a52021-02-09 16:53:23 +0000193 {Name: upgradeEvWaitForCommit, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStWaitForCommit},
mpagenko183647c2021-06-08 15:25:04 +0000194 {Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStWaitForCommit, upgradeStActivated},
mpagenkoc26d4c02021-05-06 14:27:57 +0000195 Dst: upgradeStCommitSw}, //allows also for direct commitment (without download) [TODO!!!]
mpagenko15ff4a52021-03-02 10:09:20 +0000196 {Name: upgradeEvCheckCommitted, Src: []string{upgradeStCommitSw}, Dst: upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000197
198 /*
199 {Name: upgradeEvTimeoutSimple, Src: []string{
200 upgradeStCreatingDot1PMapper, upgradeStCreatingMBPCD, upgradeStSettingTconts, upgradeStSettingDot1PMapper}, Dst: upgradeStStarting},
201 {Name: upgradeEvTimeoutMids, Src: []string{
202 upgradeStCreatingGemNCTPs, upgradeStCreatingGemIWs, upgradeStSettingPQs}, Dst: upgradeStStarting},
203 */
204 // exceptional treatments
mpagenko183647c2021-06-08 15:25:04 +0000205 //on upgradeEvReset: upgradeStWaitForCommit and upgradeStActivated are not reset (to let the FSM survive the expected OnuDown indication)
mpagenkoc26d4c02021-05-06 14:27:57 +0000206 {Name: upgradeEvReset, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
207 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
mpagenko183647c2021-06-08 15:25:04 +0000208 upgradeStRequestingActivate, upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000209 Dst: upgradeStResetting},
mpagenkoc26d4c02021-05-06 14:27:57 +0000210 {Name: upgradeEvAbort, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
211 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
mpagenko183647c2021-06-08 15:25:04 +0000212 upgradeStRequestingActivate, upgradeStActivated, upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000213 Dst: upgradeStResetting},
214 {Name: upgradeEvRestart, Src: []string{upgradeStResetting}, Dst: upgradeStDisabled},
215 },
216 fsm.Callbacks{
217 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
218 "enter_" + upgradeStStarting: func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
mpagenkoc26d4c02021-05-06 14:27:57 +0000219 "enter_" + upgradeStWaitingAdapterDL: func(e *fsm.Event) { instFsm.enterWaitingAdapterDL(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000220 "enter_" + upgradeStPreparingDL: func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
221 "enter_" + upgradeStDLSection: func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
222 "enter_" + upgradeStVerifyWindow: func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
223 "enter_" + upgradeStFinalizeDL: func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
mpagenko59498c12021-03-18 14:15:15 +0000224 "enter_" + upgradeStWaitEndDL: func(e *fsm.Event) { instFsm.enterWaitEndDL(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000225 "enter_" + upgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
226 "enter_" + upgradeStCommitSw: func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
mpagenko15ff4a52021-03-02 10:09:20 +0000227 "enter_" + upgradeStCheckCommitted: func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000228 "enter_" + upgradeStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
229 "enter_" + upgradeStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
230 },
231 )
232 if instFsm.pAdaptFsm.pFsm == nil {
233 logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
234 "device-id": instFsm.deviceID})
235 return nil
236 }
237
238 logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
239 return instFsm
240}
241
242//SetDownloadParams configures the needed parameters for a specific download to the ONU
mpagenkoc26d4c02021-05-06 14:27:57 +0000243// called from 'old' API Activate_image_update()
mpagenko15ff4a52021-03-02 10:09:20 +0000244func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
245 apImageDsc *voltha.ImageDownload, apDownloadManager *adapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +0000246 pBaseFsm := oFsm.pAdaptFsm.pFsm
247 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000248 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000249 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
250 "device-id": oFsm.deviceID, "image-description": apImageDsc})
mpagenko15ff4a52021-03-02 10:09:20 +0000251 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenko80622a52021-02-09 16:53:23 +0000252 oFsm.pImageDsc = apImageDsc
253 oFsm.pDownloadManager = apDownloadManager
Holger Hildebrandtac1e0592021-06-03 15:16:49 +0000254 oFsm.activateImage = true
255 oFsm.commitImage = true
mpagenkoaa3afe92021-05-21 16:20:58 +0000256 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000257
258 go func(aPBaseFsm *fsm.FSM) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000259 // let the upgrade FSM proceed to PreparingDL
mpagenko80622a52021-02-09 16:53:23 +0000260 _ = aPBaseFsm.Event(upgradeEvPrepareSwDownload)
261 }(pBaseFsm)
262 return nil
263 }
264 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
265 "device-id": oFsm.deviceID})
266 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
267}
268
mpagenkoc26d4c02021-05-06 14:27:57 +0000269//SetDownloadParamsAfterDownload configures the needed parameters for a specific download to the ONU according to
270// updated API interface with R2.8: start download to ONU if the image is downloaded to the adapter
271// called from 'new' API Download_onu_image
272func (oFsm *OnuUpgradeFsm) SetDownloadParamsAfterDownload(ctx context.Context, aInactiveImageID uint16,
273 apImageRequest *voltha.DeviceImageDownloadRequest, apDownloadManager *fileDownloadManager,
Holger Hildebrandtac010732021-06-02 13:35:39 +0000274 aImageIdentifier string) error {
mpagenkoc26d4c02021-05-06 14:27:57 +0000275 oFsm.mutexUpgradeParams.Lock()
276 var pBaseFsm *fsm.FSM = nil
277 if oFsm.pAdaptFsm != nil {
278 pBaseFsm = oFsm.pAdaptFsm.pFsm
279 }
280 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
281 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
282 "device-id": oFsm.deviceID, "image-description": apImageRequest})
283 oFsm.useAPIVersion43 = true
284 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
285 oFsm.pFileManager = apDownloadManager
286 oFsm.imageIdentifier = aImageIdentifier
287 oFsm.imageVersion = apImageRequest.Image.Version
288 oFsm.activateImage = apImageRequest.ActivateOnSuccess
289 oFsm.commitImage = apImageRequest.CommitOnSuccess
mpagenkoc26d4c02021-05-06 14:27:57 +0000290 //TODO: currently straightforward options activate and commit are expected to be set and (unconditionally) done
291 // for separate handling of these options the FSM must accordingly branch from the concerned states - later
292 oFsm.mutexUpgradeParams.Unlock()
293 _ = pBaseFsm.Event(upgradeEvAdapterDownload) //no need to call the FSM event in background here
294 return nil
295 }
296 oFsm.mutexUpgradeParams.Unlock()
297 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
298 "device-id": oFsm.deviceID})
299 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
300}
301
302//SetActivationParamsRunning sets the activate and commit flags for a running download to the ONU according to adapters rpc call
303// called from 'new' API Activate_onu_image
304func (oFsm *OnuUpgradeFsm) SetActivationParamsRunning(ctx context.Context,
305 aImageIdentifier string, aCommit bool) error {
306 oFsm.mutexUpgradeParams.Lock()
307 //set activate/commit independent from state, if FSM is already beyond concerned states, then it does not matter anyway
308 // (as long as the Imageidentifier is correct)
309 logger.Debugw(ctx, "OnuUpgradeFsm activate/commit parameter setting", log.Fields{
310 "device-id": oFsm.deviceID, "image-id": aImageIdentifier, "commit": aCommit})
311 if aImageIdentifier != oFsm.imageIdentifier {
312 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
313 "device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
314 oFsm.mutexUpgradeParams.Unlock()
315 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
316 oFsm.deviceID))
317 }
318 oFsm.activateImage = true
319 oFsm.commitImage = aCommit
320 oFsm.mutexUpgradeParams.Unlock()
321 var pBaseFsm *fsm.FSM = nil
322 if oFsm.pAdaptFsm != nil {
323 pBaseFsm = oFsm.pAdaptFsm.pFsm
324 }
325 if pBaseFsm != nil {
326 if pBaseFsm.Is(upgradeStWaitForActivate) {
327 logger.Debugw(ctx, "OnuUpgradeFsm finish waiting for activate", log.Fields{"device-id": oFsm.deviceID})
328 _ = pBaseFsm.Event(upgradeEvRequestActivate) //no need to call the FSM event in background here
329 }
330 return nil
331 }
332 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
333 "device-id": oFsm.deviceID})
334 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
335}
336
337//SetActivationParamsStart starts upgrade processing with immediate activation
338// called from 'new' API Activate_onu_image
339func (oFsm *OnuUpgradeFsm) SetActivationParamsStart(ctx context.Context, aImageVersion string, aInactiveImageID uint16, aCommit bool) error {
340 oFsm.mutexUpgradeParams.Lock()
341 var pBaseFsm *fsm.FSM = nil
342 if oFsm.pAdaptFsm != nil {
343 pBaseFsm = oFsm.pAdaptFsm.pFsm
344 }
345 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
346 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with activation", log.Fields{
347 "device-id": oFsm.deviceID, "image-version": aImageVersion})
348 oFsm.useAPIVersion43 = true
349 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
350 oFsm.imageVersion = aImageVersion
351 oFsm.activateImage = true
352 oFsm.commitImage = aCommit
mpagenko183647c2021-06-08 15:25:04 +0000353 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN // this is just an activate request without prior download
mpagenkoc26d4c02021-05-06 14:27:57 +0000354 oFsm.mutexUpgradeParams.Unlock()
355 //directly request the FSM to activate the image
356 _ = pBaseFsm.Event(upgradeEvRequestActivate) //no need to call the FSM event in background here
357 return nil
358 }
359 oFsm.mutexUpgradeParams.Unlock()
360 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
361 "device-id": oFsm.deviceID})
362 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
363}
364
365//SetCommitmentParamsRunning sets the commit flag for a running download to the ONU according to adapters rpc call
366// called from 'new' API Commit_onu_image
367func (oFsm *OnuUpgradeFsm) SetCommitmentParamsRunning(ctx context.Context, aImageIdentifier string) error {
368 oFsm.mutexUpgradeParams.Lock()
369 //set commit independent from state, if FSM is already beyond commit state (just ready), then it does not matter anyway
370 // (as long as the Imageidentifier is correct)
371 logger.Debugw(ctx, "OnuUpgradeFsm commit parameter setting", log.Fields{
372 "device-id": oFsm.deviceID, "image-id": aImageIdentifier})
373 if aImageIdentifier != oFsm.imageIdentifier {
374 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
375 "device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
376 oFsm.mutexUpgradeParams.Unlock()
377 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
378 oFsm.deviceID))
379 }
380 oFsm.commitImage = true
381 oFsm.mutexUpgradeParams.Unlock()
382 var pBaseFsm *fsm.FSM = nil
383 if oFsm.pAdaptFsm != nil {
384 pBaseFsm = oFsm.pAdaptFsm.pFsm
385 }
386 if pBaseFsm != nil {
mpagenko183647c2021-06-08 15:25:04 +0000387 //let the FSM decide if it is ready to process the event
388 logger.Debugw(ctx, "OnuUpgradeFsm requesting commit",
389 log.Fields{"device-id": oFsm.deviceID, "current FsmState": pBaseFsm.Current()})
390 _ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
mpagenkoc26d4c02021-05-06 14:27:57 +0000391 return nil
392 }
393 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
394 "device-id": oFsm.deviceID})
395 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
396}
397
398//SetCommitmentParamsStart starts upgrade processing with immediate commitment
399// called from 'new' API Commit_onu_image
400func (oFsm *OnuUpgradeFsm) SetCommitmentParamsStart(ctx context.Context, aImageVersion string, aActiveImageID uint16) error {
401 oFsm.mutexUpgradeParams.Lock()
402 var pBaseFsm *fsm.FSM = nil
403 if oFsm.pAdaptFsm != nil {
404 pBaseFsm = oFsm.pAdaptFsm.pFsm
405 }
406 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
407 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with commitment", log.Fields{
408 "device-id": oFsm.deviceID, "image-version": aImageVersion})
409 oFsm.useAPIVersion43 = true
410 oFsm.inactiveImageMeID = aActiveImageID //upgrade state machines inactive ImageId is the new active ImageId
411 oFsm.imageVersion = aImageVersion
412 oFsm.commitImage = true
mpagenko183647c2021-06-08 15:25:04 +0000413 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN // this is just a commit request without prior download
mpagenkoc26d4c02021-05-06 14:27:57 +0000414 oFsm.mutexUpgradeParams.Unlock()
415 //directly request the FSM to activate the image
416 _ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
417 return nil
418 }
419 oFsm.mutexUpgradeParams.Unlock()
420 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
421 "device-id": oFsm.deviceID})
422 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
423}
424
mpagenkoaa3afe92021-05-21 16:20:58 +0000425//GetImageStates delivers the download states as per device proto buf or error indication
426func (oFsm *OnuUpgradeFsm) GetImageStates(ctx context.Context,
427 aImageIdentifier string, aVersion string) (*voltha.ImageState, error) {
428 pImageState := &voltha.ImageState{}
429 // check if the request refers to some active image/version of the processing
430 oFsm.mutexUpgradeParams.RLock()
431 if (aImageIdentifier == oFsm.imageIdentifier) || (aVersion == oFsm.imageVersion) {
432 pImageState.DownloadState = oFsm.volthaDownloadState
433 pImageState.Reason = oFsm.volthaDownloadReason
434 pImageState.ImageState = oFsm.volthaImageState
435 } else {
436 pImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
437 pImageState.Reason = voltha.ImageState_NO_ERROR
438 pImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
439 }
440 oFsm.mutexUpgradeParams.RUnlock()
441 return pImageState, nil
442}
443
mpagenko183647c2021-06-08 15:25:04 +0000444//SetImageState sets the FSM internal volthaImageState
445func (oFsm *OnuUpgradeFsm) SetImageState(ctx context.Context, aImageState voltha.ImageState_ImageActivationState) {
446 oFsm.mutexUpgradeParams.Lock()
447 defer oFsm.mutexUpgradeParams.Unlock()
448 oFsm.volthaImageState = aImageState
449}
450
mpagenkoc26d4c02021-05-06 14:27:57 +0000451//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
452func (oFsm *OnuUpgradeFsm) CancelProcessing(ctx context.Context) {
453 //mutex protection is required for possible concurrent access to FSM members
454 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
455 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
456 oFsm.mutexIsAwaitingAdapterDlResponse.RLock()
457 if oFsm.isWaitingForAdapterDlResponse {
458 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
459 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
460 oFsm.chAdapterDlReady <- false
461 } else {
462 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
463 }
464 //chOnuDlReady is cleared as part of the FSM reset processing (from enterResetting())
465
466 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
467 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
468 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
469 pAdaptFsm := oFsm.pAdaptFsm
470 if pAdaptFsm != nil {
471 // calling FSM events in background to avoid blocking of the caller
472 go func(aPAFsm *AdapterFsm) {
473 if aPAFsm.pFsm != nil {
474 if aPAFsm.pFsm.Is(upgradeStWaitEndDL) {
475 oFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
476 }
477 _ = aPAFsm.pFsm.Event(upgradeEvReset) //anyway and for all other states
478 } //else the FSM seems already to be in some released state
479 }(pAdaptFsm)
480 }
481}
482
mpagenko80622a52021-02-09 16:53:23 +0000483func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
484 logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
485 "device-id": oFsm.deviceID})
486
487 // start go routine for processing of LockState messages
488 go oFsm.processOmciUpgradeMessages(ctx)
489}
490
mpagenkoc26d4c02021-05-06 14:27:57 +0000491//enterWaitingAdapterDL state can only be reached with useAPIVersion43
492func (oFsm *OnuUpgradeFsm) enterWaitingAdapterDL(ctx context.Context, e *fsm.Event) {
493 logger.Debugw(ctx, "OnuUpgradeFsm waiting for adapter download", log.Fields{"in state": e.FSM.Current(),
494 "device-id": oFsm.deviceID})
495 go oFsm.waitOnDownloadToAdapterReady(ctx, oFsm.chAdapterDlReady)
496 go oFsm.pFileManager.RequestDownloadReady(ctx, oFsm.imageIdentifier, oFsm.chAdapterDlReady)
497}
498
mpagenko80622a52021-02-09 16:53:23 +0000499func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
500 logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
501 "device-id": oFsm.deviceID})
502
mpagenkoc26d4c02021-05-06 14:27:57 +0000503 var fileLen int64
504 var err error
mpagenkoaa3afe92021-05-21 16:20:58 +0000505 oFsm.mutexUpgradeParams.Lock()
mpagenkoc26d4c02021-05-06 14:27:57 +0000506 if oFsm.useAPIVersion43 {
507 //with the new API structure download to adapter is implicit and we have to wait until the image is available
508 fileLen, err = oFsm.pFileManager.GetImageBufferLen(ctx, oFsm.imageIdentifier)
509 } else {
510 fileLen, err = oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
511 }
mpagenko80622a52021-02-09 16:53:23 +0000512 if err != nil || fileLen > int64(cMaxUint32) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000513 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000514 logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
515 "device-id": oFsm.deviceID, "error": err, "length": fileLen})
516 pBaseFsm := oFsm.pAdaptFsm
517 // Can't call FSM Event directly, decoupling it
518 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000519 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000520 }(pBaseFsm)
521 return
522 }
523
mpagenkoc26d4c02021-05-06 14:27:57 +0000524 //copy file content to buffer
mpagenko80622a52021-02-09 16:53:23 +0000525 oFsm.imageBuffer = make([]byte, fileLen)
mpagenkoc26d4c02021-05-06 14:27:57 +0000526 if oFsm.useAPIVersion43 {
527 oFsm.imageBuffer, err = oFsm.pFileManager.GetDownloadImageBuffer(ctx, oFsm.imageIdentifier)
528 } else {
529 oFsm.imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
530 }
mpagenko80622a52021-02-09 16:53:23 +0000531 if err != nil {
mpagenkoaa3afe92021-05-21 16:20:58 +0000532 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000533 logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
534 "device-id": oFsm.deviceID, "error": err})
535 pBaseFsm := oFsm.pAdaptFsm
536 // Can't call FSM Event directly, decoupling it
537 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000538 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000539 }(pBaseFsm)
540 return
541 }
542
543 oFsm.noOfSections = uint32(fileLen / cOmciDownloadSectionSize)
544 if fileLen%cOmciDownloadSectionSize > 0 {
mpagenkoc26d4c02021-05-06 14:27:57 +0000545 bufferPadding := make([]byte, cOmciDownloadSectionSize-uint32((fileLen)%cOmciDownloadSectionSize))
mpagenko80622a52021-02-09 16:53:23 +0000546 //expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
mpagenkoc26d4c02021-05-06 14:27:57 +0000547 oFsm.imageBuffer = append(oFsm.imageBuffer[:(fileLen)], bufferPadding...)
mpagenko80622a52021-02-09 16:53:23 +0000548 oFsm.noOfSections++
549 }
550 oFsm.origImageLength = uint32(fileLen)
551 oFsm.imageLength = uint32(len(oFsm.imageBuffer))
mpagenko80622a52021-02-09 16:53:23 +0000552 logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
553 "MeId": oFsm.inactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
554 "ImageSize": oFsm.imageLength, "original file size": fileLen})
555 //"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
mpagenkoaa3afe92021-05-21 16:20:58 +0000556
557 oFsm.mutexUpgradeParams.Unlock()
558 go oFsm.waitOnDownloadToOnuReady(ctx, oFsm.chOnuDlReady) // start supervision of the complete download-to-ONU procedure
559
Girish Gowdra0b235842021-03-09 13:06:46 -0800560 err = oFsm.pOmciCC.sendStartSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000561 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength)
562 if err != nil {
563 logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
564 "device-id": oFsm.deviceID, "error": err})
565 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
566 pBaseFsm := oFsm.pAdaptFsm
567 // Can't call FSM Event directly, decoupling it
568 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000569 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000570 }(pBaseFsm)
571 return
572 }
573}
574
575func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
576 logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
577 "device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
578
579 var windowAckRequest uint8 = 0
580 var bufferStartOffset uint32
581 var bufferEndOffset uint32
582 var downloadSection []byte
583 framePrint := false //default no printing of downloadSection frames
mpagenkoaa3afe92021-05-21 16:20:58 +0000584 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000585 if oFsm.nextDownloadSectionsAbsolute == 0 {
586 //debug print of first section frame
587 framePrint = true
mpagenkoaa3afe92021-05-21 16:20:58 +0000588 oFsm.volthaImageState = voltha.ImageState_IMAGE_DOWNLOADING
mpagenko80622a52021-02-09 16:53:23 +0000589 }
590
591 for {
592 bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * cOmciDownloadSectionSize
593 bufferEndOffset = bufferStartOffset + cOmciDownloadSectionSize - 1 //for representing cOmciDownloadSectionSizeLimit values
594 logger.Debugw(ctx, "DlSection values are", log.Fields{
595 "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
596 "DlSectionWindow": oFsm.nextDownloadSectionsWindow,
597 "startOffset": bufferStartOffset, "endOffset": bufferEndOffset})
598 if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
599 logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
600 "device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
601 "bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
mpagenkoaa3afe92021-05-21 16:20:58 +0000602 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000603 //logical error -- reset the FSM
604 pBaseFsm := oFsm.pAdaptFsm
605 // Can't call FSM Event directly, decoupling it
606 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000607 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000608 }(pBaseFsm)
609 return
610 }
611 downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
612 if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
613 windowAckRequest = 1
614 logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
615 "device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
616 }
617 if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
618 windowAckRequest = 1
619 framePrint = true //debug print of last frame
mpagenko15ff4a52021-03-02 10:09:20 +0000620 oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
621 logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000622 "device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
623 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000624 oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
Girish Gowdra0b235842021-03-09 13:06:46 -0800625 err := oFsm.pOmciCC.sendDownloadSection(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000626 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, framePrint)
627 if err != nil {
628 logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
mpagenko15ff4a52021-03-02 10:09:20 +0000629 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
mpagenko80622a52021-02-09 16:53:23 +0000630 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
631 pBaseFsm := oFsm.pAdaptFsm
632 // Can't call FSM Event directly, decoupling it
633 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000634 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000635 }(pBaseFsm)
636 return
637 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000638 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000639 oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
640 if windowAckRequest == 1 {
641 pBaseFsm := oFsm.pAdaptFsm
642 // Can't call FSM Event directly, decoupling it
mpagenkoaa3afe92021-05-21 16:20:58 +0000643 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000644 go func(a_pAFsm *AdapterFsm) {
645 _ = a_pAFsm.pFsm.Event(upgradeEvWaitWindowAck) //state transition to upgradeStVerifyWindow
646 }(pBaseFsm)
647 return
648 }
649 framePrint = false //for the next Section frame (if wanted, can be enabled in logic before sendXXX())
650 oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
mpagenko59498c12021-03-18 14:15:15 +0000651 if oFsm.omciSectionInterleaveDelay > 0 {
mpagenko80622a52021-02-09 16:53:23 +0000652 //ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
mpagenkoaa3afe92021-05-21 16:20:58 +0000653 oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
mpagenko59498c12021-03-18 14:15:15 +0000654 time.Sleep(oFsm.omciSectionInterleaveDelay * time.Millisecond)
mpagenkoaa3afe92021-05-21 16:20:58 +0000655 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000656 }
657 }
658}
659
660func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
661 logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
662 "for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
663}
664
665func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
mpagenko80622a52021-02-09 16:53:23 +0000666 logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
mpagenko59498c12021-03-18 14:15:15 +0000667 "device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(oFsm.imageCRC), 16), "delay": oFsm.delayEndSwDl})
mpagenko80622a52021-02-09 16:53:23 +0000668
mpagenkoaa3afe92021-05-21 16:20:58 +0000669 oFsm.mutexUpgradeParams.RLock()
mpagenko80622a52021-02-09 16:53:23 +0000670 if oFsm.delayEndSwDl {
mpagenkoaa3afe92021-05-21 16:20:58 +0000671 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +0000672 //give the ONU some time for image evaluation (hoping it does not base that on first EndSwDl itself)
673 // should not be set in case this state is used for real download abort (not yet implemented)
674 time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
mpagenkoaa3afe92021-05-21 16:20:58 +0000675 } else {
676 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +0000677 }
678
mpagenko59498c12021-03-18 14:15:15 +0000679 pBaseFsm := oFsm.pAdaptFsm
680 if pBaseFsm == nil {
681 logger.Errorw(ctx, "EndSwDl abort: BaseFsm invalid", log.Fields{
682 "device-id": oFsm.deviceID})
683 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
684 // Can't call FSM Event directly, decoupling it
685 go func(a_pAFsm *AdapterFsm) {
686 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
687 }(pBaseFsm)
688 return
689 }
Girish Gowdra0b235842021-03-09 13:06:46 -0800690 err := oFsm.pOmciCC.sendEndSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko59498c12021-03-18 14:15:15 +0000691 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.origImageLength, oFsm.imageCRC)
mpagenko80622a52021-02-09 16:53:23 +0000692 if err != nil {
693 logger.Errorw(ctx, "EndSwDl abort: can't send section", log.Fields{
694 "device-id": oFsm.deviceID, "error": err})
695 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
mpagenko80622a52021-02-09 16:53:23 +0000696 // Can't call FSM Event directly, decoupling it
697 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000698 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000699 }(pBaseFsm)
700 return
701 }
mpagenko59498c12021-03-18 14:15:15 +0000702 // go waiting for the EndSwDLResponse and check, if the ONU is ready for activation
703 // Can't call FSM Event directly, decoupling it
704 go func(a_pAFsm *AdapterFsm) {
705 _ = a_pAFsm.pFsm.Event(upgradeEvWaitEndDownload)
706 }(pBaseFsm)
707}
708
709func (oFsm *OnuUpgradeFsm) enterWaitEndDL(ctx context.Context, e *fsm.Event) {
710 logger.Infow(ctx, "OnuUpgradeFsm WaitEndDl", log.Fields{
711 "device-id": oFsm.deviceID, "wait delay": oFsm.waitDelayEndSwDl * time.Second, "wait count": oFsm.waitCountEndSwDl})
712 if oFsm.waitCountEndSwDl == 0 {
713 logger.Errorw(ctx, "WaitEndDl abort: max limit of EndSwDL reached", log.Fields{
714 "device-id": oFsm.deviceID})
715 pBaseFsm := oFsm.pAdaptFsm
716 if pBaseFsm == nil {
717 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
718 "device-id": oFsm.deviceID})
719 return
720 }
721 go func(a_pAFsm *AdapterFsm) {
722 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
723 }(pBaseFsm)
724 return
725 }
726
727 oFsm.waitCountEndSwDl--
728 select {
729 case <-time.After(oFsm.waitDelayEndSwDl * time.Second):
730 pBaseFsm := oFsm.pAdaptFsm
731 if pBaseFsm == nil {
732 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
733 "device-id": oFsm.deviceID})
734 //FSM may be reset already from somewhere else, nothing we can do here anymore
735 return
736 }
737 //retry End SW DL
mpagenkoaa3afe92021-05-21 16:20:58 +0000738 oFsm.mutexUpgradeParams.Lock()
mpagenko59498c12021-03-18 14:15:15 +0000739 oFsm.delayEndSwDl = false //no more extra delay for the request
mpagenkoaa3afe92021-05-21 16:20:58 +0000740 oFsm.mutexUpgradeParams.Unlock()
mpagenko59498c12021-03-18 14:15:15 +0000741 go func(a_pAFsm *AdapterFsm) {
742 _ = a_pAFsm.pFsm.Event(upgradeEvContinueFinalize)
743 }(pBaseFsm)
744 return
745 case success := <-oFsm.chReceiveExpectedResponse:
746 logger.Debugw(ctx, "WaitEndDl stop wait timer", log.Fields{"device-id": oFsm.deviceID})
747 pBaseFsm := oFsm.pAdaptFsm
748 if pBaseFsm == nil {
749 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
750 "device-id": oFsm.deviceID})
751 //FSM may be reset already from somewhere else, nothing we can do here anymore
752 return
753 }
754 if success {
755 //answer received with ready indication
mpagenkoc26d4c02021-05-06 14:27:57 +0000756 if oFsm.activateImage {
757 //immediate activation requested
758 go func(a_pAFsm *AdapterFsm) {
759 _ = a_pAFsm.pFsm.Event(upgradeEvRequestActivate)
760 }(pBaseFsm)
761 } else {
762 //have to wait on explicit activation request
763 go func(a_pAFsm *AdapterFsm) {
764 _ = a_pAFsm.pFsm.Event(upgradeEvWaitForActivate)
765 }(pBaseFsm)
766 }
mpagenko59498c12021-03-18 14:15:15 +0000767 return
768 }
769 //timer was aborted
770 go func(a_pAFsm *AdapterFsm) {
771 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
772 }(pBaseFsm)
773 return
774 }
mpagenko80622a52021-02-09 16:53:23 +0000775}
776
777func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
778 logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
779 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
780
mpagenkoaa3afe92021-05-21 16:20:58 +0000781 oFsm.mutexUpgradeParams.Lock()
782 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVATING
783 oFsm.mutexUpgradeParams.Unlock()
784
Girish Gowdra0b235842021-03-09 13:06:46 -0800785 err := oFsm.pOmciCC.sendActivateSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000786 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID)
787 if err != nil {
788 logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
789 "device-id": oFsm.deviceID, "error": err})
790 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
791 pBaseFsm := oFsm.pAdaptFsm
792 // Can't call FSM Event directly, decoupling it
793 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000794 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000795 }(pBaseFsm)
796 return
797 }
798}
799
800func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
mpagenko15ff4a52021-03-02 10:09:20 +0000801 if activeImageID, err := oFsm.pOnuOmciDevice.GetActiveImageMeID(ctx); err == nil {
802 //TODO!!: as long as testing with BBSIM and BBSIM not support upgrade tests following check needs to be deactivated
803 imageFit := true //TODO!!: test workaround as long as BBSIM does not fully support upgrade
mpagenkoaa3afe92021-05-21 16:20:58 +0000804 oFsm.mutexUpgradeParams.Lock()
mpagenko15ff4a52021-03-02 10:09:20 +0000805 if imageFit || activeImageID == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +0000806 inactiveImageID := oFsm.inactiveImageMeID
mpagenko15ff4a52021-03-02 10:09:20 +0000807 logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
mpagenkoaa3afe92021-05-21 16:20:58 +0000808 "device-id": oFsm.deviceID, "me-id": inactiveImageID}) //more efficient activeImageID with above check
809 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTING
810 oFsm.mutexUpgradeParams.Unlock()
Girish Gowdra0b235842021-03-09 13:06:46 -0800811 err := oFsm.pOmciCC.sendCommitSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenkoaa3afe92021-05-21 16:20:58 +0000812 oFsm.pAdaptFsm.commChan, inactiveImageID) //more efficient activeImageID with above check
mpagenko15ff4a52021-03-02 10:09:20 +0000813 if err != nil {
814 logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
815 "device-id": oFsm.deviceID, "error": err})
816 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
817 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
818 pBaseFsm := oFsm.pAdaptFsm
819 // Can't call FSM Event directly, decoupling it
820 go func(a_pAFsm *AdapterFsm) {
821 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
822 }(pBaseFsm)
823 return
824 }
825 return
826 }
827 logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
828 "device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.inactiveImageMeID})
mpagenkoaa3afe92021-05-21 16:20:58 +0000829 oFsm.mutexUpgradeParams.Unlock()
830
mpagenko15ff4a52021-03-02 10:09:20 +0000831 //TODO!!!: possibly send event information for aborted upgrade (not activated)??
832 pBaseFsm := oFsm.pAdaptFsm
833 // Can't call FSM Event directly, decoupling it
834 go func(a_pAFsm *AdapterFsm) {
835 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
836 }(pBaseFsm)
837 return
838 }
839 logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
840 "device-id": oFsm.deviceID})
841 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
842 pBaseFsm := oFsm.pAdaptFsm
843 // Can't call FSM Event directly, decoupling it
844 go func(a_pAFsm *AdapterFsm) {
845 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
846 }(pBaseFsm)
847}
848
849func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
850 logger.Infow(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000851 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
mpagenko15ff4a52021-03-02 10:09:20 +0000852 requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
ozgecanetsiab36ed572021-04-01 10:38:48 +0300853 meInstance, err := oFsm.pOmciCC.sendGetMe(log.WithSpanFromContext(context.TODO(), ctx),
Girish Gowdra0b235842021-03-09 13:06:46 -0800854 me.SoftwareImageClassID, oFsm.inactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false, oFsm.pAdaptFsm.commChan)
mpagenko15ff4a52021-03-02 10:09:20 +0000855 //accept also nil as (error) return value for writing to LastTx
856 // - this avoids misinterpretation of new received OMCI messages
ozgecanetsiab36ed572021-04-01 10:38:48 +0300857 if err != nil {
858 logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
859 log.Fields{"device-id": oFsm.deviceID, "Error": err})
860 pOnuUpgradeFsm := oFsm.pAdaptFsm
861 if pOnuUpgradeFsm != nil {
862 go func(a_pAFsm *AdapterFsm) {
mpagenko183647c2021-06-08 15:25:04 +0000863 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300864 }(pOnuUpgradeFsm)
865 }
866 return
867 }
mpagenko15ff4a52021-03-02 10:09:20 +0000868 oFsm.pLastTxMeInstance = meInstance
mpagenko80622a52021-02-09 16:53:23 +0000869}
870
871func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
872 logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
873
mpagenkoc26d4c02021-05-06 14:27:57 +0000874 // in case the download-to-ONU timer is still running - cancel it
875 oFsm.mutexIsAwaitingOnuDlResponse.RLock()
876 if oFsm.isWaitingForOnuDlResponse {
877 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
878 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
879 oFsm.chOnuDlReady <- false
880 } else {
881 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
882 }
883
mpagenko80622a52021-02-09 16:53:23 +0000884 pConfigupgradeStateAFsm := oFsm.pAdaptFsm
885 if pConfigupgradeStateAFsm != nil {
886 // abort running message processing
887 fsmAbortMsg := Message{
888 Type: TestMsg,
889 Data: TestMessage{
890 TestMessageVal: AbortMessageProcessing,
891 },
892 }
893 pConfigupgradeStateAFsm.commChan <- fsmAbortMsg
894
895 //try to restart the FSM to 'disabled'
896 // Can't call FSM Event directly, decoupling it
897 go func(a_pAFsm *AdapterFsm) {
898 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
899 _ = a_pAFsm.pFsm.Event(upgradeEvRestart)
900 }
901 }(pConfigupgradeStateAFsm)
902 }
903}
904
905func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
906 logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +0000907 // 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 +0000908 if oFsm.pDeviceHandler != nil {
909 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
910 go oFsm.pDeviceHandler.removeOnuUpgradeFsm(ctx)
911 }
912}
913
914func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
915 logger.Debugw(ctx, "Start OnuUpgradeFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
916loop:
917 for {
918 // case <-ctx.Done():
919 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
920 // break loop
921 message, ok := <-oFsm.pAdaptFsm.commChan
922 if !ok {
923 logger.Info(ctx, "OnuUpgradeFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
924 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
mpagenko15ff4a52021-03-02 10:09:20 +0000925 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000926 break loop
927 }
928 logger.Debugw(ctx, "OnuUpgradeFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
929
930 switch message.Type {
931 case TestMsg:
932 msg, _ := message.Data.(TestMessage)
933 if msg.TestMessageVal == AbortMessageProcessing {
934 logger.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
935 break loop
936 }
937 logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
938 case OMCI:
939 msg, _ := message.Data.(OmciMessage)
940 oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
941 default:
942 logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
943 "message.Type": message.Type})
944 }
945 }
946 logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
947}
948
949//nolint: gocyclo
950func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg OmciMessage) {
951 logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
952 "msgType": msg.OmciMsg.MessageType})
953
954 switch msg.OmciMsg.MessageType {
955 case omci.StartSoftwareDownloadResponseType:
956 {
957 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
958 if msgLayer == nil {
959 logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
960 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000961 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
962 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000963 return
964 }
965 msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
966 if !msgOk {
967 logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
968 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000969 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
970 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000971 return
972 }
973 logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
974 "device-id": oFsm.deviceID, "data-fields": msgObj})
975 if msgObj.Result != me.Success {
976 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
977 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
978 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000979 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
980 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000981 return
982 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000983
984 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000985 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
986 logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
987 if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
988 // also response WindowSize = 0 is a valid number for used Window size 1
989 logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
990 "acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
991 oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
992 }
993 oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
994 if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
995 oFsm.noOfWindows++
996 }
997 logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
998 "windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
999 "at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
1000 oFsm.nextDownloadSectionsAbsolute = 0
1001 oFsm.nextDownloadSectionsWindow = 0
1002 oFsm.nextDownloadWindow = 0
1003
mpagenkoaa3afe92021-05-21 16:20:58 +00001004 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001005 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRxStartSwDownload)
1006 return
1007 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001008 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001009 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
1010 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1011 // TODO!!!: possibly repeat the start request (once)?
mpagenko15ff4a52021-03-02 10:09:20 +00001012 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1013 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001014 return
1015 } //StartSoftwareDownloadResponseType
1016 case omci.DownloadSectionResponseType:
1017 {
mpagenko80622a52021-02-09 16:53:23 +00001018 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
1019 if msgLayer == nil {
1020 logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
1021 log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
mpagenko15ff4a52021-03-02 10:09:20 +00001022 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1023 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001024 return
1025 }
1026 msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
1027 if !msgOk {
1028 logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
1029 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001030 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1031 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001032 return
1033 }
1034 logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
1035 "device-id": oFsm.deviceID, "data-fields": msgObj})
1036 if msgObj.Result != me.Success {
1037 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
1038 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko15ff4a52021-03-02 10:09:20 +00001039 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1040 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001041 return
1042 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001043 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +00001044 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
1045 sectionNumber := msgObj.SectionNumber
mpagenko15ff4a52021-03-02 10:09:20 +00001046 logger.Infow(ctx, "DlSectionResponse received", log.Fields{
1047 "window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +00001048
mpagenko15ff4a52021-03-02 10:09:20 +00001049 oFsm.nextDownloadWindow++
1050 if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
1051 if sectionNumber != oFsm.omciDownloadWindowSizeLast {
mpagenko02cf1b22021-03-12 17:30:30 +00001052 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error last window - later: repeat window once?", //TODO!!!
mpagenko15ff4a52021-03-02 10:09:20 +00001053 log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
1054 "expected section": oFsm.omciDownloadWindowSizeLast})
1055 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
mpagenkoaa3afe92021-05-21 16:20:58 +00001056 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001057 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1058 return
1059 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001060 oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
1061 //CRC computation for all data bytes of the file
1062 imageCRC := crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //store internal for multiple usage
1063 //revert the retrieved CRC Byte Order (seems not to deliver NetworkByteOrder)
1064 var byteSlice []byte = make([]byte, 4)
1065 binary.LittleEndian.PutUint32(byteSlice, uint32(imageCRC))
1066 oFsm.imageCRC = binary.BigEndian.Uint32(byteSlice)
mpagenkoaa3afe92021-05-21 16:20:58 +00001067 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001068 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvEndSwDownload)
1069 return
1070 }
1071 if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
1072 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
mpagenko02cf1b22021-03-12 17:30:30 +00001073 log.Fields{"device-id": oFsm.deviceID, "actual-section": sectionNumber,
1074 "expected section": oFsm.omciDownloadWindowSizeLimit})
mpagenkoaa3afe92021-05-21 16:20:58 +00001075 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001076 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1077 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1078 return
1079 }
1080 oFsm.nextDownloadSectionsWindow = 0
mpagenkoaa3afe92021-05-21 16:20:58 +00001081 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001082 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvContinueNextWindow)
mpagenko80622a52021-02-09 16:53:23 +00001083 return
1084 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001085 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001086 logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
1087 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +00001088 // TODO!!!: possibly repeat the download (section) (once)?
1089 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1090 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001091 return
mpagenko80622a52021-02-09 16:53:23 +00001092 } //DownloadSectionResponseType
1093 case omci.EndSoftwareDownloadResponseType:
1094 {
1095 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
1096 if msgLayer == nil {
1097 logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
1098 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001099 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1100 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001101 return
1102 }
1103 msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
1104 if !msgOk {
1105 logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
1106 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001107 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1108 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001109 return
1110 }
1111 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
1112 "device-id": oFsm.deviceID, "data-fields": msgObj})
1113 if msgObj.Result != me.Success {
mpagenko59498c12021-03-18 14:15:15 +00001114 if msgObj.Result == me.DeviceBusy {
1115 //ONU indicates it is still processing the image - let the FSM just wait and then repeat the request
1116 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse busy: waiting before sending new request", log.Fields{
1117 "device-id": oFsm.deviceID})
1118 return
1119 }
mpagenko80622a52021-02-09 16:53:23 +00001120 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - later: drive FSM to abort state ?",
1121 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1122 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +00001123 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1124 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001125 return
1126 }
mpagenko183647c2021-06-08 15:25:04 +00001127 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +00001128 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenko183647c2021-06-08 15:25:04 +00001129 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1130 oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE
1131 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001132 logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001133 oFsm.mutexIsAwaitingOnuDlResponse.RLock()
1134 if oFsm.isWaitingForOnuDlResponse {
1135 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
1136 //use channel to indicate that the download to ONU was successful
1137 oFsm.chOnuDlReady <- true
1138 } else {
1139 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
1140 }
mpagenko59498c12021-03-18 14:15:15 +00001141 oFsm.chReceiveExpectedResponse <- true //let the FSM proceed from the waitState
mpagenko80622a52021-02-09 16:53:23 +00001142 return
1143 }
mpagenko183647c2021-06-08 15:25:04 +00001144 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001145 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
1146 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1147 // TODO!!!: possibly repeat the end request (once)? or verify ONU upgrade state?
mpagenko15ff4a52021-03-02 10:09:20 +00001148 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1149 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001150 return
1151 } //EndSoftwareDownloadResponseType
1152 case omci.ActivateSoftwareResponseType:
1153 {
1154 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
1155 if msgLayer == nil {
1156 logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
1157 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001158 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1159 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001160 return
1161 }
1162 msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
1163 if !msgOk {
1164 logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
1165 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001166 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1167 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001168 return
1169 }
1170 logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
1171 "device-id": oFsm.deviceID, "data-fields": msgObj})
1172 if msgObj.Result != me.Success {
1173 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
1174 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1175 // TODO!!!: error treatment?, perhaps in the end reset the FSM
mpagenko15ff4a52021-03-02 10:09:20 +00001176 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1177 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001178 return
1179 }
mpagenko183647c2021-06-08 15:25:04 +00001180 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +00001181 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenko183647c2021-06-08 15:25:04 +00001182 oFsm.mutexUpgradeParams.Unlock()
1183 logger.Infow(ctx, "Expected ActivateSwResponse received",
1184 log.Fields{"device-id": oFsm.deviceID, "commit": oFsm.commitImage})
1185 if oFsm.commitImage {
1186 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
1187 } else {
1188 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvActivationDone) // let the FSM wait for external commit request
1189 }
mpagenko80622a52021-02-09 16:53:23 +00001190 return
1191 }
mpagenko183647c2021-06-08 15:25:04 +00001192 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001193 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
1194 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +00001195 // TODO!!!: error treatment?
1196 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1197 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001198 return
1199 } //ActivateSoftwareResponseType
mpagenko15ff4a52021-03-02 10:09:20 +00001200 case omci.CommitSoftwareResponseType:
1201 {
1202 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
1203 if msgLayer == nil {
1204 logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
1205 log.Fields{"device-id": oFsm.deviceID})
1206 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1207 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1208 return
1209 }
1210 msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
1211 if !msgOk {
1212 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
1213 log.Fields{"device-id": oFsm.deviceID})
1214 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1215 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1216 return
1217 }
mpagenkobf67a092021-03-17 09:52:28 +00001218 if msgObj.Result != me.Success {
mpagenko15ff4a52021-03-02 10:09:20 +00001219 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
1220 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1221 // TODO!!!: error treatment?, perhaps in the end reset the FSM
1222 return
mpagenkobf67a092021-03-17 09:52:28 +00001223 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001224 oFsm.mutexUpgradeParams.RLock()
mpagenko15ff4a52021-03-02 10:09:20 +00001225 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +00001226 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001227 logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
1228 //verifying committed image
1229 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvCheckCommitted)
1230 return
1231 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001232 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001233 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse wrong ME instance: abort",
1234 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1235 // TODO!!!: error treatment?
1236 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1237 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1238 return
1239 } //CommitSoftwareResponseType
1240 case omci.GetResponseType:
1241 {
1242 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
1243 if msgLayer == nil {
1244 logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
1245 log.Fields{"device-id": oFsm.deviceID})
1246 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1247 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1248 return
1249 }
1250 msgObj, msgOk := msgLayer.(*omci.GetResponse)
1251 if !msgOk {
1252 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
1253 log.Fields{"device-id": oFsm.deviceID})
1254 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1255 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1256 return
1257 }
1258 logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
1259 "device-id": oFsm.deviceID, "data-fields": msgObj})
1260 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1261 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1262 if msgObj.Result != me.Success {
1263 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
1264 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1265 // TODO!!!: error treatment?, perhaps in the end reset the FSM
1266 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1267 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1268 return
1269 }
1270 } else {
1271 logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
1272 log.Fields{"device-id": oFsm.deviceID})
1273 return
1274 }
1275
1276 meAttributes := msgObj.Attributes
1277 imageIsCommitted := meAttributes["IsCommitted"].(uint8)
1278 imageIsActive := meAttributes["IsActive"].(uint8)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001279 imageVersion := TrimStringFromMeOctet(meAttributes["Version"])
mpagenko02cf1b22021-03-12 17:30:30 +00001280 logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
mpagenko15ff4a52021-03-02 10:09:20 +00001281 log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
1282 "version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
mpagenkoaa3afe92021-05-21 16:20:58 +00001283
1284 oFsm.mutexUpgradeParams.Lock()
1285 if msgObj.EntityInstance == oFsm.inactiveImageMeID && imageIsActive == swIsActive {
mpagenkoc26d4c02021-05-06 14:27:57 +00001286 //a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
1287 // indicated in the download image version string (version must be part of the image content itself)
1288 // so checking that might be quite unreliable
1289 //but with new API this was changed, assumption is that omci image version is known at download request and exactly that is used
1290 // in all the API references, so it can and should be checked here now
1291 if oFsm.useAPIVersion43 {
1292 if imageVersion != oFsm.imageVersion {
1293 //new active version indicated on OMCI from ONU is not the expected version
1294 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1295 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance,
1296 "onu-version": imageVersion, "expected-version": oFsm.imageVersion})
mpagenkoaa3afe92021-05-21 16:20:58 +00001297 oFsm.mutexUpgradeParams.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001298 // TODO!!!: error treatment?
1299 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1300 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1301 return
1302 }
1303 logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU",
1304 log.Fields{"device-id": oFsm.deviceID})
1305 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001306 if imageIsCommitted == swIsCommitted {
mpagenkoaa3afe92021-05-21 16:20:58 +00001307 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTED
1308 logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
1309 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent)) //to let the handler now about success
1310 oFsm.mutexUpgradeParams.Unlock()
1311 //releasing the upgrade FSM
mpagenko183647c2021-06-08 15:25:04 +00001312 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenkoaa3afe92021-05-21 16:20:58 +00001313 return
1314 }
1315 oFsm.mutexUpgradeParams.Unlock()
1316 return //if the imageId is active but not committed let upgrade persist, maybe ONU reboot or manual commit may resolve the situation
mpagenko15ff4a52021-03-02 10:09:20 +00001317 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001318 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001319 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1320 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1321 // TODO!!!: error treatment?
1322 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1323 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1324 return
1325 } //GetResponseType
mpagenko80622a52021-02-09 16:53:23 +00001326 default:
1327 {
1328 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
1329 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
1330 return
1331 }
1332 }
1333}
1334
mpagenkoc26d4c02021-05-06 14:27:57 +00001335//waitOnDownloadToAdapterReady state can only be reached with useAPIVersion43 (usage of pFileManager)
1336func (oFsm *OnuUpgradeFsm) waitOnDownloadToAdapterReady(ctx context.Context, aWaitChannel chan bool) {
1337 downloadToAdapterTimeout := oFsm.pFileManager.GetDownloadTimeout(ctx)
1338 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1339 oFsm.isWaitingForAdapterDlResponse = true
1340 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001341 select {
1342 // maybe be also some outside cancel (but no context modeled for the moment ...)
1343 // case <-ctx.Done():
mpagenkoc26d4c02021-05-06 14:27:57 +00001344 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToAdapterReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1345 case <-time.After(downloadToAdapterTimeout): //10s should be enough for downloading some image to the adapter
1346 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-adapter-download timeout", log.Fields{
1347 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToAdapterTimeout})
1348 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
1349 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1350 oFsm.isWaitingForAdapterDlResponse = false
1351 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1352 //the upgrade process has to be aborted
1353 pUpgradeFsm := oFsm.pAdaptFsm
1354 if pUpgradeFsm != nil {
mpagenko183647c2021-06-08 15:25:04 +00001355 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
mpagenkoc26d4c02021-05-06 14:27:57 +00001356 } else {
1357 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +00001358 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001359 return
1360
1361 case success := <-aWaitChannel:
1362 if success {
1363 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded received", log.Fields{"device-id": oFsm.deviceID})
1364 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1365 oFsm.isWaitingForAdapterDlResponse = false
1366 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1367 //let the upgrade process proceed
1368 pUpgradeFsm := oFsm.pAdaptFsm
1369 if pUpgradeFsm != nil {
1370 _ = pUpgradeFsm.pFsm.Event(upgradeEvPrepareSwDownload)
1371 } else {
1372 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1373 }
1374 return
1375 }
1376 // waiting was aborted (probably on external request)
1377 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-adapter-download aborted", log.Fields{"device-id": oFsm.deviceID})
1378 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
1379 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1380 oFsm.isWaitingForAdapterDlResponse = false
1381 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1382 //the upgrade process has to be aborted
1383 pUpgradeFsm := oFsm.pAdaptFsm
1384 if pUpgradeFsm != nil {
1385 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
1386 } else {
1387 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1388 }
1389 return
mpagenko80622a52021-02-09 16:53:23 +00001390 }
1391}
mpagenkoc26d4c02021-05-06 14:27:57 +00001392
1393//waitOnDownloadToOnuReady state can only be reached with useAPIVersion43 (usage of pFileManager)
1394func (oFsm *OnuUpgradeFsm) waitOnDownloadToOnuReady(ctx context.Context, aWaitChannel chan bool) {
1395 downloadToOnuTimeout := time.Duration(1+(oFsm.imageLength/0x400000)) * oFsm.downloadToOnuTimeout4MB
1396 logger.Debugw(ctx, "OnuUpgradeFsm start download-to-ONU timer", log.Fields{"device-id": oFsm.deviceID,
1397 "duration": downloadToOnuTimeout})
1398 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1399 oFsm.isWaitingForOnuDlResponse = true
1400 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1401 select {
1402 // maybe be also some outside cancel (but no context modeled for the moment ...)
1403 // case <-ctx.Done():
1404 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToOnuReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1405 case <-time.After(downloadToOnuTimeout): //using an image-size depending timout (in minutes)
1406 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-ONU-download timeout", log.Fields{
1407 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToOnuTimeout})
1408 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1409 oFsm.isWaitingForOnuDlResponse = false
1410 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1411 //the upgrade process has to be aborted
1412 pUpgradeFsm := oFsm.pAdaptFsm
1413 if pUpgradeFsm != nil {
1414 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
1415 } else {
1416 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1417 }
1418 return
1419
1420 case success := <-aWaitChannel:
1421 if success {
1422 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded on ONU received", log.Fields{"device-id": oFsm.deviceID})
1423 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1424 oFsm.isWaitingForOnuDlResponse = false
1425 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1426 //all fine, let the FSM proceed like defined from the sender of this event
1427 return
1428 }
1429 // waiting was aborted (assumed here to be caused by
1430 // error detection or cancel at download after upgrade FSM reset/abort)
1431 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-ONU-download aborted", log.Fields{"device-id": oFsm.deviceID})
1432 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1433 oFsm.isWaitingForOnuDlResponse = false
1434 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1435 return
1436 }
1437}