blob: 7756bf4fa2de27f2cc6192b1fa171d88fb689bc8 [file] [log] [blame]
khenaidoob9203542018-09-17 22:56:37 -04001/*
2 * Copyright 2018-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 */
npujar1d86a522019-11-14 17:11:16 +053016
khenaidoob9203542018-09-17 22:56:37 -040017package core
18
19import (
npujar467fe752020-01-16 20:17:45 +053020 "context"
npujar1d86a522019-11-14 17:11:16 +053021 "github.com/opencord/voltha-go/rw_core/coreif"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080022 "github.com/opencord/voltha-lib-go/v3/pkg/log"
23 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoob9203542018-09-17 22:56:37 -040024)
25
npujar1d86a522019-11-14 17:11:16 +053026// DeviceType mentions type of device like parent, child
khenaidoob9203542018-09-17 22:56:37 -040027type DeviceType int32
28
29const (
30 parent DeviceType = 0
31 child DeviceType = 1
32 any DeviceType = 2
33)
34
npujar1d86a522019-11-14 17:11:16 +053035// DeviceState has admin, operational and connection status of device
khenaidoob9203542018-09-17 22:56:37 -040036type DeviceState struct {
serkant.uluderya2ae470f2020-01-21 11:13:09 -080037 Admin voltha.AdminState_Types
38 Connection voltha.ConnectStatus_Types
39 Operational voltha.OperStatus_Types
khenaidoob9203542018-09-17 22:56:37 -040040}
41
npujar1d86a522019-11-14 17:11:16 +053042// TransitionHandler function type which takes device as input parameter
npujar467fe752020-01-16 20:17:45 +053043type TransitionHandler func(context.Context, *voltha.Device) error
khenaidoob9203542018-09-17 22:56:37 -040044
npujar1d86a522019-11-14 17:11:16 +053045// Transition represent transition related attributes
khenaidoob9203542018-09-17 22:56:37 -040046type Transition struct {
47 deviceType DeviceType
48 previousState DeviceState
49 currentState DeviceState
khenaidoo92e62c52018-10-03 14:02:54 -040050 handlers []TransitionHandler
khenaidoob9203542018-09-17 22:56:37 -040051}
52
npujar1d86a522019-11-14 17:11:16 +053053// TransitionMap represent map of transitions and device manager
khenaidoob9203542018-09-17 22:56:37 -040054type TransitionMap struct {
55 transitions []Transition
npujar1d86a522019-11-14 17:11:16 +053056 dMgr coreif.DeviceManager
khenaidoob9203542018-09-17 22:56:37 -040057}
58
npujar1d86a522019-11-14 17:11:16 +053059// NewTransitionMap creates transition map
60func NewTransitionMap(dMgr coreif.DeviceManager) *TransitionMap {
khenaidoob9203542018-09-17 22:56:37 -040061 var transitionMap TransitionMap
khenaidoo0a822f92019-05-08 15:15:57 -040062 transitionMap.dMgr = dMgr
khenaidoob9203542018-09-17 22:56:37 -040063 transitionMap.transitions = make([]Transition, 0)
khenaidoob9203542018-09-17 22:56:37 -040064 transitionMap.transitions = append(transitionMap.transitions,
65 Transition{
khenaidoob9203542018-09-17 22:56:37 -040066 deviceType: parent,
khenaidoo59ef7be2019-06-21 12:40:28 -040067 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
68 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
khenaidoo0a822f92019-05-08 15:15:57 -040069 handlers: []TransitionHandler{dMgr.CreateLogicalDevice}})
70 transitionMap.transitions = append(transitionMap.transitions,
71 Transition{
khenaidoo59ef7be2019-06-21 12:40:28 -040072 deviceType: child,
73 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
74 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
75 handlers: []TransitionHandler{dMgr.SetupUNILogicalPorts}})
khenaidoob9203542018-09-17 22:56:37 -040076 transitionMap.transitions = append(transitionMap.transitions,
77 Transition{
78 deviceType: child,
khenaidoo59ef7be2019-06-21 12:40:28 -040079 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
80 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
khenaidoo0a822f92019-05-08 15:15:57 -040081 handlers: []TransitionHandler{dMgr.SetupUNILogicalPorts}})
khenaidoob9203542018-09-17 22:56:37 -040082 transitionMap.transitions = append(transitionMap.transitions,
83 Transition{
khenaidoo4554f7c2019-05-29 22:13:15 -040084 deviceType: any,
85 previousState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
86 currentState: DeviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
87 handlers: []TransitionHandler{dMgr.RunPostDeviceDelete}})
88 transitionMap.transitions = append(transitionMap.transitions,
89 Transition{
khenaidoo4d4802d2018-10-04 21:59:49 -040090 deviceType: parent,
khenaidoob9203542018-09-17 22:56:37 -040091 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
khenaidoo4d4802d2018-10-04 21:59:49 -040092 currentState: DeviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
Devmalya Paul84169b52019-08-27 19:31:44 -040093 handlers: []TransitionHandler{dMgr.DisableAllChildDevices, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.RunPostDeviceDelete}})
khenaidoo0a822f92019-05-08 15:15:57 -040094 transitionMap.transitions = append(transitionMap.transitions,
95 Transition{
96 deviceType: child,
97 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
98 currentState: DeviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
99 handlers: []TransitionHandler{dMgr.DeleteLogicalPorts, dMgr.RunPostDeviceDelete}})
khenaidoob9203542018-09-17 22:56:37 -0400100 transitionMap.transitions = append(transitionMap.transitions,
101 Transition{
102 deviceType: any,
khenaidoo59ef7be2019-06-21 12:40:28 -0400103 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
104 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
105 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
106 transitionMap.transitions = append(transitionMap.transitions,
107 Transition{
108 deviceType: any,
109 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
110 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
111 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
112 transitionMap.transitions = append(transitionMap.transitions,
113 Transition{
114 deviceType: any,
115 previousState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
116 currentState: DeviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
117 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
118 transitionMap.transitions = append(transitionMap.transitions,
119 Transition{
120 deviceType: any,
121 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
122 currentState: DeviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
123 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
124 transitionMap.transitions = append(transitionMap.transitions,
125 Transition{
126 deviceType: any,
127 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
128 currentState: DeviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
129 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
130 transitionMap.transitions = append(transitionMap.transitions,
131 Transition{
132 deviceType: parent,
133 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
134 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
135 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
136 transitionMap.transitions = append(transitionMap.transitions,
137 Transition{
138 deviceType: any,
139 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
140 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
141 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
142 transitionMap.transitions = append(transitionMap.transitions,
143 Transition{
144 deviceType: any,
145 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
146 currentState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
147 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
148 transitionMap.transitions = append(transitionMap.transitions,
149 Transition{
150 deviceType: child,
151 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
152 currentState: DeviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
153 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
154 transitionMap.transitions = append(transitionMap.transitions,
155 Transition{
156 deviceType: any,
157 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
158 currentState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
159 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
160 transitionMap.transitions = append(transitionMap.transitions,
161 Transition{
162 deviceType: any,
khenaidoob9203542018-09-17 22:56:37 -0400163 previousState: DeviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
164 currentState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
khenaidoo0a822f92019-05-08 15:15:57 -0400165 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
khenaidoob9203542018-09-17 22:56:37 -0400166
167 return &transitionMap
168}
169
170func getDeviceStates(device *voltha.Device) *DeviceState {
171 return &DeviceState{Admin: device.AdminState, Connection: device.ConnectStatus, Operational: device.OperStatus}
172}
173
174// isMatched matches a state transition. It returns whether there is a match and if there is whether it is an exact match
khenaidoo92e62c52018-10-03 14:02:54 -0400175func getHandler(previous *DeviceState, current *DeviceState, transition *Transition) ([]TransitionHandler, bool) {
khenaidoob9203542018-09-17 22:56:37 -0400176
177 // Do we have an exact match?
178 if *previous == transition.previousState && *current == transition.currentState {
khenaidoo92e62c52018-10-03 14:02:54 -0400179 return transition.handlers, true
khenaidoob9203542018-09-17 22:56:37 -0400180 }
khenaidoo0a822f92019-05-08 15:15:57 -0400181
182 // Admin states must match
183 if previous.Admin != transition.previousState.Admin || current.Admin != transition.currentState.Admin {
184 return nil, false
185 }
186
khenaidoob9203542018-09-17 22:56:37 -0400187 // If the admin state changed then prioritize it first
188 if previous.Admin != current.Admin {
189 if previous.Admin == transition.previousState.Admin && current.Admin == transition.currentState.Admin {
khenaidoo92e62c52018-10-03 14:02:54 -0400190 return transition.handlers, false
khenaidoob9203542018-09-17 22:56:37 -0400191 }
192 }
193 // If the operational state changed then prioritize it in second position
194 if previous.Operational != current.Operational {
195 if previous.Operational == transition.previousState.Operational && current.Operational == transition.currentState.Operational {
khenaidoo92e62c52018-10-03 14:02:54 -0400196 return transition.handlers, false
khenaidoob9203542018-09-17 22:56:37 -0400197 }
198 }
199 // If the connection state changed then prioritize it in third position
200 if previous.Connection != current.Connection {
201 if previous.Connection == transition.previousState.Connection && current.Connection == transition.currentState.Connection {
khenaidoo92e62c52018-10-03 14:02:54 -0400202 return transition.handlers, false
khenaidoob9203542018-09-17 22:56:37 -0400203 }
204 }
205 return nil, false
206}
207
npujar1d86a522019-11-14 17:11:16 +0530208// GetTransitionHandler returns transition handler
khenaidoo92e62c52018-10-03 14:02:54 -0400209func (tMap *TransitionMap) GetTransitionHandler(pDevice *voltha.Device, cDevice *voltha.Device) []TransitionHandler {
khenaidoob9203542018-09-17 22:56:37 -0400210 //1. Get the previous and current set of states
211 pState := getDeviceStates(pDevice)
212 cState := getDeviceStates(cDevice)
khenaidoo92e62c52018-10-03 14:02:54 -0400213 //log.Infow("DeviceType", log.Fields{"device": pDevice})
khenaidoob9203542018-09-17 22:56:37 -0400214 deviceType := parent
215 if !pDevice.Root {
216 log.Info("device is child")
217 deviceType = child
218 }
219 log.Infof("deviceType:%d-deviceId:%s-previous:%v-current:%v", deviceType, pDevice.Id, pState, cState)
220
221 //2. Go over transition array to get the right transition
khenaidoo92e62c52018-10-03 14:02:54 -0400222 var currentMatch []TransitionHandler
223 var tempHandler []TransitionHandler
khenaidoo0a822f92019-05-08 15:15:57 -0400224 var exactStateMatch bool
225 var stateMatchFound bool
khenaidoob9203542018-09-17 22:56:37 -0400226 for _, aTransition := range tMap.transitions {
227 // consider transition only if it matches deviceType or is a wild card - any
228 if aTransition.deviceType != deviceType && aTransition.deviceType != any {
229 continue
230 }
khenaidoo0a822f92019-05-08 15:15:57 -0400231 tempHandler, exactStateMatch = getHandler(pState, cState, &aTransition)
khenaidoob9203542018-09-17 22:56:37 -0400232 if tempHandler != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400233 if exactStateMatch && aTransition.deviceType == deviceType {
khenaidoob9203542018-09-17 22:56:37 -0400234 return tempHandler
khenaidoo0a822f92019-05-08 15:15:57 -0400235 } else if exactStateMatch {
236 currentMatch = tempHandler
237 stateMatchFound = true
238 } else if currentMatch == nil && !stateMatchFound {
239 currentMatch = tempHandler
khenaidoob9203542018-09-17 22:56:37 -0400240 }
241 }
242 }
243 return currentMatch
244}