blob: 88101b3db3dd4ea28d587fd4fecfcddc4777fa04 [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"
Girish Gowdra50e56422021-06-01 16:46:04 -070032 "github.com/opencord/voltha-lib-go/v5/pkg/log"
mpagenko80622a52021-02-09 16:53:23 +000033 "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},
mpagenko1f8e8822021-06-25 14:10:21 +0000194 {Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStRequestingActivate, upgradeStWaitForCommit,
195 upgradeStActivated}, 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
mpagenko1f8e8822021-06-25 14:10:21 +0000205 //on upgradeEvReset: upgradeStRequestingActivate, upgradeStWaitForCommit and upgradeStActivated are not reset
206 // (to let the FSM survive the expected OnuDown indication)
mpagenkoc26d4c02021-05-06 14:27:57 +0000207 {Name: upgradeEvReset, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
208 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
mpagenko1f8e8822021-06-25 14:10:21 +0000209 upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000210 Dst: upgradeStResetting},
mpagenkoc26d4c02021-05-06 14:27:57 +0000211 {Name: upgradeEvAbort, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
212 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
mpagenko183647c2021-06-08 15:25:04 +0000213 upgradeStRequestingActivate, upgradeStActivated, upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000214 Dst: upgradeStResetting},
215 {Name: upgradeEvRestart, Src: []string{upgradeStResetting}, Dst: upgradeStDisabled},
216 },
217 fsm.Callbacks{
218 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
219 "enter_" + upgradeStStarting: func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
mpagenkoc26d4c02021-05-06 14:27:57 +0000220 "enter_" + upgradeStWaitingAdapterDL: func(e *fsm.Event) { instFsm.enterWaitingAdapterDL(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000221 "enter_" + upgradeStPreparingDL: func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
222 "enter_" + upgradeStDLSection: func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
223 "enter_" + upgradeStVerifyWindow: func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
224 "enter_" + upgradeStFinalizeDL: func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
mpagenko59498c12021-03-18 14:15:15 +0000225 "enter_" + upgradeStWaitEndDL: func(e *fsm.Event) { instFsm.enterWaitEndDL(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000226 "enter_" + upgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
227 "enter_" + upgradeStCommitSw: func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
mpagenko15ff4a52021-03-02 10:09:20 +0000228 "enter_" + upgradeStCheckCommitted: func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000229 "enter_" + upgradeStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
230 "enter_" + upgradeStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
231 },
232 )
233 if instFsm.pAdaptFsm.pFsm == nil {
234 logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
235 "device-id": instFsm.deviceID})
236 return nil
237 }
238
239 logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
240 return instFsm
241}
242
243//SetDownloadParams configures the needed parameters for a specific download to the ONU
mpagenkoc26d4c02021-05-06 14:27:57 +0000244// called from 'old' API Activate_image_update()
mpagenko15ff4a52021-03-02 10:09:20 +0000245func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
246 apImageDsc *voltha.ImageDownload, apDownloadManager *adapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +0000247 pBaseFsm := oFsm.pAdaptFsm.pFsm
248 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000249 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000250 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
251 "device-id": oFsm.deviceID, "image-description": apImageDsc})
mpagenko15ff4a52021-03-02 10:09:20 +0000252 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenko80622a52021-02-09 16:53:23 +0000253 oFsm.pImageDsc = apImageDsc
254 oFsm.pDownloadManager = apDownloadManager
Holger Hildebrandtac1e0592021-06-03 15:16:49 +0000255 oFsm.activateImage = true
256 oFsm.commitImage = true
mpagenkoaa3afe92021-05-21 16:20:58 +0000257 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000258
259 go func(aPBaseFsm *fsm.FSM) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000260 // let the upgrade FSM proceed to PreparingDL
mpagenko80622a52021-02-09 16:53:23 +0000261 _ = aPBaseFsm.Event(upgradeEvPrepareSwDownload)
262 }(pBaseFsm)
263 return nil
264 }
265 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
266 "device-id": oFsm.deviceID})
267 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
268}
269
mpagenkoc26d4c02021-05-06 14:27:57 +0000270//SetDownloadParamsAfterDownload configures the needed parameters for a specific download to the ONU according to
271// updated API interface with R2.8: start download to ONU if the image is downloaded to the adapter
272// called from 'new' API Download_onu_image
273func (oFsm *OnuUpgradeFsm) SetDownloadParamsAfterDownload(ctx context.Context, aInactiveImageID uint16,
274 apImageRequest *voltha.DeviceImageDownloadRequest, apDownloadManager *fileDownloadManager,
Holger Hildebrandtac010732021-06-02 13:35:39 +0000275 aImageIdentifier string) error {
mpagenkoc26d4c02021-05-06 14:27:57 +0000276 oFsm.mutexUpgradeParams.Lock()
277 var pBaseFsm *fsm.FSM = nil
278 if oFsm.pAdaptFsm != nil {
279 pBaseFsm = oFsm.pAdaptFsm.pFsm
280 }
281 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
282 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
283 "device-id": oFsm.deviceID, "image-description": apImageRequest})
284 oFsm.useAPIVersion43 = true
285 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
286 oFsm.pFileManager = apDownloadManager
287 oFsm.imageIdentifier = aImageIdentifier
288 oFsm.imageVersion = apImageRequest.Image.Version
289 oFsm.activateImage = apImageRequest.ActivateOnSuccess
290 oFsm.commitImage = apImageRequest.CommitOnSuccess
mpagenkoc26d4c02021-05-06 14:27:57 +0000291 //TODO: currently straightforward options activate and commit are expected to be set and (unconditionally) done
292 // for separate handling of these options the FSM must accordingly branch from the concerned states - later
293 oFsm.mutexUpgradeParams.Unlock()
294 _ = pBaseFsm.Event(upgradeEvAdapterDownload) //no need to call the FSM event in background here
295 return nil
296 }
297 oFsm.mutexUpgradeParams.Unlock()
298 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
299 "device-id": oFsm.deviceID})
300 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
301}
302
303//SetActivationParamsRunning sets the activate and commit flags for a running download to the ONU according to adapters rpc call
304// called from 'new' API Activate_onu_image
305func (oFsm *OnuUpgradeFsm) SetActivationParamsRunning(ctx context.Context,
306 aImageIdentifier string, aCommit bool) error {
307 oFsm.mutexUpgradeParams.Lock()
308 //set activate/commit independent from state, if FSM is already beyond concerned states, then it does not matter anyway
309 // (as long as the Imageidentifier is correct)
310 logger.Debugw(ctx, "OnuUpgradeFsm activate/commit parameter setting", log.Fields{
311 "device-id": oFsm.deviceID, "image-id": aImageIdentifier, "commit": aCommit})
312 if aImageIdentifier != oFsm.imageIdentifier {
313 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
314 "device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
315 oFsm.mutexUpgradeParams.Unlock()
316 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
317 oFsm.deviceID))
318 }
319 oFsm.activateImage = true
320 oFsm.commitImage = aCommit
321 oFsm.mutexUpgradeParams.Unlock()
322 var pBaseFsm *fsm.FSM = nil
323 if oFsm.pAdaptFsm != nil {
324 pBaseFsm = oFsm.pAdaptFsm.pFsm
325 }
326 if pBaseFsm != nil {
327 if pBaseFsm.Is(upgradeStWaitForActivate) {
328 logger.Debugw(ctx, "OnuUpgradeFsm finish waiting for activate", log.Fields{"device-id": oFsm.deviceID})
329 _ = pBaseFsm.Event(upgradeEvRequestActivate) //no need to call the FSM event in background here
330 }
331 return nil
332 }
333 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
334 "device-id": oFsm.deviceID})
335 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
336}
337
338//SetActivationParamsStart starts upgrade processing with immediate activation
339// called from 'new' API Activate_onu_image
340func (oFsm *OnuUpgradeFsm) SetActivationParamsStart(ctx context.Context, aImageVersion string, aInactiveImageID uint16, aCommit bool) error {
341 oFsm.mutexUpgradeParams.Lock()
342 var pBaseFsm *fsm.FSM = nil
343 if oFsm.pAdaptFsm != nil {
344 pBaseFsm = oFsm.pAdaptFsm.pFsm
345 }
346 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
347 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with activation", log.Fields{
348 "device-id": oFsm.deviceID, "image-version": aImageVersion})
349 oFsm.useAPIVersion43 = true
350 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
351 oFsm.imageVersion = aImageVersion
352 oFsm.activateImage = true
353 oFsm.commitImage = aCommit
mpagenko183647c2021-06-08 15:25:04 +0000354 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN // this is just an activate request without prior download
mpagenkoc26d4c02021-05-06 14:27:57 +0000355 oFsm.mutexUpgradeParams.Unlock()
356 //directly request the FSM to activate the image
357 _ = pBaseFsm.Event(upgradeEvRequestActivate) //no need to call the FSM event in background here
358 return nil
359 }
360 oFsm.mutexUpgradeParams.Unlock()
361 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
362 "device-id": oFsm.deviceID})
363 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
364}
365
366//SetCommitmentParamsRunning sets the commit flag for a running download to the ONU according to adapters rpc call
367// called from 'new' API Commit_onu_image
368func (oFsm *OnuUpgradeFsm) SetCommitmentParamsRunning(ctx context.Context, aImageIdentifier string) error {
369 oFsm.mutexUpgradeParams.Lock()
370 //set commit independent from state, if FSM is already beyond commit state (just ready), then it does not matter anyway
371 // (as long as the Imageidentifier is correct)
372 logger.Debugw(ctx, "OnuUpgradeFsm commit parameter setting", log.Fields{
373 "device-id": oFsm.deviceID, "image-id": aImageIdentifier})
374 if aImageIdentifier != oFsm.imageIdentifier {
375 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
376 "device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
377 oFsm.mutexUpgradeParams.Unlock()
378 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
379 oFsm.deviceID))
380 }
381 oFsm.commitImage = true
382 oFsm.mutexUpgradeParams.Unlock()
383 var pBaseFsm *fsm.FSM = nil
384 if oFsm.pAdaptFsm != nil {
385 pBaseFsm = oFsm.pAdaptFsm.pFsm
386 }
387 if pBaseFsm != nil {
mpagenko183647c2021-06-08 15:25:04 +0000388 //let the FSM decide if it is ready to process the event
389 logger.Debugw(ctx, "OnuUpgradeFsm requesting commit",
390 log.Fields{"device-id": oFsm.deviceID, "current FsmState": pBaseFsm.Current()})
391 _ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
mpagenkoc26d4c02021-05-06 14:27:57 +0000392 return nil
393 }
394 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
395 "device-id": oFsm.deviceID})
396 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
397}
398
399//SetCommitmentParamsStart starts upgrade processing with immediate commitment
400// called from 'new' API Commit_onu_image
401func (oFsm *OnuUpgradeFsm) SetCommitmentParamsStart(ctx context.Context, aImageVersion string, aActiveImageID uint16) error {
402 oFsm.mutexUpgradeParams.Lock()
403 var pBaseFsm *fsm.FSM = nil
404 if oFsm.pAdaptFsm != nil {
405 pBaseFsm = oFsm.pAdaptFsm.pFsm
406 }
407 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
408 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with commitment", log.Fields{
409 "device-id": oFsm.deviceID, "image-version": aImageVersion})
410 oFsm.useAPIVersion43 = true
411 oFsm.inactiveImageMeID = aActiveImageID //upgrade state machines inactive ImageId is the new active ImageId
412 oFsm.imageVersion = aImageVersion
413 oFsm.commitImage = true
mpagenko183647c2021-06-08 15:25:04 +0000414 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN // this is just a commit request without prior download
mpagenkoc26d4c02021-05-06 14:27:57 +0000415 oFsm.mutexUpgradeParams.Unlock()
416 //directly request the FSM to activate the image
417 _ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
418 return nil
419 }
420 oFsm.mutexUpgradeParams.Unlock()
421 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
422 "device-id": oFsm.deviceID})
423 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
424}
425
mpagenko1f8e8822021-06-25 14:10:21 +0000426//GetCommitFlag delivers the commit flag that was configured here
427func (oFsm *OnuUpgradeFsm) GetCommitFlag(ctx context.Context) bool {
428 oFsm.mutexUpgradeParams.RLock()
429 defer oFsm.mutexUpgradeParams.RUnlock()
430 return oFsm.commitImage
431}
432
mpagenkoaa3afe92021-05-21 16:20:58 +0000433//GetImageStates delivers the download states as per device proto buf or error indication
434func (oFsm *OnuUpgradeFsm) GetImageStates(ctx context.Context,
435 aImageIdentifier string, aVersion string) (*voltha.ImageState, error) {
436 pImageState := &voltha.ImageState{}
437 // check if the request refers to some active image/version of the processing
438 oFsm.mutexUpgradeParams.RLock()
439 if (aImageIdentifier == oFsm.imageIdentifier) || (aVersion == oFsm.imageVersion) {
440 pImageState.DownloadState = oFsm.volthaDownloadState
441 pImageState.Reason = oFsm.volthaDownloadReason
442 pImageState.ImageState = oFsm.volthaImageState
443 } else {
444 pImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
445 pImageState.Reason = voltha.ImageState_NO_ERROR
446 pImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
447 }
448 oFsm.mutexUpgradeParams.RUnlock()
449 return pImageState, nil
450}
451
mpagenko183647c2021-06-08 15:25:04 +0000452//SetImageState sets the FSM internal volthaImageState
453func (oFsm *OnuUpgradeFsm) SetImageState(ctx context.Context, aImageState voltha.ImageState_ImageActivationState) {
454 oFsm.mutexUpgradeParams.Lock()
455 defer oFsm.mutexUpgradeParams.Unlock()
456 oFsm.volthaImageState = aImageState
457}
458
mpagenkoc26d4c02021-05-06 14:27:57 +0000459//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
460func (oFsm *OnuUpgradeFsm) CancelProcessing(ctx context.Context) {
461 //mutex protection is required for possible concurrent access to FSM members
462 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
463 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
464 oFsm.mutexIsAwaitingAdapterDlResponse.RLock()
465 if oFsm.isWaitingForAdapterDlResponse {
466 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
467 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
468 oFsm.chAdapterDlReady <- false
469 } else {
470 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
471 }
472 //chOnuDlReady is cleared as part of the FSM reset processing (from enterResetting())
473
474 // 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 +0000475 // specific here: See definition of state changes: some states are excluded from reset for possible later commit
mpagenkoc26d4c02021-05-06 14:27:57 +0000476 pAdaptFsm := oFsm.pAdaptFsm
477 if pAdaptFsm != nil {
478 // calling FSM events in background to avoid blocking of the caller
479 go func(aPAFsm *AdapterFsm) {
480 if aPAFsm.pFsm != nil {
481 if aPAFsm.pFsm.Is(upgradeStWaitEndDL) {
482 oFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
483 }
484 _ = aPAFsm.pFsm.Event(upgradeEvReset) //anyway and for all other states
485 } //else the FSM seems already to be in some released state
486 }(pAdaptFsm)
487 }
488}
489
mpagenko80622a52021-02-09 16:53:23 +0000490func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
491 logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
492 "device-id": oFsm.deviceID})
493
494 // start go routine for processing of LockState messages
495 go oFsm.processOmciUpgradeMessages(ctx)
496}
497
mpagenkoc26d4c02021-05-06 14:27:57 +0000498//enterWaitingAdapterDL state can only be reached with useAPIVersion43
499func (oFsm *OnuUpgradeFsm) enterWaitingAdapterDL(ctx context.Context, e *fsm.Event) {
500 logger.Debugw(ctx, "OnuUpgradeFsm waiting for adapter download", log.Fields{"in state": e.FSM.Current(),
501 "device-id": oFsm.deviceID})
502 go oFsm.waitOnDownloadToAdapterReady(ctx, oFsm.chAdapterDlReady)
503 go oFsm.pFileManager.RequestDownloadReady(ctx, oFsm.imageIdentifier, oFsm.chAdapterDlReady)
504}
505
mpagenko80622a52021-02-09 16:53:23 +0000506func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
507 logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
508 "device-id": oFsm.deviceID})
509
mpagenkoc26d4c02021-05-06 14:27:57 +0000510 var fileLen int64
511 var err error
mpagenkoaa3afe92021-05-21 16:20:58 +0000512 oFsm.mutexUpgradeParams.Lock()
mpagenkoc26d4c02021-05-06 14:27:57 +0000513 if oFsm.useAPIVersion43 {
514 //with the new API structure download to adapter is implicit and we have to wait until the image is available
515 fileLen, err = oFsm.pFileManager.GetImageBufferLen(ctx, oFsm.imageIdentifier)
516 } else {
517 fileLen, err = oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
518 }
mpagenko80622a52021-02-09 16:53:23 +0000519 if err != nil || fileLen > int64(cMaxUint32) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000520 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000521 logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
522 "device-id": oFsm.deviceID, "error": err, "length": fileLen})
523 pBaseFsm := oFsm.pAdaptFsm
524 // Can't call FSM Event directly, decoupling it
525 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000526 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000527 }(pBaseFsm)
528 return
529 }
530
mpagenkoc26d4c02021-05-06 14:27:57 +0000531 //copy file content to buffer
mpagenko80622a52021-02-09 16:53:23 +0000532 oFsm.imageBuffer = make([]byte, fileLen)
mpagenkoc26d4c02021-05-06 14:27:57 +0000533 if oFsm.useAPIVersion43 {
534 oFsm.imageBuffer, err = oFsm.pFileManager.GetDownloadImageBuffer(ctx, oFsm.imageIdentifier)
535 } else {
536 oFsm.imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
537 }
mpagenko80622a52021-02-09 16:53:23 +0000538 if err != nil {
mpagenkoaa3afe92021-05-21 16:20:58 +0000539 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000540 logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
541 "device-id": oFsm.deviceID, "error": err})
542 pBaseFsm := oFsm.pAdaptFsm
543 // Can't call FSM Event directly, decoupling it
544 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000545 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000546 }(pBaseFsm)
547 return
548 }
549
550 oFsm.noOfSections = uint32(fileLen / cOmciDownloadSectionSize)
551 if fileLen%cOmciDownloadSectionSize > 0 {
mpagenkoc26d4c02021-05-06 14:27:57 +0000552 bufferPadding := make([]byte, cOmciDownloadSectionSize-uint32((fileLen)%cOmciDownloadSectionSize))
mpagenko80622a52021-02-09 16:53:23 +0000553 //expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
mpagenkoc26d4c02021-05-06 14:27:57 +0000554 oFsm.imageBuffer = append(oFsm.imageBuffer[:(fileLen)], bufferPadding...)
mpagenko80622a52021-02-09 16:53:23 +0000555 oFsm.noOfSections++
556 }
557 oFsm.origImageLength = uint32(fileLen)
558 oFsm.imageLength = uint32(len(oFsm.imageBuffer))
mpagenko80622a52021-02-09 16:53:23 +0000559 logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
560 "MeId": oFsm.inactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
561 "ImageSize": oFsm.imageLength, "original file size": fileLen})
562 //"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
mpagenkoaa3afe92021-05-21 16:20:58 +0000563
564 oFsm.mutexUpgradeParams.Unlock()
565 go oFsm.waitOnDownloadToOnuReady(ctx, oFsm.chOnuDlReady) // start supervision of the complete download-to-ONU procedure
566
Girish Gowdra0b235842021-03-09 13:06:46 -0800567 err = oFsm.pOmciCC.sendStartSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000568 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength)
569 if err != nil {
570 logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
571 "device-id": oFsm.deviceID, "error": err})
572 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
573 pBaseFsm := oFsm.pAdaptFsm
574 // Can't call FSM Event directly, decoupling it
575 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000576 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000577 }(pBaseFsm)
578 return
579 }
580}
581
582func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
583 logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
584 "device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
585
586 var windowAckRequest uint8 = 0
587 var bufferStartOffset uint32
588 var bufferEndOffset uint32
589 var downloadSection []byte
590 framePrint := false //default no printing of downloadSection frames
mpagenkoaa3afe92021-05-21 16:20:58 +0000591 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000592 if oFsm.nextDownloadSectionsAbsolute == 0 {
593 //debug print of first section frame
594 framePrint = true
mpagenkoaa3afe92021-05-21 16:20:58 +0000595 oFsm.volthaImageState = voltha.ImageState_IMAGE_DOWNLOADING
mpagenko80622a52021-02-09 16:53:23 +0000596 }
597
598 for {
599 bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * cOmciDownloadSectionSize
600 bufferEndOffset = bufferStartOffset + cOmciDownloadSectionSize - 1 //for representing cOmciDownloadSectionSizeLimit values
601 logger.Debugw(ctx, "DlSection values are", log.Fields{
602 "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
603 "DlSectionWindow": oFsm.nextDownloadSectionsWindow,
604 "startOffset": bufferStartOffset, "endOffset": bufferEndOffset})
605 if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
606 logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
607 "device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
608 "bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
mpagenkoaa3afe92021-05-21 16:20:58 +0000609 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000610 //logical error -- reset the FSM
611 pBaseFsm := oFsm.pAdaptFsm
612 // Can't call FSM Event directly, decoupling it
613 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000614 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000615 }(pBaseFsm)
616 return
617 }
618 downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
619 if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
620 windowAckRequest = 1
621 logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
622 "device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
623 }
624 if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
625 windowAckRequest = 1
626 framePrint = true //debug print of last frame
mpagenko15ff4a52021-03-02 10:09:20 +0000627 oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
628 logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000629 "device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
630 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000631 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 -0800632 err := oFsm.pOmciCC.sendDownloadSection(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000633 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, framePrint)
634 if err != nil {
635 logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
mpagenko15ff4a52021-03-02 10:09:20 +0000636 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
mpagenko80622a52021-02-09 16:53:23 +0000637 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
638 pBaseFsm := oFsm.pAdaptFsm
639 // Can't call FSM Event directly, decoupling it
640 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000641 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000642 }(pBaseFsm)
643 return
644 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000645 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000646 oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
647 if windowAckRequest == 1 {
648 pBaseFsm := oFsm.pAdaptFsm
649 // Can't call FSM Event directly, decoupling it
mpagenkoaa3afe92021-05-21 16:20:58 +0000650 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000651 go func(a_pAFsm *AdapterFsm) {
652 _ = a_pAFsm.pFsm.Event(upgradeEvWaitWindowAck) //state transition to upgradeStVerifyWindow
653 }(pBaseFsm)
654 return
655 }
656 framePrint = false //for the next Section frame (if wanted, can be enabled in logic before sendXXX())
657 oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
mpagenko59498c12021-03-18 14:15:15 +0000658 if oFsm.omciSectionInterleaveDelay > 0 {
mpagenko80622a52021-02-09 16:53:23 +0000659 //ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
mpagenkoaa3afe92021-05-21 16:20:58 +0000660 oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
mpagenko59498c12021-03-18 14:15:15 +0000661 time.Sleep(oFsm.omciSectionInterleaveDelay * time.Millisecond)
mpagenkoaa3afe92021-05-21 16:20:58 +0000662 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000663 }
664 }
665}
666
667func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
668 logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
669 "for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
670}
671
672func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
mpagenko80622a52021-02-09 16:53:23 +0000673 logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
mpagenko59498c12021-03-18 14:15:15 +0000674 "device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(oFsm.imageCRC), 16), "delay": oFsm.delayEndSwDl})
mpagenko80622a52021-02-09 16:53:23 +0000675
mpagenkoaa3afe92021-05-21 16:20:58 +0000676 oFsm.mutexUpgradeParams.RLock()
mpagenko80622a52021-02-09 16:53:23 +0000677 if oFsm.delayEndSwDl {
mpagenkoaa3afe92021-05-21 16:20:58 +0000678 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +0000679 //give the ONU some time for image evaluation (hoping it does not base that on first EndSwDl itself)
680 // should not be set in case this state is used for real download abort (not yet implemented)
681 time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
mpagenkoaa3afe92021-05-21 16:20:58 +0000682 } else {
683 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +0000684 }
685
mpagenko59498c12021-03-18 14:15:15 +0000686 pBaseFsm := oFsm.pAdaptFsm
687 if pBaseFsm == nil {
688 logger.Errorw(ctx, "EndSwDl abort: BaseFsm invalid", log.Fields{
689 "device-id": oFsm.deviceID})
690 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
691 // Can't call FSM Event directly, decoupling it
692 go func(a_pAFsm *AdapterFsm) {
693 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
694 }(pBaseFsm)
695 return
696 }
Girish Gowdra0b235842021-03-09 13:06:46 -0800697 err := oFsm.pOmciCC.sendEndSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko59498c12021-03-18 14:15:15 +0000698 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.origImageLength, oFsm.imageCRC)
mpagenko80622a52021-02-09 16:53:23 +0000699 if err != nil {
700 logger.Errorw(ctx, "EndSwDl abort: can't send section", log.Fields{
701 "device-id": oFsm.deviceID, "error": err})
702 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
mpagenko80622a52021-02-09 16:53:23 +0000703 // Can't call FSM Event directly, decoupling it
704 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000705 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000706 }(pBaseFsm)
707 return
708 }
mpagenko59498c12021-03-18 14:15:15 +0000709 // go waiting for the EndSwDLResponse and check, if the ONU is ready for activation
710 // Can't call FSM Event directly, decoupling it
711 go func(a_pAFsm *AdapterFsm) {
712 _ = a_pAFsm.pFsm.Event(upgradeEvWaitEndDownload)
713 }(pBaseFsm)
714}
715
716func (oFsm *OnuUpgradeFsm) enterWaitEndDL(ctx context.Context, e *fsm.Event) {
717 logger.Infow(ctx, "OnuUpgradeFsm WaitEndDl", log.Fields{
718 "device-id": oFsm.deviceID, "wait delay": oFsm.waitDelayEndSwDl * time.Second, "wait count": oFsm.waitCountEndSwDl})
719 if oFsm.waitCountEndSwDl == 0 {
720 logger.Errorw(ctx, "WaitEndDl abort: max limit of EndSwDL reached", log.Fields{
721 "device-id": oFsm.deviceID})
722 pBaseFsm := oFsm.pAdaptFsm
723 if pBaseFsm == nil {
724 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
725 "device-id": oFsm.deviceID})
726 return
727 }
728 go func(a_pAFsm *AdapterFsm) {
729 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
730 }(pBaseFsm)
731 return
732 }
733
734 oFsm.waitCountEndSwDl--
735 select {
736 case <-time.After(oFsm.waitDelayEndSwDl * time.Second):
737 pBaseFsm := oFsm.pAdaptFsm
738 if pBaseFsm == nil {
739 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
740 "device-id": oFsm.deviceID})
741 //FSM may be reset already from somewhere else, nothing we can do here anymore
742 return
743 }
744 //retry End SW DL
mpagenkoaa3afe92021-05-21 16:20:58 +0000745 oFsm.mutexUpgradeParams.Lock()
mpagenko59498c12021-03-18 14:15:15 +0000746 oFsm.delayEndSwDl = false //no more extra delay for the request
mpagenkoaa3afe92021-05-21 16:20:58 +0000747 oFsm.mutexUpgradeParams.Unlock()
mpagenko59498c12021-03-18 14:15:15 +0000748 go func(a_pAFsm *AdapterFsm) {
749 _ = a_pAFsm.pFsm.Event(upgradeEvContinueFinalize)
750 }(pBaseFsm)
751 return
752 case success := <-oFsm.chReceiveExpectedResponse:
753 logger.Debugw(ctx, "WaitEndDl stop wait timer", log.Fields{"device-id": oFsm.deviceID})
754 pBaseFsm := oFsm.pAdaptFsm
755 if pBaseFsm == nil {
756 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
757 "device-id": oFsm.deviceID})
758 //FSM may be reset already from somewhere else, nothing we can do here anymore
759 return
760 }
761 if success {
762 //answer received with ready indication
mpagenkoc26d4c02021-05-06 14:27:57 +0000763 if oFsm.activateImage {
764 //immediate activation requested
765 go func(a_pAFsm *AdapterFsm) {
766 _ = a_pAFsm.pFsm.Event(upgradeEvRequestActivate)
767 }(pBaseFsm)
768 } else {
769 //have to wait on explicit activation request
770 go func(a_pAFsm *AdapterFsm) {
771 _ = a_pAFsm.pFsm.Event(upgradeEvWaitForActivate)
772 }(pBaseFsm)
773 }
mpagenko59498c12021-03-18 14:15:15 +0000774 return
775 }
776 //timer was aborted
777 go func(a_pAFsm *AdapterFsm) {
778 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
779 }(pBaseFsm)
780 return
781 }
mpagenko80622a52021-02-09 16:53:23 +0000782}
783
784func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
785 logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
786 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
787
mpagenkoaa3afe92021-05-21 16:20:58 +0000788 oFsm.mutexUpgradeParams.Lock()
789 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVATING
790 oFsm.mutexUpgradeParams.Unlock()
791
Girish Gowdra0b235842021-03-09 13:06:46 -0800792 err := oFsm.pOmciCC.sendActivateSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000793 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID)
794 if err != nil {
795 logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
796 "device-id": oFsm.deviceID, "error": err})
797 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
798 pBaseFsm := oFsm.pAdaptFsm
799 // Can't call FSM Event directly, decoupling it
800 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000801 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000802 }(pBaseFsm)
803 return
804 }
805}
806
807func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
mpagenko15ff4a52021-03-02 10:09:20 +0000808 if activeImageID, err := oFsm.pOnuOmciDevice.GetActiveImageMeID(ctx); err == nil {
809 //TODO!!: as long as testing with BBSIM and BBSIM not support upgrade tests following check needs to be deactivated
810 imageFit := true //TODO!!: test workaround as long as BBSIM does not fully support upgrade
mpagenkoaa3afe92021-05-21 16:20:58 +0000811 oFsm.mutexUpgradeParams.Lock()
mpagenko15ff4a52021-03-02 10:09:20 +0000812 if imageFit || activeImageID == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +0000813 inactiveImageID := oFsm.inactiveImageMeID
mpagenko15ff4a52021-03-02 10:09:20 +0000814 logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
mpagenkoaa3afe92021-05-21 16:20:58 +0000815 "device-id": oFsm.deviceID, "me-id": inactiveImageID}) //more efficient activeImageID with above check
816 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTING
817 oFsm.mutexUpgradeParams.Unlock()
Girish Gowdra0b235842021-03-09 13:06:46 -0800818 err := oFsm.pOmciCC.sendCommitSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenkoaa3afe92021-05-21 16:20:58 +0000819 oFsm.pAdaptFsm.commChan, inactiveImageID) //more efficient activeImageID with above check
mpagenko15ff4a52021-03-02 10:09:20 +0000820 if err != nil {
821 logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
822 "device-id": oFsm.deviceID, "error": err})
823 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
824 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
825 pBaseFsm := oFsm.pAdaptFsm
826 // Can't call FSM Event directly, decoupling it
827 go func(a_pAFsm *AdapterFsm) {
828 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
829 }(pBaseFsm)
830 return
831 }
832 return
833 }
834 logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
835 "device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.inactiveImageMeID})
mpagenkoaa3afe92021-05-21 16:20:58 +0000836 oFsm.mutexUpgradeParams.Unlock()
837
mpagenko15ff4a52021-03-02 10:09:20 +0000838 //TODO!!!: possibly send event information for aborted upgrade (not activated)??
839 pBaseFsm := oFsm.pAdaptFsm
840 // Can't call FSM Event directly, decoupling it
841 go func(a_pAFsm *AdapterFsm) {
842 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
843 }(pBaseFsm)
844 return
845 }
846 logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
847 "device-id": oFsm.deviceID})
848 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
849 pBaseFsm := oFsm.pAdaptFsm
850 // Can't call FSM Event directly, decoupling it
851 go func(a_pAFsm *AdapterFsm) {
852 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
853 }(pBaseFsm)
854}
855
856func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
857 logger.Infow(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000858 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
mpagenko15ff4a52021-03-02 10:09:20 +0000859 requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
ozgecanetsiab36ed572021-04-01 10:38:48 +0300860 meInstance, err := oFsm.pOmciCC.sendGetMe(log.WithSpanFromContext(context.TODO(), ctx),
Girish Gowdra0b235842021-03-09 13:06:46 -0800861 me.SoftwareImageClassID, oFsm.inactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false, oFsm.pAdaptFsm.commChan)
mpagenko15ff4a52021-03-02 10:09:20 +0000862 //accept also nil as (error) return value for writing to LastTx
863 // - this avoids misinterpretation of new received OMCI messages
ozgecanetsiab36ed572021-04-01 10:38:48 +0300864 if err != nil {
865 logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
866 log.Fields{"device-id": oFsm.deviceID, "Error": err})
867 pOnuUpgradeFsm := oFsm.pAdaptFsm
868 if pOnuUpgradeFsm != nil {
869 go func(a_pAFsm *AdapterFsm) {
mpagenko183647c2021-06-08 15:25:04 +0000870 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300871 }(pOnuUpgradeFsm)
872 }
873 return
874 }
mpagenko15ff4a52021-03-02 10:09:20 +0000875 oFsm.pLastTxMeInstance = meInstance
mpagenko80622a52021-02-09 16:53:23 +0000876}
877
878func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
879 logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
880
mpagenkoc26d4c02021-05-06 14:27:57 +0000881 // in case the download-to-ONU timer is still running - cancel it
882 oFsm.mutexIsAwaitingOnuDlResponse.RLock()
883 if oFsm.isWaitingForOnuDlResponse {
884 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
885 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
886 oFsm.chOnuDlReady <- false
887 } else {
888 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
889 }
890
mpagenko80622a52021-02-09 16:53:23 +0000891 pConfigupgradeStateAFsm := oFsm.pAdaptFsm
892 if pConfigupgradeStateAFsm != nil {
893 // abort running message processing
894 fsmAbortMsg := Message{
895 Type: TestMsg,
896 Data: TestMessage{
897 TestMessageVal: AbortMessageProcessing,
898 },
899 }
900 pConfigupgradeStateAFsm.commChan <- fsmAbortMsg
901
902 //try to restart the FSM to 'disabled'
903 // Can't call FSM Event directly, decoupling it
904 go func(a_pAFsm *AdapterFsm) {
905 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
906 _ = a_pAFsm.pFsm.Event(upgradeEvRestart)
907 }
908 }(pConfigupgradeStateAFsm)
909 }
910}
911
912func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
913 logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +0000914 // 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 +0000915 if oFsm.pDeviceHandler != nil {
916 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
917 go oFsm.pDeviceHandler.removeOnuUpgradeFsm(ctx)
918 }
919}
920
921func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
922 logger.Debugw(ctx, "Start OnuUpgradeFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
923loop:
924 for {
925 // case <-ctx.Done():
926 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
927 // break loop
928 message, ok := <-oFsm.pAdaptFsm.commChan
929 if !ok {
930 logger.Info(ctx, "OnuUpgradeFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
931 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
mpagenko15ff4a52021-03-02 10:09:20 +0000932 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000933 break loop
934 }
935 logger.Debugw(ctx, "OnuUpgradeFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
936
937 switch message.Type {
938 case TestMsg:
939 msg, _ := message.Data.(TestMessage)
940 if msg.TestMessageVal == AbortMessageProcessing {
941 logger.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
942 break loop
943 }
944 logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
945 case OMCI:
946 msg, _ := message.Data.(OmciMessage)
947 oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
948 default:
949 logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
950 "message.Type": message.Type})
951 }
952 }
953 logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
954}
955
956//nolint: gocyclo
957func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg OmciMessage) {
958 logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
959 "msgType": msg.OmciMsg.MessageType})
960
961 switch msg.OmciMsg.MessageType {
962 case omci.StartSoftwareDownloadResponseType:
963 {
964 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
965 if msgLayer == nil {
966 logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
967 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000968 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
969 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000970 return
971 }
972 msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
973 if !msgOk {
974 logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
975 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000976 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
977 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000978 return
979 }
980 logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
981 "device-id": oFsm.deviceID, "data-fields": msgObj})
982 if msgObj.Result != me.Success {
983 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
984 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
985 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000986 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
987 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000988 return
989 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000990
991 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000992 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
993 logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
994 if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
995 // also response WindowSize = 0 is a valid number for used Window size 1
996 logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
997 "acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
998 oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
999 }
1000 oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
1001 if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
1002 oFsm.noOfWindows++
1003 }
1004 logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
1005 "windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
1006 "at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
1007 oFsm.nextDownloadSectionsAbsolute = 0
1008 oFsm.nextDownloadSectionsWindow = 0
1009 oFsm.nextDownloadWindow = 0
1010
mpagenkoaa3afe92021-05-21 16:20:58 +00001011 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001012 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRxStartSwDownload)
1013 return
1014 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001015 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001016 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
1017 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1018 // TODO!!!: possibly repeat the start request (once)?
mpagenko15ff4a52021-03-02 10:09:20 +00001019 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1020 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001021 return
1022 } //StartSoftwareDownloadResponseType
1023 case omci.DownloadSectionResponseType:
1024 {
mpagenko80622a52021-02-09 16:53:23 +00001025 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
1026 if msgLayer == nil {
1027 logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
1028 log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
mpagenko15ff4a52021-03-02 10:09:20 +00001029 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1030 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001031 return
1032 }
1033 msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
1034 if !msgOk {
1035 logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
1036 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001037 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1038 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001039 return
1040 }
1041 logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
1042 "device-id": oFsm.deviceID, "data-fields": msgObj})
1043 if msgObj.Result != me.Success {
1044 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
1045 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko15ff4a52021-03-02 10:09:20 +00001046 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1047 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001048 return
1049 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001050 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +00001051 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
1052 sectionNumber := msgObj.SectionNumber
mpagenko15ff4a52021-03-02 10:09:20 +00001053 logger.Infow(ctx, "DlSectionResponse received", log.Fields{
1054 "window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +00001055
mpagenko15ff4a52021-03-02 10:09:20 +00001056 oFsm.nextDownloadWindow++
1057 if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
1058 if sectionNumber != oFsm.omciDownloadWindowSizeLast {
mpagenko02cf1b22021-03-12 17:30:30 +00001059 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error last window - later: repeat window once?", //TODO!!!
mpagenko15ff4a52021-03-02 10:09:20 +00001060 log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
1061 "expected section": oFsm.omciDownloadWindowSizeLast})
1062 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
mpagenkoaa3afe92021-05-21 16:20:58 +00001063 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001064 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1065 return
1066 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001067 oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
1068 //CRC computation for all data bytes of the file
1069 imageCRC := crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //store internal for multiple usage
1070 //revert the retrieved CRC Byte Order (seems not to deliver NetworkByteOrder)
1071 var byteSlice []byte = make([]byte, 4)
1072 binary.LittleEndian.PutUint32(byteSlice, uint32(imageCRC))
1073 oFsm.imageCRC = binary.BigEndian.Uint32(byteSlice)
mpagenkoaa3afe92021-05-21 16:20:58 +00001074 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001075 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvEndSwDownload)
1076 return
1077 }
1078 if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
1079 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
mpagenko02cf1b22021-03-12 17:30:30 +00001080 log.Fields{"device-id": oFsm.deviceID, "actual-section": sectionNumber,
1081 "expected section": oFsm.omciDownloadWindowSizeLimit})
mpagenkoaa3afe92021-05-21 16:20:58 +00001082 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001083 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1084 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1085 return
1086 }
1087 oFsm.nextDownloadSectionsWindow = 0
mpagenkoaa3afe92021-05-21 16:20:58 +00001088 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001089 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvContinueNextWindow)
mpagenko80622a52021-02-09 16:53:23 +00001090 return
1091 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001092 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001093 logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
1094 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +00001095 // TODO!!!: possibly repeat the download (section) (once)?
1096 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1097 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001098 return
mpagenko80622a52021-02-09 16:53:23 +00001099 } //DownloadSectionResponseType
1100 case omci.EndSoftwareDownloadResponseType:
1101 {
1102 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
1103 if msgLayer == nil {
1104 logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
1105 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001106 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1107 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001108 return
1109 }
1110 msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
1111 if !msgOk {
1112 logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
1113 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001114 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1115 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001116 return
1117 }
1118 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
1119 "device-id": oFsm.deviceID, "data-fields": msgObj})
1120 if msgObj.Result != me.Success {
mpagenko59498c12021-03-18 14:15:15 +00001121 if msgObj.Result == me.DeviceBusy {
1122 //ONU indicates it is still processing the image - let the FSM just wait and then repeat the request
1123 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse busy: waiting before sending new request", log.Fields{
1124 "device-id": oFsm.deviceID})
1125 return
1126 }
mpagenko80622a52021-02-09 16:53:23 +00001127 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - later: drive FSM to abort state ?",
1128 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1129 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +00001130 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1131 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001132 return
1133 }
mpagenko183647c2021-06-08 15:25:04 +00001134 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +00001135 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenko183647c2021-06-08 15:25:04 +00001136 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1137 oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE
1138 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001139 logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001140 oFsm.mutexIsAwaitingOnuDlResponse.RLock()
1141 if oFsm.isWaitingForOnuDlResponse {
1142 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
1143 //use channel to indicate that the download to ONU was successful
1144 oFsm.chOnuDlReady <- true
1145 } else {
1146 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
1147 }
mpagenko59498c12021-03-18 14:15:15 +00001148 oFsm.chReceiveExpectedResponse <- true //let the FSM proceed from the waitState
mpagenko80622a52021-02-09 16:53:23 +00001149 return
1150 }
mpagenko183647c2021-06-08 15:25:04 +00001151 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001152 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
1153 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1154 // TODO!!!: possibly repeat the end request (once)? or verify ONU upgrade state?
mpagenko15ff4a52021-03-02 10:09:20 +00001155 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1156 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001157 return
1158 } //EndSoftwareDownloadResponseType
1159 case omci.ActivateSoftwareResponseType:
1160 {
1161 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
1162 if msgLayer == nil {
1163 logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
1164 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001165 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1166 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001167 return
1168 }
1169 msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
1170 if !msgOk {
1171 logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
1172 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001173 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1174 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001175 return
1176 }
1177 logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
1178 "device-id": oFsm.deviceID, "data-fields": msgObj})
1179 if msgObj.Result != me.Success {
1180 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
1181 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1182 // TODO!!!: error treatment?, perhaps in the end reset the FSM
mpagenko15ff4a52021-03-02 10:09:20 +00001183 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1184 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001185 return
1186 }
mpagenko183647c2021-06-08 15:25:04 +00001187 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +00001188 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenko183647c2021-06-08 15:25:04 +00001189 oFsm.mutexUpgradeParams.Unlock()
1190 logger.Infow(ctx, "Expected ActivateSwResponse received",
1191 log.Fields{"device-id": oFsm.deviceID, "commit": oFsm.commitImage})
1192 if oFsm.commitImage {
1193 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
1194 } else {
1195 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvActivationDone) // let the FSM wait for external commit request
1196 }
mpagenko80622a52021-02-09 16:53:23 +00001197 return
1198 }
mpagenko183647c2021-06-08 15:25:04 +00001199 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001200 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
1201 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +00001202 // TODO!!!: error treatment?
1203 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1204 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001205 return
1206 } //ActivateSoftwareResponseType
mpagenko15ff4a52021-03-02 10:09:20 +00001207 case omci.CommitSoftwareResponseType:
1208 {
1209 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
1210 if msgLayer == nil {
1211 logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
1212 log.Fields{"device-id": oFsm.deviceID})
1213 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1214 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1215 return
1216 }
1217 msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
1218 if !msgOk {
1219 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
1220 log.Fields{"device-id": oFsm.deviceID})
1221 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1222 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1223 return
1224 }
mpagenkobf67a092021-03-17 09:52:28 +00001225 if msgObj.Result != me.Success {
mpagenko15ff4a52021-03-02 10:09:20 +00001226 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
1227 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1228 // TODO!!!: error treatment?, perhaps in the end reset the FSM
1229 return
mpagenkobf67a092021-03-17 09:52:28 +00001230 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001231 oFsm.mutexUpgradeParams.RLock()
mpagenko15ff4a52021-03-02 10:09:20 +00001232 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +00001233 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001234 logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
1235 //verifying committed image
1236 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvCheckCommitted)
1237 return
1238 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001239 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001240 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse wrong ME instance: abort",
1241 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1242 // TODO!!!: error treatment?
1243 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1244 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1245 return
1246 } //CommitSoftwareResponseType
1247 case omci.GetResponseType:
1248 {
1249 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
1250 if msgLayer == nil {
1251 logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
1252 log.Fields{"device-id": oFsm.deviceID})
1253 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1254 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1255 return
1256 }
1257 msgObj, msgOk := msgLayer.(*omci.GetResponse)
1258 if !msgOk {
1259 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
1260 log.Fields{"device-id": oFsm.deviceID})
1261 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1262 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1263 return
1264 }
1265 logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
1266 "device-id": oFsm.deviceID, "data-fields": msgObj})
1267 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1268 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1269 if msgObj.Result != me.Success {
1270 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
1271 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1272 // TODO!!!: error treatment?, perhaps in the end reset the FSM
1273 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1274 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1275 return
1276 }
1277 } else {
1278 logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
1279 log.Fields{"device-id": oFsm.deviceID})
1280 return
1281 }
1282
1283 meAttributes := msgObj.Attributes
1284 imageIsCommitted := meAttributes["IsCommitted"].(uint8)
1285 imageIsActive := meAttributes["IsActive"].(uint8)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001286 imageVersion := TrimStringFromMeOctet(meAttributes["Version"])
mpagenko02cf1b22021-03-12 17:30:30 +00001287 logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
mpagenko15ff4a52021-03-02 10:09:20 +00001288 log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
1289 "version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
mpagenkoaa3afe92021-05-21 16:20:58 +00001290
1291 oFsm.mutexUpgradeParams.Lock()
1292 if msgObj.EntityInstance == oFsm.inactiveImageMeID && imageIsActive == swIsActive {
mpagenkoc26d4c02021-05-06 14:27:57 +00001293 //a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
1294 // indicated in the download image version string (version must be part of the image content itself)
1295 // so checking that might be quite unreliable
1296 //but with new API this was changed, assumption is that omci image version is known at download request and exactly that is used
1297 // in all the API references, so it can and should be checked here now
1298 if oFsm.useAPIVersion43 {
1299 if imageVersion != oFsm.imageVersion {
1300 //new active version indicated on OMCI from ONU is not the expected version
1301 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1302 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance,
1303 "onu-version": imageVersion, "expected-version": oFsm.imageVersion})
mpagenkoaa3afe92021-05-21 16:20:58 +00001304 oFsm.mutexUpgradeParams.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001305 // TODO!!!: error treatment?
1306 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1307 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1308 return
1309 }
1310 logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU",
1311 log.Fields{"device-id": oFsm.deviceID})
1312 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001313 if imageIsCommitted == swIsCommitted {
mpagenkoaa3afe92021-05-21 16:20:58 +00001314 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTED
1315 logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
1316 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent)) //to let the handler now about success
1317 oFsm.mutexUpgradeParams.Unlock()
1318 //releasing the upgrade FSM
mpagenko183647c2021-06-08 15:25:04 +00001319 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenkoaa3afe92021-05-21 16:20:58 +00001320 return
1321 }
1322 oFsm.mutexUpgradeParams.Unlock()
1323 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 +00001324 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001325 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001326 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1327 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1328 // TODO!!!: error treatment?
1329 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1330 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1331 return
1332 } //GetResponseType
mpagenko80622a52021-02-09 16:53:23 +00001333 default:
1334 {
1335 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
1336 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
1337 return
1338 }
1339 }
1340}
1341
mpagenkoc26d4c02021-05-06 14:27:57 +00001342//waitOnDownloadToAdapterReady state can only be reached with useAPIVersion43 (usage of pFileManager)
1343func (oFsm *OnuUpgradeFsm) waitOnDownloadToAdapterReady(ctx context.Context, aWaitChannel chan bool) {
1344 downloadToAdapterTimeout := oFsm.pFileManager.GetDownloadTimeout(ctx)
1345 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1346 oFsm.isWaitingForAdapterDlResponse = true
1347 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001348 select {
1349 // maybe be also some outside cancel (but no context modeled for the moment ...)
1350 // case <-ctx.Done():
mpagenkoc26d4c02021-05-06 14:27:57 +00001351 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToAdapterReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1352 case <-time.After(downloadToAdapterTimeout): //10s should be enough for downloading some image to the adapter
1353 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-adapter-download timeout", log.Fields{
1354 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToAdapterTimeout})
1355 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
1356 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1357 oFsm.isWaitingForAdapterDlResponse = false
1358 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1359 //the upgrade process has to be aborted
1360 pUpgradeFsm := oFsm.pAdaptFsm
1361 if pUpgradeFsm != nil {
mpagenko183647c2021-06-08 15:25:04 +00001362 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
mpagenkoc26d4c02021-05-06 14:27:57 +00001363 } else {
1364 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +00001365 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001366 return
1367
1368 case success := <-aWaitChannel:
1369 if success {
1370 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded received", log.Fields{"device-id": oFsm.deviceID})
1371 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1372 oFsm.isWaitingForAdapterDlResponse = false
1373 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1374 //let the upgrade process proceed
1375 pUpgradeFsm := oFsm.pAdaptFsm
1376 if pUpgradeFsm != nil {
1377 _ = pUpgradeFsm.pFsm.Event(upgradeEvPrepareSwDownload)
1378 } else {
1379 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1380 }
1381 return
1382 }
1383 // waiting was aborted (probably on external request)
1384 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-adapter-download aborted", log.Fields{"device-id": oFsm.deviceID})
1385 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
1386 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1387 oFsm.isWaitingForAdapterDlResponse = false
1388 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1389 //the upgrade process has to be aborted
1390 pUpgradeFsm := oFsm.pAdaptFsm
1391 if pUpgradeFsm != nil {
1392 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
1393 } else {
1394 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1395 }
1396 return
mpagenko80622a52021-02-09 16:53:23 +00001397 }
1398}
mpagenkoc26d4c02021-05-06 14:27:57 +00001399
1400//waitOnDownloadToOnuReady state can only be reached with useAPIVersion43 (usage of pFileManager)
1401func (oFsm *OnuUpgradeFsm) waitOnDownloadToOnuReady(ctx context.Context, aWaitChannel chan bool) {
1402 downloadToOnuTimeout := time.Duration(1+(oFsm.imageLength/0x400000)) * oFsm.downloadToOnuTimeout4MB
1403 logger.Debugw(ctx, "OnuUpgradeFsm start download-to-ONU timer", log.Fields{"device-id": oFsm.deviceID,
1404 "duration": downloadToOnuTimeout})
1405 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1406 oFsm.isWaitingForOnuDlResponse = true
1407 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1408 select {
1409 // maybe be also some outside cancel (but no context modeled for the moment ...)
1410 // case <-ctx.Done():
1411 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToOnuReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1412 case <-time.After(downloadToOnuTimeout): //using an image-size depending timout (in minutes)
1413 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-ONU-download timeout", log.Fields{
1414 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToOnuTimeout})
1415 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1416 oFsm.isWaitingForOnuDlResponse = false
1417 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1418 //the upgrade process has to be aborted
1419 pUpgradeFsm := oFsm.pAdaptFsm
1420 if pUpgradeFsm != nil {
1421 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
1422 } else {
1423 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1424 }
1425 return
1426
1427 case success := <-aWaitChannel:
1428 if success {
1429 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded on ONU received", log.Fields{"device-id": oFsm.deviceID})
1430 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1431 oFsm.isWaitingForOnuDlResponse = false
1432 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1433 //all fine, let the FSM proceed like defined from the sender of this event
1434 return
1435 }
1436 // waiting was aborted (assumed here to be caused by
1437 // error detection or cancel at download after upgrade FSM reset/abort)
1438 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-ONU-download aborted", log.Fields{"device-id": oFsm.deviceID})
1439 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1440 oFsm.isWaitingForOnuDlResponse = false
1441 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1442 return
1443 }
1444}