blob: 9d57c89fd8fda7656b25f00dccf3133bb57e47d8 [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"
63 upgradeEvWaitForCommit = "upgradeEvWaitForCommit"
64 upgradeEvCommitSw = "upgradeEvCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000065 upgradeEvCheckCommitted = "upgradeEvCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000066
67 //upgradeEvTimeoutSimple = "upgradeEvTimeoutSimple"
68 //upgradeEvTimeoutMids = "upgradeEvTimeoutMids"
69 upgradeEvReset = "upgradeEvReset"
70 upgradeEvAbort = "upgradeEvAbort"
71 upgradeEvRestart = "upgradeEvRestart"
72)
73
74const (
75 // states of config PON ANI port FSM
76 upgradeStDisabled = "upgradeStDisabled"
77 upgradeStStarting = "upgradeStStarting"
mpagenkoc26d4c02021-05-06 14:27:57 +000078 upgradeStWaitingAdapterDL = "upgradeStWaitingAdapterDL"
mpagenko80622a52021-02-09 16:53:23 +000079 upgradeStPreparingDL = "upgradeStPreparingDL"
80 upgradeStDLSection = "upgradeStDLSection"
81 upgradeStVerifyWindow = "upgradeStVerifyWindow"
82 upgradeStFinalizeDL = "upgradeStFinalizeDL"
mpagenko59498c12021-03-18 14:15:15 +000083 upgradeStWaitEndDL = "upgradeStWaitEndDL"
mpagenkoc26d4c02021-05-06 14:27:57 +000084 upgradeStWaitForActivate = "upgradeStWaitForActivate"
mpagenko80622a52021-02-09 16:53:23 +000085 upgradeStRequestingActivate = "upgradeStRequestingActivate"
86 upgradeStWaitForCommit = "upgradeStWaitForCommit"
87 upgradeStCommitSw = "upgradeStCommitSw"
mpagenko15ff4a52021-03-02 10:09:20 +000088 upgradeStCheckCommitted = "upgradeStCheckCommitted"
mpagenko80622a52021-02-09 16:53:23 +000089 upgradeStResetting = "upgradeStResetting"
90)
91
92//required definition for IdleState detection for activities on OMCI
93const cOnuUpgradeFsmIdleState = upgradeStWaitForCommit
94
95//OnuUpgradeFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
96type OnuUpgradeFsm struct {
97 pDeviceHandler *deviceHandler
98 pDownloadManager *adapterDownloadManager
mpagenkoc26d4c02021-05-06 14:27:57 +000099 pFileManager *fileDownloadManager //used from R2.8 with new API version
mpagenko80622a52021-02-09 16:53:23 +0000100 deviceID string
mpagenko15ff4a52021-03-02 10:09:20 +0000101 pOnuOmciDevice *OnuDeviceEntry
mpagenko80622a52021-02-09 16:53:23 +0000102 pOmciCC *omciCC
103 pOnuDB *onuDeviceDB
104 requestEvent OnuDeviceEvent
105 //omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
mpagenkoc26d4c02021-05-06 14:27:57 +0000106 pAdaptFsm *AdapterFsm
107 pImageDsc *voltha.ImageDownload
108 imageBuffer []byte
109 origImageLength uint32 //as also limited by OMCI
110 imageCRC uint32 //as per OMCI - ITU I.363.5 crc
111 imageLength uint32 //including last bytes padding
112 omciDownloadWindowSizeLimit uint8 //windowSize-1 in sections
113 omciDownloadWindowSizeLast uint8 //number of sections in last window
114 noOfSections uint32 //uint32 range for sections should be sufficient for very long images
115 nextDownloadSectionsAbsolute uint32 //number of next section to download in overall image
116 nextDownloadSectionsWindow uint8 //number of next section to download within current window
117 noOfWindows uint32 //uint32 range for windows should be sufficient for very long images
118 nextDownloadWindow uint32 //number of next window to download
119 inactiveImageMeID uint16 //ME-ID of the inactive image
120 downloadToOnuTimeout4MB time.Duration //timeout for downloading the image to the ONU for a 4MB image slice
121 omciSectionInterleaveDelay time.Duration //DownloadSectionInterleave delay in milliseconds
122 delayEndSwDl bool //flag to provide a delay between last section and EndSwDl
123 pLastTxMeInstance *me.ManagedEntity
124 waitCountEndSwDl uint8 //number, how often is waited for EndSwDl at maximum
125 waitDelayEndSwDl time.Duration //duration, how long is waited before next request on EndSwDl
126 chReceiveExpectedResponse chan bool
mpagenkoaa3afe92021-05-21 16:20:58 +0000127 useAPIVersion43 bool //flag for indication on which API version is used (and accordingly which specific methods)
128 mutexUpgradeParams sync.RWMutex //mutex to protect members for parallel function requests and omci response processing
129 imageVersion string //name of the image as used within OMCI (and on extrenal API interface)
130 imageIdentifier string //name of the image as used in the adapter
mpagenkoc26d4c02021-05-06 14:27:57 +0000131 mutexIsAwaitingAdapterDlResponse sync.RWMutex
132 chAdapterDlReady chan bool
133 isWaitingForAdapterDlResponse bool
134 mutexIsAwaitingOnuDlResponse sync.RWMutex
135 chOnuDlReady chan bool
136 isWaitingForOnuDlResponse bool
137 activateImage bool
138 commitImage bool
mpagenkoaa3afe92021-05-21 16:20:58 +0000139 volthaDownloadState voltha.ImageState_ImageDownloadState
140 volthaDownloadReason voltha.ImageState_ImageFailureReason
141 volthaImageState voltha.ImageState_ImageActivationState
mpagenko80622a52021-02-09 16:53:23 +0000142}
143
144//NewOnuUpgradeFsm is the 'constructor' for the state machine to config the PON ANI ports
145// of ONU UNI ports via OMCI
146func NewOnuUpgradeFsm(ctx context.Context, apDeviceHandler *deviceHandler,
mpagenko15ff4a52021-03-02 10:09:20 +0000147 apDevEntry *OnuDeviceEntry, apOnuDB *onuDeviceDB,
mpagenko80622a52021-02-09 16:53:23 +0000148 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message) *OnuUpgradeFsm {
149 instFsm := &OnuUpgradeFsm{
mpagenko59498c12021-03-18 14:15:15 +0000150 pDeviceHandler: apDeviceHandler,
151 deviceID: apDeviceHandler.deviceID,
152 pOnuOmciDevice: apDevEntry,
153 pOmciCC: apDevEntry.PDevOmciCC,
154 pOnuDB: apOnuDB,
155 requestEvent: aRequestEvent,
156 omciDownloadWindowSizeLimit: cOmciDownloadWindowSizeLimit,
157 omciSectionInterleaveDelay: cOmciSectionInterleaveMilliseconds,
Holger Hildebrandtac010732021-06-02 13:35:39 +0000158 downloadToOnuTimeout4MB: apDeviceHandler.pOpenOnuAc.dlToOnuTimeout4M,
mpagenko59498c12021-03-18 14:15:15 +0000159 waitCountEndSwDl: cWaitCountEndSwDl,
160 waitDelayEndSwDl: cWaitDelayEndSwDlSeconds,
mpagenkoaa3afe92021-05-21 16:20:58 +0000161 volthaDownloadState: voltha.ImageState_DOWNLOAD_STARTED, //if FSM created we can assume that the download (to adapter) really started
162 volthaDownloadReason: voltha.ImageState_NO_ERROR,
163 volthaImageState: voltha.ImageState_IMAGE_UNKNOWN,
mpagenko80622a52021-02-09 16:53:23 +0000164 }
mpagenko59498c12021-03-18 14:15:15 +0000165 instFsm.chReceiveExpectedResponse = make(chan bool)
mpagenkoc26d4c02021-05-06 14:27:57 +0000166 instFsm.chAdapterDlReady = make(chan bool)
167 instFsm.chOnuDlReady = make(chan bool)
mpagenko80622a52021-02-09 16:53:23 +0000168
169 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
170 if instFsm.pAdaptFsm == nil {
171 logger.Errorw(ctx, "OnuUpgradeFsm's AdapterFsm could not be instantiated!!", log.Fields{
172 "device-id": instFsm.deviceID})
173 return nil
174 }
175 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
176 upgradeStDisabled,
177 fsm.Events{
178 {Name: upgradeEvStart, Src: []string{upgradeStDisabled}, Dst: upgradeStStarting},
mpagenkoc26d4c02021-05-06 14:27:57 +0000179 {Name: upgradeEvAdapterDownload, Src: []string{upgradeStStarting}, Dst: upgradeStWaitingAdapterDL},
180 {Name: upgradeEvPrepareSwDownload, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL}, Dst: upgradeStPreparingDL},
mpagenko80622a52021-02-09 16:53:23 +0000181 {Name: upgradeEvRxStartSwDownload, Src: []string{upgradeStPreparingDL}, Dst: upgradeStDLSection},
182 {Name: upgradeEvWaitWindowAck, Src: []string{upgradeStDLSection}, Dst: upgradeStVerifyWindow},
183 {Name: upgradeEvContinueNextWindow, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStDLSection},
184 {Name: upgradeEvEndSwDownload, Src: []string{upgradeStVerifyWindow}, Dst: upgradeStFinalizeDL},
mpagenko59498c12021-03-18 14:15:15 +0000185 {Name: upgradeEvWaitEndDownload, Src: []string{upgradeStFinalizeDL}, Dst: upgradeStWaitEndDL},
186 {Name: upgradeEvContinueFinalize, Src: []string{upgradeStWaitEndDL}, Dst: upgradeStFinalizeDL},
mpagenkoc26d4c02021-05-06 14:27:57 +0000187 {Name: upgradeEvWaitForActivate, Src: []string{upgradeStWaitEndDL}, Dst: upgradeStWaitForActivate},
188 {Name: upgradeEvRequestActivate, Src: []string{upgradeStStarting, upgradeStWaitEndDL, upgradeStWaitForActivate},
189 Dst: upgradeStRequestingActivate}, //allows also for direct activation (without download) [TODO!!!]
mpagenko80622a52021-02-09 16:53:23 +0000190 {Name: upgradeEvWaitForCommit, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStWaitForCommit},
191 {Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStWaitForCommit},
mpagenkoc26d4c02021-05-06 14:27:57 +0000192 Dst: upgradeStCommitSw}, //allows also for direct commitment (without download) [TODO!!!]
mpagenko15ff4a52021-03-02 10:09:20 +0000193 {Name: upgradeEvCheckCommitted, Src: []string{upgradeStCommitSw}, Dst: upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000194
195 /*
196 {Name: upgradeEvTimeoutSimple, Src: []string{
197 upgradeStCreatingDot1PMapper, upgradeStCreatingMBPCD, upgradeStSettingTconts, upgradeStSettingDot1PMapper}, Dst: upgradeStStarting},
198 {Name: upgradeEvTimeoutMids, Src: []string{
199 upgradeStCreatingGemNCTPs, upgradeStCreatingGemIWs, upgradeStSettingPQs}, Dst: upgradeStStarting},
200 */
201 // exceptional treatments
mpagenkoc26d4c02021-05-06 14:27:57 +0000202 {Name: upgradeEvReset, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
203 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
204 upgradeStRequestingActivate, upgradeStCommitSw, upgradeStCheckCommitted}, //upgradeStWaitForCommit is not reset (later perhaps also not upgradeStWaitActivate)
mpagenko80622a52021-02-09 16:53:23 +0000205 Dst: upgradeStResetting},
mpagenkoc26d4c02021-05-06 14:27:57 +0000206 {Name: upgradeEvAbort, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
207 upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
208 upgradeStRequestingActivate, upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
mpagenko80622a52021-02-09 16:53:23 +0000209 Dst: upgradeStResetting},
210 {Name: upgradeEvRestart, Src: []string{upgradeStResetting}, Dst: upgradeStDisabled},
211 },
212 fsm.Callbacks{
213 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
214 "enter_" + upgradeStStarting: func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
mpagenkoc26d4c02021-05-06 14:27:57 +0000215 "enter_" + upgradeStWaitingAdapterDL: func(e *fsm.Event) { instFsm.enterWaitingAdapterDL(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000216 "enter_" + upgradeStPreparingDL: func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
217 "enter_" + upgradeStDLSection: func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
218 "enter_" + upgradeStVerifyWindow: func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
219 "enter_" + upgradeStFinalizeDL: func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
mpagenko59498c12021-03-18 14:15:15 +0000220 "enter_" + upgradeStWaitEndDL: func(e *fsm.Event) { instFsm.enterWaitEndDL(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000221 "enter_" + upgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
222 "enter_" + upgradeStCommitSw: func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
mpagenko15ff4a52021-03-02 10:09:20 +0000223 "enter_" + upgradeStCheckCommitted: func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
mpagenko80622a52021-02-09 16:53:23 +0000224 "enter_" + upgradeStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
225 "enter_" + upgradeStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
226 },
227 )
228 if instFsm.pAdaptFsm.pFsm == nil {
229 logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
230 "device-id": instFsm.deviceID})
231 return nil
232 }
233
234 logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
235 return instFsm
236}
237
238//SetDownloadParams configures the needed parameters for a specific download to the ONU
mpagenkoc26d4c02021-05-06 14:27:57 +0000239// called from 'old' API Activate_image_update()
mpagenko15ff4a52021-03-02 10:09:20 +0000240func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
241 apImageDsc *voltha.ImageDownload, apDownloadManager *adapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +0000242 pBaseFsm := oFsm.pAdaptFsm.pFsm
243 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000244 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000245 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
246 "device-id": oFsm.deviceID, "image-description": apImageDsc})
mpagenko15ff4a52021-03-02 10:09:20 +0000247 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
mpagenko80622a52021-02-09 16:53:23 +0000248 oFsm.pImageDsc = apImageDsc
249 oFsm.pDownloadManager = apDownloadManager
Holger Hildebrandtac1e0592021-06-03 15:16:49 +0000250 oFsm.activateImage = true
251 oFsm.commitImage = true
mpagenkoaa3afe92021-05-21 16:20:58 +0000252 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000253
254 go func(aPBaseFsm *fsm.FSM) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000255 // let the upgrade FSM proceed to PreparingDL
mpagenko80622a52021-02-09 16:53:23 +0000256 _ = aPBaseFsm.Event(upgradeEvPrepareSwDownload)
257 }(pBaseFsm)
258 return nil
259 }
260 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
261 "device-id": oFsm.deviceID})
262 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
263}
264
mpagenkoc26d4c02021-05-06 14:27:57 +0000265//SetDownloadParamsAfterDownload configures the needed parameters for a specific download to the ONU according to
266// updated API interface with R2.8: start download to ONU if the image is downloaded to the adapter
267// called from 'new' API Download_onu_image
268func (oFsm *OnuUpgradeFsm) SetDownloadParamsAfterDownload(ctx context.Context, aInactiveImageID uint16,
269 apImageRequest *voltha.DeviceImageDownloadRequest, apDownloadManager *fileDownloadManager,
Holger Hildebrandtac010732021-06-02 13:35:39 +0000270 aImageIdentifier string) error {
mpagenkoc26d4c02021-05-06 14:27:57 +0000271 oFsm.mutexUpgradeParams.Lock()
272 var pBaseFsm *fsm.FSM = nil
273 if oFsm.pAdaptFsm != nil {
274 pBaseFsm = oFsm.pAdaptFsm.pFsm
275 }
276 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
277 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
278 "device-id": oFsm.deviceID, "image-description": apImageRequest})
279 oFsm.useAPIVersion43 = true
280 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
281 oFsm.pFileManager = apDownloadManager
282 oFsm.imageIdentifier = aImageIdentifier
283 oFsm.imageVersion = apImageRequest.Image.Version
284 oFsm.activateImage = apImageRequest.ActivateOnSuccess
285 oFsm.commitImage = apImageRequest.CommitOnSuccess
mpagenkoc26d4c02021-05-06 14:27:57 +0000286 //TODO: currently straightforward options activate and commit are expected to be set and (unconditionally) done
287 // for separate handling of these options the FSM must accordingly branch from the concerned states - later
288 oFsm.mutexUpgradeParams.Unlock()
289 _ = pBaseFsm.Event(upgradeEvAdapterDownload) //no need to call the FSM event in background here
290 return nil
291 }
292 oFsm.mutexUpgradeParams.Unlock()
293 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
294 "device-id": oFsm.deviceID})
295 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
296}
297
298//SetActivationParamsRunning sets the activate and commit flags for a running download to the ONU according to adapters rpc call
299// called from 'new' API Activate_onu_image
300func (oFsm *OnuUpgradeFsm) SetActivationParamsRunning(ctx context.Context,
301 aImageIdentifier string, aCommit bool) error {
302 oFsm.mutexUpgradeParams.Lock()
303 //set activate/commit independent from state, if FSM is already beyond concerned states, then it does not matter anyway
304 // (as long as the Imageidentifier is correct)
305 logger.Debugw(ctx, "OnuUpgradeFsm activate/commit parameter setting", log.Fields{
306 "device-id": oFsm.deviceID, "image-id": aImageIdentifier, "commit": aCommit})
307 if aImageIdentifier != oFsm.imageIdentifier {
308 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
309 "device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
310 oFsm.mutexUpgradeParams.Unlock()
311 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
312 oFsm.deviceID))
313 }
314 oFsm.activateImage = true
315 oFsm.commitImage = aCommit
316 oFsm.mutexUpgradeParams.Unlock()
317 var pBaseFsm *fsm.FSM = nil
318 if oFsm.pAdaptFsm != nil {
319 pBaseFsm = oFsm.pAdaptFsm.pFsm
320 }
321 if pBaseFsm != nil {
322 if pBaseFsm.Is(upgradeStWaitForActivate) {
323 logger.Debugw(ctx, "OnuUpgradeFsm finish waiting for activate", log.Fields{"device-id": oFsm.deviceID})
324 _ = pBaseFsm.Event(upgradeEvRequestActivate) //no need to call the FSM event in background here
325 }
326 return nil
327 }
328 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
329 "device-id": oFsm.deviceID})
330 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
331}
332
333//SetActivationParamsStart starts upgrade processing with immediate activation
334// called from 'new' API Activate_onu_image
335func (oFsm *OnuUpgradeFsm) SetActivationParamsStart(ctx context.Context, aImageVersion string, aInactiveImageID uint16, aCommit bool) error {
336 oFsm.mutexUpgradeParams.Lock()
337 var pBaseFsm *fsm.FSM = nil
338 if oFsm.pAdaptFsm != nil {
339 pBaseFsm = oFsm.pAdaptFsm.pFsm
340 }
341 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
342 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with activation", log.Fields{
343 "device-id": oFsm.deviceID, "image-version": aImageVersion})
344 oFsm.useAPIVersion43 = true
345 oFsm.inactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
346 oFsm.imageVersion = aImageVersion
347 oFsm.activateImage = true
348 oFsm.commitImage = aCommit
349 oFsm.mutexUpgradeParams.Unlock()
350 //directly request the FSM to activate the image
351 _ = pBaseFsm.Event(upgradeEvRequestActivate) //no need to call the FSM event in background here
352 return nil
353 }
354 oFsm.mutexUpgradeParams.Unlock()
355 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
356 "device-id": oFsm.deviceID})
357 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
358}
359
360//SetCommitmentParamsRunning sets the commit flag for a running download to the ONU according to adapters rpc call
361// called from 'new' API Commit_onu_image
362func (oFsm *OnuUpgradeFsm) SetCommitmentParamsRunning(ctx context.Context, aImageIdentifier string) error {
363 oFsm.mutexUpgradeParams.Lock()
364 //set commit independent from state, if FSM is already beyond commit state (just ready), then it does not matter anyway
365 // (as long as the Imageidentifier is correct)
366 logger.Debugw(ctx, "OnuUpgradeFsm commit parameter setting", log.Fields{
367 "device-id": oFsm.deviceID, "image-id": aImageIdentifier})
368 if aImageIdentifier != oFsm.imageIdentifier {
369 logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
370 "device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
371 oFsm.mutexUpgradeParams.Unlock()
372 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
373 oFsm.deviceID))
374 }
375 oFsm.commitImage = true
376 oFsm.mutexUpgradeParams.Unlock()
377 var pBaseFsm *fsm.FSM = nil
378 if oFsm.pAdaptFsm != nil {
379 pBaseFsm = oFsm.pAdaptFsm.pFsm
380 }
381 if pBaseFsm != nil {
382 if pBaseFsm.Is(upgradeStWaitForCommit) {
383 logger.Debugw(ctx, "OnuUpgradeFsm finish waiting for commit", log.Fields{"device-id": oFsm.deviceID})
384 _ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
385 }
386 return nil
387 }
388 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
389 "device-id": oFsm.deviceID})
390 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
391}
392
393//SetCommitmentParamsStart starts upgrade processing with immediate commitment
394// called from 'new' API Commit_onu_image
395func (oFsm *OnuUpgradeFsm) SetCommitmentParamsStart(ctx context.Context, aImageVersion string, aActiveImageID uint16) error {
396 oFsm.mutexUpgradeParams.Lock()
397 var pBaseFsm *fsm.FSM = nil
398 if oFsm.pAdaptFsm != nil {
399 pBaseFsm = oFsm.pAdaptFsm.pFsm
400 }
401 if pBaseFsm != nil && pBaseFsm.Is(upgradeStStarting) {
402 logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with commitment", log.Fields{
403 "device-id": oFsm.deviceID, "image-version": aImageVersion})
404 oFsm.useAPIVersion43 = true
405 oFsm.inactiveImageMeID = aActiveImageID //upgrade state machines inactive ImageId is the new active ImageId
406 oFsm.imageVersion = aImageVersion
407 oFsm.commitImage = true
408 oFsm.mutexUpgradeParams.Unlock()
409 //directly request the FSM to activate the image
410 _ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
411 return nil
412 }
413 oFsm.mutexUpgradeParams.Unlock()
414 logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
415 "device-id": oFsm.deviceID})
416 return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
417}
418
mpagenkoaa3afe92021-05-21 16:20:58 +0000419//GetImageStates delivers the download states as per device proto buf or error indication
420func (oFsm *OnuUpgradeFsm) GetImageStates(ctx context.Context,
421 aImageIdentifier string, aVersion string) (*voltha.ImageState, error) {
422 pImageState := &voltha.ImageState{}
423 // check if the request refers to some active image/version of the processing
424 oFsm.mutexUpgradeParams.RLock()
425 if (aImageIdentifier == oFsm.imageIdentifier) || (aVersion == oFsm.imageVersion) {
426 pImageState.DownloadState = oFsm.volthaDownloadState
427 pImageState.Reason = oFsm.volthaDownloadReason
428 pImageState.ImageState = oFsm.volthaImageState
429 } else {
430 pImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
431 pImageState.Reason = voltha.ImageState_NO_ERROR
432 pImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
433 }
434 oFsm.mutexUpgradeParams.RUnlock()
435 return pImageState, nil
436}
437
mpagenkoc26d4c02021-05-06 14:27:57 +0000438//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
439func (oFsm *OnuUpgradeFsm) CancelProcessing(ctx context.Context) {
440 //mutex protection is required for possible concurrent access to FSM members
441 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
442 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
443 oFsm.mutexIsAwaitingAdapterDlResponse.RLock()
444 if oFsm.isWaitingForAdapterDlResponse {
445 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
446 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
447 oFsm.chAdapterDlReady <- false
448 } else {
449 oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
450 }
451 //chOnuDlReady is cleared as part of the FSM reset processing (from enterResetting())
452
453 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
454 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
455 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
456 pAdaptFsm := oFsm.pAdaptFsm
457 if pAdaptFsm != nil {
458 // calling FSM events in background to avoid blocking of the caller
459 go func(aPAFsm *AdapterFsm) {
460 if aPAFsm.pFsm != nil {
461 if aPAFsm.pFsm.Is(upgradeStWaitEndDL) {
462 oFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
463 }
464 _ = aPAFsm.pFsm.Event(upgradeEvReset) //anyway and for all other states
465 } //else the FSM seems already to be in some released state
466 }(pAdaptFsm)
467 }
468}
469
mpagenko80622a52021-02-09 16:53:23 +0000470func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
471 logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
472 "device-id": oFsm.deviceID})
473
474 // start go routine for processing of LockState messages
475 go oFsm.processOmciUpgradeMessages(ctx)
476}
477
mpagenkoc26d4c02021-05-06 14:27:57 +0000478//enterWaitingAdapterDL state can only be reached with useAPIVersion43
479func (oFsm *OnuUpgradeFsm) enterWaitingAdapterDL(ctx context.Context, e *fsm.Event) {
480 logger.Debugw(ctx, "OnuUpgradeFsm waiting for adapter download", log.Fields{"in state": e.FSM.Current(),
481 "device-id": oFsm.deviceID})
482 go oFsm.waitOnDownloadToAdapterReady(ctx, oFsm.chAdapterDlReady)
483 go oFsm.pFileManager.RequestDownloadReady(ctx, oFsm.imageIdentifier, oFsm.chAdapterDlReady)
484}
485
mpagenko80622a52021-02-09 16:53:23 +0000486func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
487 logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
488 "device-id": oFsm.deviceID})
489
mpagenkoc26d4c02021-05-06 14:27:57 +0000490 var fileLen int64
491 var err error
mpagenkoaa3afe92021-05-21 16:20:58 +0000492 oFsm.mutexUpgradeParams.Lock()
mpagenkoc26d4c02021-05-06 14:27:57 +0000493 if oFsm.useAPIVersion43 {
494 //with the new API structure download to adapter is implicit and we have to wait until the image is available
495 fileLen, err = oFsm.pFileManager.GetImageBufferLen(ctx, oFsm.imageIdentifier)
496 } else {
497 fileLen, err = oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
498 }
mpagenko80622a52021-02-09 16:53:23 +0000499 if err != nil || fileLen > int64(cMaxUint32) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000500 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000501 logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
502 "device-id": oFsm.deviceID, "error": err, "length": fileLen})
503 pBaseFsm := oFsm.pAdaptFsm
504 // Can't call FSM Event directly, decoupling it
505 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000506 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000507 }(pBaseFsm)
508 return
509 }
510
mpagenkoc26d4c02021-05-06 14:27:57 +0000511 //copy file content to buffer
mpagenko80622a52021-02-09 16:53:23 +0000512 oFsm.imageBuffer = make([]byte, fileLen)
mpagenkoc26d4c02021-05-06 14:27:57 +0000513 if oFsm.useAPIVersion43 {
514 oFsm.imageBuffer, err = oFsm.pFileManager.GetDownloadImageBuffer(ctx, oFsm.imageIdentifier)
515 } else {
516 oFsm.imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
517 }
mpagenko80622a52021-02-09 16:53:23 +0000518 if err != nil {
mpagenkoaa3afe92021-05-21 16:20:58 +0000519 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000520 logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
521 "device-id": oFsm.deviceID, "error": err})
522 pBaseFsm := oFsm.pAdaptFsm
523 // Can't call FSM Event directly, decoupling it
524 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000525 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000526 }(pBaseFsm)
527 return
528 }
529
530 oFsm.noOfSections = uint32(fileLen / cOmciDownloadSectionSize)
531 if fileLen%cOmciDownloadSectionSize > 0 {
mpagenkoc26d4c02021-05-06 14:27:57 +0000532 bufferPadding := make([]byte, cOmciDownloadSectionSize-uint32((fileLen)%cOmciDownloadSectionSize))
mpagenko80622a52021-02-09 16:53:23 +0000533 //expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
mpagenkoc26d4c02021-05-06 14:27:57 +0000534 oFsm.imageBuffer = append(oFsm.imageBuffer[:(fileLen)], bufferPadding...)
mpagenko80622a52021-02-09 16:53:23 +0000535 oFsm.noOfSections++
536 }
537 oFsm.origImageLength = uint32(fileLen)
538 oFsm.imageLength = uint32(len(oFsm.imageBuffer))
mpagenko80622a52021-02-09 16:53:23 +0000539 logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
540 "MeId": oFsm.inactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
541 "ImageSize": oFsm.imageLength, "original file size": fileLen})
542 //"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
mpagenkoaa3afe92021-05-21 16:20:58 +0000543
544 oFsm.mutexUpgradeParams.Unlock()
545 go oFsm.waitOnDownloadToOnuReady(ctx, oFsm.chOnuDlReady) // start supervision of the complete download-to-ONU procedure
546
Girish Gowdra0b235842021-03-09 13:06:46 -0800547 err = oFsm.pOmciCC.sendStartSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000548 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength)
549 if err != nil {
550 logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
551 "device-id": oFsm.deviceID, "error": err})
552 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
553 pBaseFsm := oFsm.pAdaptFsm
554 // Can't call FSM Event directly, decoupling it
555 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000556 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000557 }(pBaseFsm)
558 return
559 }
560}
561
562func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
563 logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
564 "device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
565
566 var windowAckRequest uint8 = 0
567 var bufferStartOffset uint32
568 var bufferEndOffset uint32
569 var downloadSection []byte
570 framePrint := false //default no printing of downloadSection frames
mpagenkoaa3afe92021-05-21 16:20:58 +0000571 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000572 if oFsm.nextDownloadSectionsAbsolute == 0 {
573 //debug print of first section frame
574 framePrint = true
mpagenkoaa3afe92021-05-21 16:20:58 +0000575 oFsm.volthaImageState = voltha.ImageState_IMAGE_DOWNLOADING
mpagenko80622a52021-02-09 16:53:23 +0000576 }
577
578 for {
579 bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * cOmciDownloadSectionSize
580 bufferEndOffset = bufferStartOffset + cOmciDownloadSectionSize - 1 //for representing cOmciDownloadSectionSizeLimit values
581 logger.Debugw(ctx, "DlSection values are", log.Fields{
582 "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
583 "DlSectionWindow": oFsm.nextDownloadSectionsWindow,
584 "startOffset": bufferStartOffset, "endOffset": bufferEndOffset})
585 if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
586 logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
587 "device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
588 "bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
mpagenkoaa3afe92021-05-21 16:20:58 +0000589 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000590 //logical error -- reset the FSM
591 pBaseFsm := oFsm.pAdaptFsm
592 // Can't call FSM Event directly, decoupling it
593 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000594 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000595 }(pBaseFsm)
596 return
597 }
598 downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
599 if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
600 windowAckRequest = 1
601 logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
602 "device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
603 }
604 if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
605 windowAckRequest = 1
606 framePrint = true //debug print of last frame
mpagenko15ff4a52021-03-02 10:09:20 +0000607 oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
608 logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000609 "device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
610 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000611 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 -0800612 err := oFsm.pOmciCC.sendDownloadSection(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000613 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, framePrint)
614 if err != nil {
615 logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
mpagenko15ff4a52021-03-02 10:09:20 +0000616 "device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
mpagenko80622a52021-02-09 16:53:23 +0000617 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
618 pBaseFsm := oFsm.pAdaptFsm
619 // Can't call FSM Event directly, decoupling it
620 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000621 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000622 }(pBaseFsm)
623 return
624 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000625 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000626 oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
627 if windowAckRequest == 1 {
628 pBaseFsm := oFsm.pAdaptFsm
629 // Can't call FSM Event directly, decoupling it
mpagenkoaa3afe92021-05-21 16:20:58 +0000630 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000631 go func(a_pAFsm *AdapterFsm) {
632 _ = a_pAFsm.pFsm.Event(upgradeEvWaitWindowAck) //state transition to upgradeStVerifyWindow
633 }(pBaseFsm)
634 return
635 }
636 framePrint = false //for the next Section frame (if wanted, can be enabled in logic before sendXXX())
637 oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
mpagenko59498c12021-03-18 14:15:15 +0000638 if oFsm.omciSectionInterleaveDelay > 0 {
mpagenko80622a52021-02-09 16:53:23 +0000639 //ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
mpagenkoaa3afe92021-05-21 16:20:58 +0000640 oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
mpagenko59498c12021-03-18 14:15:15 +0000641 time.Sleep(oFsm.omciSectionInterleaveDelay * time.Millisecond)
mpagenkoaa3afe92021-05-21 16:20:58 +0000642 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000643 }
644 }
645}
646
647func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
648 logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
649 "for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
650}
651
652func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
mpagenko80622a52021-02-09 16:53:23 +0000653 logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
mpagenko59498c12021-03-18 14:15:15 +0000654 "device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(oFsm.imageCRC), 16), "delay": oFsm.delayEndSwDl})
mpagenko80622a52021-02-09 16:53:23 +0000655
mpagenkoaa3afe92021-05-21 16:20:58 +0000656 oFsm.mutexUpgradeParams.RLock()
mpagenko80622a52021-02-09 16:53:23 +0000657 if oFsm.delayEndSwDl {
mpagenkoaa3afe92021-05-21 16:20:58 +0000658 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +0000659 //give the ONU some time for image evaluation (hoping it does not base that on first EndSwDl itself)
660 // should not be set in case this state is used for real download abort (not yet implemented)
661 time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
mpagenkoaa3afe92021-05-21 16:20:58 +0000662 } else {
663 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +0000664 }
665
mpagenko59498c12021-03-18 14:15:15 +0000666 pBaseFsm := oFsm.pAdaptFsm
667 if pBaseFsm == nil {
668 logger.Errorw(ctx, "EndSwDl abort: BaseFsm invalid", log.Fields{
669 "device-id": oFsm.deviceID})
670 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
671 // Can't call FSM Event directly, decoupling it
672 go func(a_pAFsm *AdapterFsm) {
673 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
674 }(pBaseFsm)
675 return
676 }
Girish Gowdra0b235842021-03-09 13:06:46 -0800677 err := oFsm.pOmciCC.sendEndSoftwareDownload(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko59498c12021-03-18 14:15:15 +0000678 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID, oFsm.origImageLength, oFsm.imageCRC)
mpagenko80622a52021-02-09 16:53:23 +0000679 if err != nil {
680 logger.Errorw(ctx, "EndSwDl abort: can't send section", log.Fields{
681 "device-id": oFsm.deviceID, "error": err})
682 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
mpagenko80622a52021-02-09 16:53:23 +0000683 // Can't call FSM Event directly, decoupling it
684 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000685 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000686 }(pBaseFsm)
687 return
688 }
mpagenko59498c12021-03-18 14:15:15 +0000689 // go waiting for the EndSwDLResponse and check, if the ONU is ready for activation
690 // Can't call FSM Event directly, decoupling it
691 go func(a_pAFsm *AdapterFsm) {
692 _ = a_pAFsm.pFsm.Event(upgradeEvWaitEndDownload)
693 }(pBaseFsm)
694}
695
696func (oFsm *OnuUpgradeFsm) enterWaitEndDL(ctx context.Context, e *fsm.Event) {
697 logger.Infow(ctx, "OnuUpgradeFsm WaitEndDl", log.Fields{
698 "device-id": oFsm.deviceID, "wait delay": oFsm.waitDelayEndSwDl * time.Second, "wait count": oFsm.waitCountEndSwDl})
699 if oFsm.waitCountEndSwDl == 0 {
700 logger.Errorw(ctx, "WaitEndDl abort: max limit of EndSwDL reached", log.Fields{
701 "device-id": oFsm.deviceID})
702 pBaseFsm := oFsm.pAdaptFsm
703 if pBaseFsm == nil {
704 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
705 "device-id": oFsm.deviceID})
706 return
707 }
708 go func(a_pAFsm *AdapterFsm) {
709 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
710 }(pBaseFsm)
711 return
712 }
713
714 oFsm.waitCountEndSwDl--
715 select {
716 case <-time.After(oFsm.waitDelayEndSwDl * time.Second):
717 pBaseFsm := oFsm.pAdaptFsm
718 if pBaseFsm == nil {
719 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
720 "device-id": oFsm.deviceID})
721 //FSM may be reset already from somewhere else, nothing we can do here anymore
722 return
723 }
724 //retry End SW DL
mpagenkoaa3afe92021-05-21 16:20:58 +0000725 oFsm.mutexUpgradeParams.Lock()
mpagenko59498c12021-03-18 14:15:15 +0000726 oFsm.delayEndSwDl = false //no more extra delay for the request
mpagenkoaa3afe92021-05-21 16:20:58 +0000727 oFsm.mutexUpgradeParams.Unlock()
mpagenko59498c12021-03-18 14:15:15 +0000728 go func(a_pAFsm *AdapterFsm) {
729 _ = a_pAFsm.pFsm.Event(upgradeEvContinueFinalize)
730 }(pBaseFsm)
731 return
732 case success := <-oFsm.chReceiveExpectedResponse:
733 logger.Debugw(ctx, "WaitEndDl stop wait timer", log.Fields{"device-id": oFsm.deviceID})
734 pBaseFsm := oFsm.pAdaptFsm
735 if pBaseFsm == nil {
736 logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
737 "device-id": oFsm.deviceID})
738 //FSM may be reset already from somewhere else, nothing we can do here anymore
739 return
740 }
741 if success {
742 //answer received with ready indication
mpagenkoc26d4c02021-05-06 14:27:57 +0000743 if oFsm.activateImage {
744 //immediate activation requested
745 go func(a_pAFsm *AdapterFsm) {
746 _ = a_pAFsm.pFsm.Event(upgradeEvRequestActivate)
747 }(pBaseFsm)
748 } else {
749 //have to wait on explicit activation request
750 go func(a_pAFsm *AdapterFsm) {
751 _ = a_pAFsm.pFsm.Event(upgradeEvWaitForActivate)
752 }(pBaseFsm)
753 }
mpagenko59498c12021-03-18 14:15:15 +0000754 return
755 }
756 //timer was aborted
757 go func(a_pAFsm *AdapterFsm) {
758 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
759 }(pBaseFsm)
760 return
761 }
mpagenko80622a52021-02-09 16:53:23 +0000762}
763
764func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
765 logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
766 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
767
mpagenkoaa3afe92021-05-21 16:20:58 +0000768 oFsm.mutexUpgradeParams.Lock()
769 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVATING
770 oFsm.mutexUpgradeParams.Unlock()
771
Girish Gowdra0b235842021-03-09 13:06:46 -0800772 err := oFsm.pOmciCC.sendActivateSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenko80622a52021-02-09 16:53:23 +0000773 oFsm.pAdaptFsm.commChan, oFsm.inactiveImageMeID)
774 if err != nil {
775 logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
776 "device-id": oFsm.deviceID, "error": err})
777 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
778 pBaseFsm := oFsm.pAdaptFsm
779 // Can't call FSM Event directly, decoupling it
780 go func(a_pAFsm *AdapterFsm) {
mpagenko15ff4a52021-03-02 10:09:20 +0000781 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000782 }(pBaseFsm)
783 return
784 }
785}
786
787func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
mpagenko15ff4a52021-03-02 10:09:20 +0000788 if activeImageID, err := oFsm.pOnuOmciDevice.GetActiveImageMeID(ctx); err == nil {
789 //TODO!!: as long as testing with BBSIM and BBSIM not support upgrade tests following check needs to be deactivated
790 imageFit := true //TODO!!: test workaround as long as BBSIM does not fully support upgrade
mpagenkoaa3afe92021-05-21 16:20:58 +0000791 oFsm.mutexUpgradeParams.Lock()
mpagenko15ff4a52021-03-02 10:09:20 +0000792 if imageFit || activeImageID == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +0000793 inactiveImageID := oFsm.inactiveImageMeID
mpagenko15ff4a52021-03-02 10:09:20 +0000794 logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
mpagenkoaa3afe92021-05-21 16:20:58 +0000795 "device-id": oFsm.deviceID, "me-id": inactiveImageID}) //more efficient activeImageID with above check
796 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTING
797 oFsm.mutexUpgradeParams.Unlock()
Girish Gowdra0b235842021-03-09 13:06:46 -0800798 err := oFsm.pOmciCC.sendCommitSoftware(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false,
mpagenkoaa3afe92021-05-21 16:20:58 +0000799 oFsm.pAdaptFsm.commChan, inactiveImageID) //more efficient activeImageID with above check
mpagenko15ff4a52021-03-02 10:09:20 +0000800 if err != nil {
801 logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
802 "device-id": oFsm.deviceID, "error": err})
803 //TODO!!!: define some more sophisticated error treatment with some repetition, for now just reset the FSM
804 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
805 pBaseFsm := oFsm.pAdaptFsm
806 // Can't call FSM Event directly, decoupling it
807 go func(a_pAFsm *AdapterFsm) {
808 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
809 }(pBaseFsm)
810 return
811 }
812 return
813 }
814 logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
815 "device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.inactiveImageMeID})
mpagenkoaa3afe92021-05-21 16:20:58 +0000816 oFsm.mutexUpgradeParams.Unlock()
817
mpagenko15ff4a52021-03-02 10:09:20 +0000818 //TODO!!!: possibly send event information for aborted upgrade (not activated)??
819 pBaseFsm := oFsm.pAdaptFsm
820 // Can't call FSM Event directly, decoupling it
821 go func(a_pAFsm *AdapterFsm) {
822 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
823 }(pBaseFsm)
824 return
825 }
826 logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
827 "device-id": oFsm.deviceID})
828 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
829 pBaseFsm := oFsm.pAdaptFsm
830 // Can't call FSM Event directly, decoupling it
831 go func(a_pAFsm *AdapterFsm) {
832 _ = a_pAFsm.pFsm.Event(upgradeEvAbort)
833 }(pBaseFsm)
834}
835
836func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
837 logger.Infow(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +0000838 "device-id": oFsm.deviceID, "me-id": oFsm.inactiveImageMeID})
mpagenko15ff4a52021-03-02 10:09:20 +0000839 requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
ozgecanetsiab36ed572021-04-01 10:38:48 +0300840 meInstance, err := oFsm.pOmciCC.sendGetMe(log.WithSpanFromContext(context.TODO(), ctx),
Girish Gowdra0b235842021-03-09 13:06:46 -0800841 me.SoftwareImageClassID, oFsm.inactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, false, oFsm.pAdaptFsm.commChan)
mpagenko15ff4a52021-03-02 10:09:20 +0000842 //accept also nil as (error) return value for writing to LastTx
843 // - this avoids misinterpretation of new received OMCI messages
ozgecanetsiab36ed572021-04-01 10:38:48 +0300844 if err != nil {
845 logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
846 log.Fields{"device-id": oFsm.deviceID, "Error": err})
847 pOnuUpgradeFsm := oFsm.pAdaptFsm
848 if pOnuUpgradeFsm != nil {
849 go func(a_pAFsm *AdapterFsm) {
850 _ = a_pAFsm.pFsm.Event(upgradeEvReset)
851 }(pOnuUpgradeFsm)
852 }
853 return
854 }
mpagenko15ff4a52021-03-02 10:09:20 +0000855 oFsm.pLastTxMeInstance = meInstance
mpagenko80622a52021-02-09 16:53:23 +0000856}
857
858func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
859 logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
860
mpagenkoc26d4c02021-05-06 14:27:57 +0000861 // in case the download-to-ONU timer is still running - cancel it
862 oFsm.mutexIsAwaitingOnuDlResponse.RLock()
863 if oFsm.isWaitingForOnuDlResponse {
864 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
865 //use channel to indicate that the download response waiting shall be aborted for this device (channel)
866 oFsm.chOnuDlReady <- false
867 } else {
868 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
869 }
870
mpagenko80622a52021-02-09 16:53:23 +0000871 pConfigupgradeStateAFsm := oFsm.pAdaptFsm
872 if pConfigupgradeStateAFsm != nil {
873 // abort running message processing
874 fsmAbortMsg := Message{
875 Type: TestMsg,
876 Data: TestMessage{
877 TestMessageVal: AbortMessageProcessing,
878 },
879 }
880 pConfigupgradeStateAFsm.commChan <- fsmAbortMsg
881
882 //try to restart the FSM to 'disabled'
883 // Can't call FSM Event directly, decoupling it
884 go func(a_pAFsm *AdapterFsm) {
885 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
886 _ = a_pAFsm.pFsm.Event(upgradeEvRestart)
887 }
888 }(pConfigupgradeStateAFsm)
889 }
890}
891
892func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
893 logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +0000894 // 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 +0000895 if oFsm.pDeviceHandler != nil {
896 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
897 go oFsm.pDeviceHandler.removeOnuUpgradeFsm(ctx)
898 }
899}
900
901func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
902 logger.Debugw(ctx, "Start OnuUpgradeFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
903loop:
904 for {
905 // case <-ctx.Done():
906 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
907 // break loop
908 message, ok := <-oFsm.pAdaptFsm.commChan
909 if !ok {
910 logger.Info(ctx, "OnuUpgradeFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
911 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
mpagenko15ff4a52021-03-02 10:09:20 +0000912 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000913 break loop
914 }
915 logger.Debugw(ctx, "OnuUpgradeFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
916
917 switch message.Type {
918 case TestMsg:
919 msg, _ := message.Data.(TestMessage)
920 if msg.TestMessageVal == AbortMessageProcessing {
921 logger.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
922 break loop
923 }
924 logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
925 case OMCI:
926 msg, _ := message.Data.(OmciMessage)
927 oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
928 default:
929 logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
930 "message.Type": message.Type})
931 }
932 }
933 logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
934}
935
936//nolint: gocyclo
937func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg OmciMessage) {
938 logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
939 "msgType": msg.OmciMsg.MessageType})
940
941 switch msg.OmciMsg.MessageType {
942 case omci.StartSoftwareDownloadResponseType:
943 {
944 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
945 if msgLayer == nil {
946 logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
947 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000948 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
949 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000950 return
951 }
952 msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
953 if !msgOk {
954 logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
955 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000956 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
957 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000958 return
959 }
960 logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
961 "device-id": oFsm.deviceID, "data-fields": msgObj})
962 if msgObj.Result != me.Success {
963 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
964 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
965 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +0000966 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
967 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +0000968 return
969 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000970
971 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +0000972 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
973 logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
974 if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
975 // also response WindowSize = 0 is a valid number for used Window size 1
976 logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
977 "acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
978 oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
979 }
980 oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
981 if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
982 oFsm.noOfWindows++
983 }
984 logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
985 "windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
986 "at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
987 oFsm.nextDownloadSectionsAbsolute = 0
988 oFsm.nextDownloadSectionsWindow = 0
989 oFsm.nextDownloadWindow = 0
990
mpagenkoaa3afe92021-05-21 16:20:58 +0000991 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000992 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvRxStartSwDownload)
993 return
994 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000995 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +0000996 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
997 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
998 // TODO!!!: possibly repeat the start request (once)?
mpagenko15ff4a52021-03-02 10:09:20 +0000999 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1000 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001001 return
1002 } //StartSoftwareDownloadResponseType
1003 case omci.DownloadSectionResponseType:
1004 {
mpagenko80622a52021-02-09 16:53:23 +00001005 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
1006 if msgLayer == nil {
1007 logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
1008 log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
mpagenko15ff4a52021-03-02 10:09:20 +00001009 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1010 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001011 return
1012 }
1013 msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
1014 if !msgOk {
1015 logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
1016 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001017 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1018 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001019 return
1020 }
1021 logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
1022 "device-id": oFsm.deviceID, "data-fields": msgObj})
1023 if msgObj.Result != me.Success {
1024 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
1025 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenko15ff4a52021-03-02 10:09:20 +00001026 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1027 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001028 return
1029 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001030 oFsm.mutexUpgradeParams.Lock()
mpagenko80622a52021-02-09 16:53:23 +00001031 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
1032 sectionNumber := msgObj.SectionNumber
mpagenko15ff4a52021-03-02 10:09:20 +00001033 logger.Infow(ctx, "DlSectionResponse received", log.Fields{
1034 "window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +00001035
mpagenko15ff4a52021-03-02 10:09:20 +00001036 oFsm.nextDownloadWindow++
1037 if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
1038 if sectionNumber != oFsm.omciDownloadWindowSizeLast {
mpagenko02cf1b22021-03-12 17:30:30 +00001039 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error last window - later: repeat window once?", //TODO!!!
mpagenko15ff4a52021-03-02 10:09:20 +00001040 log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
1041 "expected section": oFsm.omciDownloadWindowSizeLast})
1042 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
mpagenkoaa3afe92021-05-21 16:20:58 +00001043 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001044 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1045 return
1046 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001047 oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
1048 //CRC computation for all data bytes of the file
1049 imageCRC := crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //store internal for multiple usage
1050 //revert the retrieved CRC Byte Order (seems not to deliver NetworkByteOrder)
1051 var byteSlice []byte = make([]byte, 4)
1052 binary.LittleEndian.PutUint32(byteSlice, uint32(imageCRC))
1053 oFsm.imageCRC = binary.BigEndian.Uint32(byteSlice)
mpagenkoaa3afe92021-05-21 16:20:58 +00001054 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001055 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvEndSwDownload)
1056 return
1057 }
1058 if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
1059 logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
mpagenko02cf1b22021-03-12 17:30:30 +00001060 log.Fields{"device-id": oFsm.deviceID, "actual-section": sectionNumber,
1061 "expected section": oFsm.omciDownloadWindowSizeLimit})
mpagenkoaa3afe92021-05-21 16:20:58 +00001062 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001063 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1064 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1065 return
1066 }
1067 oFsm.nextDownloadSectionsWindow = 0
mpagenkoaa3afe92021-05-21 16:20:58 +00001068 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001069 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvContinueNextWindow)
mpagenko80622a52021-02-09 16:53:23 +00001070 return
1071 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001072 oFsm.mutexUpgradeParams.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001073 logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
1074 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +00001075 // TODO!!!: possibly repeat the download (section) (once)?
1076 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1077 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001078 return
mpagenko80622a52021-02-09 16:53:23 +00001079 } //DownloadSectionResponseType
1080 case omci.EndSoftwareDownloadResponseType:
1081 {
1082 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
1083 if msgLayer == nil {
1084 logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
1085 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001086 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1087 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001088 return
1089 }
1090 msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
1091 if !msgOk {
1092 logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
1093 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001094 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1095 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001096 return
1097 }
1098 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
1099 "device-id": oFsm.deviceID, "data-fields": msgObj})
1100 if msgObj.Result != me.Success {
mpagenko59498c12021-03-18 14:15:15 +00001101 if msgObj.Result == me.DeviceBusy {
1102 //ONU indicates it is still processing the image - let the FSM just wait and then repeat the request
1103 logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse busy: waiting before sending new request", log.Fields{
1104 "device-id": oFsm.deviceID})
1105 return
1106 }
mpagenko80622a52021-02-09 16:53:23 +00001107 logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - later: drive FSM to abort state ?",
1108 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1109 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
mpagenko15ff4a52021-03-02 10:09:20 +00001110 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1111 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001112 return
1113 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001114 oFsm.mutexUpgradeParams.RLock()
mpagenko80622a52021-02-09 16:53:23 +00001115 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +00001116 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +00001117 logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001118 oFsm.mutexIsAwaitingOnuDlResponse.RLock()
1119 if oFsm.isWaitingForOnuDlResponse {
1120 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
1121 //use channel to indicate that the download to ONU was successful
1122 oFsm.chOnuDlReady <- true
1123 } else {
1124 oFsm.mutexIsAwaitingOnuDlResponse.RUnlock()
1125 }
mpagenko59498c12021-03-18 14:15:15 +00001126 oFsm.chReceiveExpectedResponse <- true //let the FSM proceed from the waitState
mpagenko80622a52021-02-09 16:53:23 +00001127 return
1128 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001129 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +00001130 logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
1131 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1132 // TODO!!!: possibly repeat the end request (once)? or verify ONU upgrade state?
mpagenko15ff4a52021-03-02 10:09:20 +00001133 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1134 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001135 return
1136 } //EndSoftwareDownloadResponseType
1137 case omci.ActivateSoftwareResponseType:
1138 {
1139 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
1140 if msgLayer == nil {
1141 logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
1142 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001143 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1144 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001145 return
1146 }
1147 msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
1148 if !msgOk {
1149 logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
1150 log.Fields{"device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001151 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1152 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001153 return
1154 }
1155 logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
1156 "device-id": oFsm.deviceID, "data-fields": msgObj})
1157 if msgObj.Result != me.Success {
1158 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
1159 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1160 // TODO!!!: error treatment?, perhaps in the end reset the FSM
mpagenko15ff4a52021-03-02 10:09:20 +00001161 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1162 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
mpagenko80622a52021-02-09 16:53:23 +00001163 return
1164 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001165 oFsm.mutexUpgradeParams.RLock()
mpagenko80622a52021-02-09 16:53:23 +00001166 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +00001167 oFsm.mutexUpgradeParams.RUnlock()
mpagenko02cf1b22021-03-12 17:30:30 +00001168 logger.Infow(ctx, "Expected ActivateSwResponse received", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +00001169 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
1170 return
1171 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001172 oFsm.mutexUpgradeParams.RUnlock()
mpagenko80622a52021-02-09 16:53:23 +00001173 logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
1174 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
mpagenko15ff4a52021-03-02 10:09:20 +00001175 // TODO!!!: error treatment?
1176 //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 } //ActivateSoftwareResponseType
mpagenko15ff4a52021-03-02 10:09:20 +00001180 case omci.CommitSoftwareResponseType:
1181 {
1182 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
1183 if msgLayer == nil {
1184 logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
1185 log.Fields{"device-id": oFsm.deviceID})
1186 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1187 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1188 return
1189 }
1190 msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
1191 if !msgOk {
1192 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
1193 log.Fields{"device-id": oFsm.deviceID})
1194 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1195 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1196 return
1197 }
mpagenkobf67a092021-03-17 09:52:28 +00001198 if msgObj.Result != me.Success {
mpagenko15ff4a52021-03-02 10:09:20 +00001199 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
1200 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1201 // TODO!!!: error treatment?, perhaps in the end reset the FSM
1202 return
mpagenkobf67a092021-03-17 09:52:28 +00001203 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001204 oFsm.mutexUpgradeParams.RLock()
mpagenko15ff4a52021-03-02 10:09:20 +00001205 if msgObj.EntityInstance == oFsm.inactiveImageMeID {
mpagenkoaa3afe92021-05-21 16:20:58 +00001206 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001207 logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
1208 //verifying committed image
1209 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvCheckCommitted)
1210 return
1211 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001212 oFsm.mutexUpgradeParams.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001213 logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse wrong ME instance: abort",
1214 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1215 // TODO!!!: error treatment?
1216 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1217 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1218 return
1219 } //CommitSoftwareResponseType
1220 case omci.GetResponseType:
1221 {
1222 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
1223 if msgLayer == nil {
1224 logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
1225 log.Fields{"device-id": oFsm.deviceID})
1226 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1227 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1228 return
1229 }
1230 msgObj, msgOk := msgLayer.(*omci.GetResponse)
1231 if !msgOk {
1232 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
1233 log.Fields{"device-id": oFsm.deviceID})
1234 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1235 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1236 return
1237 }
1238 logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
1239 "device-id": oFsm.deviceID, "data-fields": msgObj})
1240 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1241 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1242 if msgObj.Result != me.Success {
1243 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
1244 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1245 // TODO!!!: error treatment?, perhaps in the end reset the FSM
1246 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1247 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1248 return
1249 }
1250 } else {
1251 logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
1252 log.Fields{"device-id": oFsm.deviceID})
1253 return
1254 }
1255
1256 meAttributes := msgObj.Attributes
1257 imageIsCommitted := meAttributes["IsCommitted"].(uint8)
1258 imageIsActive := meAttributes["IsActive"].(uint8)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001259 imageVersion := TrimStringFromMeOctet(meAttributes["Version"])
mpagenko02cf1b22021-03-12 17:30:30 +00001260 logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
mpagenko15ff4a52021-03-02 10:09:20 +00001261 log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
1262 "version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
mpagenkoaa3afe92021-05-21 16:20:58 +00001263
1264 oFsm.mutexUpgradeParams.Lock()
1265 if msgObj.EntityInstance == oFsm.inactiveImageMeID && imageIsActive == swIsActive {
mpagenkoc26d4c02021-05-06 14:27:57 +00001266 //a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
1267 // indicated in the download image version string (version must be part of the image content itself)
1268 // so checking that might be quite unreliable
1269 //but with new API this was changed, assumption is that omci image version is known at download request and exactly that is used
1270 // in all the API references, so it can and should be checked here now
1271 if oFsm.useAPIVersion43 {
1272 if imageVersion != oFsm.imageVersion {
1273 //new active version indicated on OMCI from ONU is not the expected version
1274 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1275 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance,
1276 "onu-version": imageVersion, "expected-version": oFsm.imageVersion})
mpagenkoaa3afe92021-05-21 16:20:58 +00001277 oFsm.mutexUpgradeParams.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001278 // TODO!!!: error treatment?
1279 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1280 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1281 return
1282 }
1283 logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU",
1284 log.Fields{"device-id": oFsm.deviceID})
1285 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001286 oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVE
1287 if imageIsCommitted == swIsCommitted {
1288 oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1289 oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTED
1290 logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
1291 oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent)) //to let the handler now about success
1292 oFsm.mutexUpgradeParams.Unlock()
1293 //releasing the upgrade FSM
1294 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvReset)
1295 return
1296 }
1297 oFsm.mutexUpgradeParams.Unlock()
1298 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 +00001299 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001300 oFsm.mutexUpgradeParams.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001301 logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
1302 log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
1303 // TODO!!!: error treatment?
1304 //TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
1305 _ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
1306 return
1307 } //GetResponseType
mpagenko80622a52021-02-09 16:53:23 +00001308 default:
1309 {
1310 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
1311 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
1312 return
1313 }
1314 }
1315}
1316
mpagenkoc26d4c02021-05-06 14:27:57 +00001317//waitOnDownloadToAdapterReady state can only be reached with useAPIVersion43 (usage of pFileManager)
1318func (oFsm *OnuUpgradeFsm) waitOnDownloadToAdapterReady(ctx context.Context, aWaitChannel chan bool) {
1319 downloadToAdapterTimeout := oFsm.pFileManager.GetDownloadTimeout(ctx)
1320 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1321 oFsm.isWaitingForAdapterDlResponse = true
1322 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
mpagenko80622a52021-02-09 16:53:23 +00001323 select {
1324 // maybe be also some outside cancel (but no context modeled for the moment ...)
1325 // case <-ctx.Done():
mpagenkoc26d4c02021-05-06 14:27:57 +00001326 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToAdapterReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1327 case <-time.After(downloadToAdapterTimeout): //10s should be enough for downloading some image to the adapter
1328 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-adapter-download timeout", log.Fields{
1329 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToAdapterTimeout})
1330 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
1331 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1332 oFsm.isWaitingForAdapterDlResponse = false
1333 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1334 //the upgrade process has to be aborted
1335 pUpgradeFsm := oFsm.pAdaptFsm
1336 if pUpgradeFsm != nil {
1337 _ = pUpgradeFsm.pFsm.Event(upgradeEvReset)
1338 } else {
1339 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
mpagenko80622a52021-02-09 16:53:23 +00001340 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001341 return
1342
1343 case success := <-aWaitChannel:
1344 if success {
1345 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded received", log.Fields{"device-id": oFsm.deviceID})
1346 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1347 oFsm.isWaitingForAdapterDlResponse = false
1348 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1349 //let the upgrade process proceed
1350 pUpgradeFsm := oFsm.pAdaptFsm
1351 if pUpgradeFsm != nil {
1352 _ = pUpgradeFsm.pFsm.Event(upgradeEvPrepareSwDownload)
1353 } else {
1354 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1355 }
1356 return
1357 }
1358 // waiting was aborted (probably on external request)
1359 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-adapter-download aborted", log.Fields{"device-id": oFsm.deviceID})
1360 oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
1361 oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
1362 oFsm.isWaitingForAdapterDlResponse = false
1363 oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
1364 //the upgrade process has to be aborted
1365 pUpgradeFsm := oFsm.pAdaptFsm
1366 if pUpgradeFsm != nil {
1367 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
1368 } else {
1369 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1370 }
1371 return
mpagenko80622a52021-02-09 16:53:23 +00001372 }
1373}
mpagenkoc26d4c02021-05-06 14:27:57 +00001374
1375//waitOnDownloadToOnuReady state can only be reached with useAPIVersion43 (usage of pFileManager)
1376func (oFsm *OnuUpgradeFsm) waitOnDownloadToOnuReady(ctx context.Context, aWaitChannel chan bool) {
1377 downloadToOnuTimeout := time.Duration(1+(oFsm.imageLength/0x400000)) * oFsm.downloadToOnuTimeout4MB
1378 logger.Debugw(ctx, "OnuUpgradeFsm start download-to-ONU timer", log.Fields{"device-id": oFsm.deviceID,
1379 "duration": downloadToOnuTimeout})
1380 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1381 oFsm.isWaitingForOnuDlResponse = true
1382 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1383 select {
1384 // maybe be also some outside cancel (but no context modeled for the moment ...)
1385 // case <-ctx.Done():
1386 // logger.Infow("OnuUpgradeFsm-waitOnDownloadToOnuReady canceled", log.Fields{"for device-id": oFsm.deviceID})
1387 case <-time.After(downloadToOnuTimeout): //using an image-size depending timout (in minutes)
1388 logger.Warnw(ctx, "OnuUpgradeFsm Waiting-ONU-download timeout", log.Fields{
1389 "for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToOnuTimeout})
1390 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1391 oFsm.isWaitingForOnuDlResponse = false
1392 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1393 //the upgrade process has to be aborted
1394 pUpgradeFsm := oFsm.pAdaptFsm
1395 if pUpgradeFsm != nil {
1396 _ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
1397 } else {
1398 logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
1399 }
1400 return
1401
1402 case success := <-aWaitChannel:
1403 if success {
1404 logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded on ONU received", log.Fields{"device-id": oFsm.deviceID})
1405 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1406 oFsm.isWaitingForOnuDlResponse = false
1407 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1408 //all fine, let the FSM proceed like defined from the sender of this event
1409 return
1410 }
1411 // waiting was aborted (assumed here to be caused by
1412 // error detection or cancel at download after upgrade FSM reset/abort)
1413 logger.Debugw(ctx, "OnuUpgradeFsm Waiting-ONU-download aborted", log.Fields{"device-id": oFsm.deviceID})
1414 oFsm.mutexIsAwaitingOnuDlResponse.Lock()
1415 oFsm.isWaitingForOnuDlResponse = false
1416 oFsm.mutexIsAwaitingOnuDlResponse.Unlock()
1417 return
1418 }
1419}