blob: 5188e56b5c10c1c174875f38cdaadc5a070c6f72 [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 (
npujar1d86a522019-11-14 17:11:16 +053020 "github.com/opencord/voltha-go/rw_core/coreif"
Scott Baker807addd2019-10-24 15:16:21 -070021 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Scott Baker555307d2019-11-04 08:58:01 -080022 "github.com/opencord/voltha-protos/v2/go/voltha"
khenaidoob9203542018-09-17 22:56:37 -040023)
24
npujar1d86a522019-11-14 17:11:16 +053025// DeviceType mentions type of device like parent, child
khenaidoob9203542018-09-17 22:56:37 -040026type DeviceType int32
27
28const (
29 parent DeviceType = 0
30 child DeviceType = 1
31 any DeviceType = 2
32)
33
npujar1d86a522019-11-14 17:11:16 +053034// DeviceState has admin, operational and connection status of device
khenaidoob9203542018-09-17 22:56:37 -040035type DeviceState struct {
36 Admin voltha.AdminState_AdminState
37 Connection voltha.ConnectStatus_ConnectStatus
38 Operational voltha.OperStatus_OperStatus
39}
40
npujar1d86a522019-11-14 17:11:16 +053041// TransitionHandler function type which takes device as input parameter
khenaidoo92e62c52018-10-03 14:02:54 -040042type TransitionHandler func(*voltha.Device) error
khenaidoob9203542018-09-17 22:56:37 -040043
npujar1d86a522019-11-14 17:11:16 +053044// Transition represent transition related attributes
khenaidoob9203542018-09-17 22:56:37 -040045type Transition struct {
46 deviceType DeviceType
47 previousState DeviceState
48 currentState DeviceState
khenaidoo92e62c52018-10-03 14:02:54 -040049 handlers []TransitionHandler
khenaidoob9203542018-09-17 22:56:37 -040050}
51
npujar1d86a522019-11-14 17:11:16 +053052// TransitionMap represent map of transitions and device manager
khenaidoob9203542018-09-17 22:56:37 -040053type TransitionMap struct {
54 transitions []Transition
npujar1d86a522019-11-14 17:11:16 +053055 dMgr coreif.DeviceManager
khenaidoob9203542018-09-17 22:56:37 -040056}
57
npujar1d86a522019-11-14 17:11:16 +053058// NewTransitionMap creates transition map
59func NewTransitionMap(dMgr coreif.DeviceManager) *TransitionMap {
khenaidoob9203542018-09-17 22:56:37 -040060 var transitionMap TransitionMap
khenaidoo0a822f92019-05-08 15:15:57 -040061 transitionMap.dMgr = dMgr
khenaidoob9203542018-09-17 22:56:37 -040062 transitionMap.transitions = make([]Transition, 0)
khenaidoob9203542018-09-17 22:56:37 -040063 transitionMap.transitions = append(transitionMap.transitions,
64 Transition{
khenaidoob9203542018-09-17 22:56:37 -040065 deviceType: parent,
khenaidoo59ef7be2019-06-21 12:40:28 -040066 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
67 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
khenaidoo0a822f92019-05-08 15:15:57 -040068 handlers: []TransitionHandler{dMgr.CreateLogicalDevice}})
69 transitionMap.transitions = append(transitionMap.transitions,
70 Transition{
khenaidoo59ef7be2019-06-21 12:40:28 -040071 deviceType: child,
72 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
73 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
74 handlers: []TransitionHandler{dMgr.SetupUNILogicalPorts}})
khenaidoob9203542018-09-17 22:56:37 -040075 transitionMap.transitions = append(transitionMap.transitions,
76 Transition{
77 deviceType: child,
khenaidoo59ef7be2019-06-21 12:40:28 -040078 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
79 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
khenaidoo0a822f92019-05-08 15:15:57 -040080 handlers: []TransitionHandler{dMgr.SetupUNILogicalPorts}})
khenaidoob9203542018-09-17 22:56:37 -040081 transitionMap.transitions = append(transitionMap.transitions,
82 Transition{
khenaidoo4554f7c2019-05-29 22:13:15 -040083 deviceType: any,
84 previousState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
85 currentState: DeviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
86 handlers: []TransitionHandler{dMgr.RunPostDeviceDelete}})
87 transitionMap.transitions = append(transitionMap.transitions,
88 Transition{
khenaidoo4d4802d2018-10-04 21:59:49 -040089 deviceType: parent,
khenaidoob9203542018-09-17 22:56:37 -040090 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
khenaidoo4d4802d2018-10-04 21:59:49 -040091 currentState: DeviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
Devmalya Paul84169b52019-08-27 19:31:44 -040092 handlers: []TransitionHandler{dMgr.DisableAllChildDevices, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.RunPostDeviceDelete}})
khenaidoo0a822f92019-05-08 15:15:57 -040093 transitionMap.transitions = append(transitionMap.transitions,
94 Transition{
95 deviceType: child,
96 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
97 currentState: DeviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
98 handlers: []TransitionHandler{dMgr.DeleteLogicalPorts, dMgr.RunPostDeviceDelete}})
khenaidoob9203542018-09-17 22:56:37 -040099 transitionMap.transitions = append(transitionMap.transitions,
100 Transition{
101 deviceType: any,
khenaidoo59ef7be2019-06-21 12:40:28 -0400102 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
103 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
104 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
105 transitionMap.transitions = append(transitionMap.transitions,
106 Transition{
107 deviceType: any,
108 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
109 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
110 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
111 transitionMap.transitions = append(transitionMap.transitions,
112 Transition{
113 deviceType: any,
114 previousState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
115 currentState: DeviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
116 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
117 transitionMap.transitions = append(transitionMap.transitions,
118 Transition{
119 deviceType: any,
120 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
121 currentState: DeviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
122 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
123 transitionMap.transitions = append(transitionMap.transitions,
124 Transition{
125 deviceType: any,
126 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
127 currentState: DeviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
128 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
129 transitionMap.transitions = append(transitionMap.transitions,
130 Transition{
131 deviceType: parent,
132 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
133 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
134 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
135 transitionMap.transitions = append(transitionMap.transitions,
136 Transition{
137 deviceType: any,
138 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
139 currentState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
140 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
141 transitionMap.transitions = append(transitionMap.transitions,
142 Transition{
143 deviceType: any,
144 previousState: DeviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
145 currentState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
146 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
147 transitionMap.transitions = append(transitionMap.transitions,
148 Transition{
149 deviceType: child,
150 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
151 currentState: DeviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
152 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
153 transitionMap.transitions = append(transitionMap.transitions,
154 Transition{
155 deviceType: any,
156 previousState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
157 currentState: DeviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
158 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
159 transitionMap.transitions = append(transitionMap.transitions,
160 Transition{
161 deviceType: any,
khenaidoob9203542018-09-17 22:56:37 -0400162 previousState: DeviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
163 currentState: DeviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
khenaidoo0a822f92019-05-08 15:15:57 -0400164 handlers: []TransitionHandler{dMgr.NotifyInvalidTransition}})
khenaidoob9203542018-09-17 22:56:37 -0400165
166 return &transitionMap
167}
168
169func getDeviceStates(device *voltha.Device) *DeviceState {
170 return &DeviceState{Admin: device.AdminState, Connection: device.ConnectStatus, Operational: device.OperStatus}
171}
172
173// 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 -0400174func getHandler(previous *DeviceState, current *DeviceState, transition *Transition) ([]TransitionHandler, bool) {
khenaidoob9203542018-09-17 22:56:37 -0400175
176 // Do we have an exact match?
177 if *previous == transition.previousState && *current == transition.currentState {
khenaidoo92e62c52018-10-03 14:02:54 -0400178 return transition.handlers, true
khenaidoob9203542018-09-17 22:56:37 -0400179 }
khenaidoo0a822f92019-05-08 15:15:57 -0400180
181 // Admin states must match
182 if previous.Admin != transition.previousState.Admin || current.Admin != transition.currentState.Admin {
183 return nil, false
184 }
185
khenaidoob9203542018-09-17 22:56:37 -0400186 // If the admin state changed then prioritize it first
187 if previous.Admin != current.Admin {
188 if previous.Admin == transition.previousState.Admin && current.Admin == transition.currentState.Admin {
khenaidoo92e62c52018-10-03 14:02:54 -0400189 return transition.handlers, false
khenaidoob9203542018-09-17 22:56:37 -0400190 }
191 }
192 // If the operational state changed then prioritize it in second position
193 if previous.Operational != current.Operational {
194 if previous.Operational == transition.previousState.Operational && current.Operational == transition.currentState.Operational {
khenaidoo92e62c52018-10-03 14:02:54 -0400195 return transition.handlers, false
khenaidoob9203542018-09-17 22:56:37 -0400196 }
197 }
198 // If the connection state changed then prioritize it in third position
199 if previous.Connection != current.Connection {
200 if previous.Connection == transition.previousState.Connection && current.Connection == transition.currentState.Connection {
khenaidoo92e62c52018-10-03 14:02:54 -0400201 return transition.handlers, false
khenaidoob9203542018-09-17 22:56:37 -0400202 }
203 }
204 return nil, false
205}
206
npujar1d86a522019-11-14 17:11:16 +0530207// GetTransitionHandler returns transition handler
khenaidoo92e62c52018-10-03 14:02:54 -0400208func (tMap *TransitionMap) GetTransitionHandler(pDevice *voltha.Device, cDevice *voltha.Device) []TransitionHandler {
khenaidoob9203542018-09-17 22:56:37 -0400209 //1. Get the previous and current set of states
210 pState := getDeviceStates(pDevice)
211 cState := getDeviceStates(cDevice)
khenaidoo92e62c52018-10-03 14:02:54 -0400212 //log.Infow("DeviceType", log.Fields{"device": pDevice})
khenaidoob9203542018-09-17 22:56:37 -0400213 deviceType := parent
214 if !pDevice.Root {
215 log.Info("device is child")
216 deviceType = child
217 }
218 log.Infof("deviceType:%d-deviceId:%s-previous:%v-current:%v", deviceType, pDevice.Id, pState, cState)
219
220 //2. Go over transition array to get the right transition
khenaidoo92e62c52018-10-03 14:02:54 -0400221 var currentMatch []TransitionHandler
222 var tempHandler []TransitionHandler
khenaidoo0a822f92019-05-08 15:15:57 -0400223 var exactStateMatch bool
224 var stateMatchFound bool
khenaidoob9203542018-09-17 22:56:37 -0400225 for _, aTransition := range tMap.transitions {
226 // consider transition only if it matches deviceType or is a wild card - any
227 if aTransition.deviceType != deviceType && aTransition.deviceType != any {
228 continue
229 }
khenaidoo0a822f92019-05-08 15:15:57 -0400230 tempHandler, exactStateMatch = getHandler(pState, cState, &aTransition)
khenaidoob9203542018-09-17 22:56:37 -0400231 if tempHandler != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400232 if exactStateMatch && aTransition.deviceType == deviceType {
khenaidoob9203542018-09-17 22:56:37 -0400233 return tempHandler
khenaidoo0a822f92019-05-08 15:15:57 -0400234 } else if exactStateMatch {
235 currentMatch = tempHandler
236 stateMatchFound = true
237 } else if currentMatch == nil && !stateMatchFound {
238 currentMatch = tempHandler
khenaidoob9203542018-09-17 22:56:37 -0400239 }
240 }
241 }
242 return currentMatch
243}