blob: 61b1c0b5724ef15fa24732e468da190a5aa8872c [file] [log] [blame]
khenaidood2b6df92018-12-13 16:37:20 -05001/*
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 */
16package adaptercore
17
18import (
19 "context"
khenaidoo54544ae2019-03-18 13:22:39 -040020 "fmt"
khenaidood2b6df92018-12-13 16:37:20 -050021 "github.com/gogo/protobuf/proto"
22 com "github.com/opencord/voltha-go/adapters/common"
23 "github.com/opencord/voltha-go/common/log"
William Kurkiandaa6bb22019-03-07 12:26:28 -050024 ic "github.com/opencord/voltha-protos/go/inter_container"
25 of "github.com/opencord/voltha-protos/go/openflow_13"
26 "github.com/opencord/voltha-protos/go/voltha"
khenaidood2b6df92018-12-13 16:37:20 -050027 "strconv"
28 "strings"
29 "sync"
khenaidoo0a822f92019-05-08 15:15:57 -040030 "time"
khenaidood2b6df92018-12-13 16:37:20 -050031)
32
33//DeviceHandler follows the same patterns as ponsim_olt. The only difference is that it does not
34// interact with an OLT device.
35type DeviceHandler struct {
36 deviceId string
37 deviceType string
38 device *voltha.Device
39 coreProxy *com.CoreProxy
40 simulatedOLT *SimulatedONU
41 uniPort *voltha.Port
42 ponPort *voltha.Port
43 exitChannel chan int
44 lockDevice sync.RWMutex
45}
46
47//NewDeviceHandler creates a new device handler
48func NewDeviceHandler(cp *com.CoreProxy, device *voltha.Device, adapter *SimulatedONU) *DeviceHandler {
49 var dh DeviceHandler
50 dh.coreProxy = cp
51 cloned := (proto.Clone(device)).(*voltha.Device)
52 dh.deviceId = cloned.Id
53 dh.deviceType = cloned.Type
54 dh.device = cloned
55 dh.simulatedOLT = adapter
56 dh.exitChannel = make(chan int, 1)
57 dh.lockDevice = sync.RWMutex{}
58 return &dh
59}
60
61// start save the device to the data model
62func (dh *DeviceHandler) start(ctx context.Context) {
63 dh.lockDevice.Lock()
64 defer dh.lockDevice.Unlock()
65 log.Debugw("starting-device-agent", log.Fields{"device": dh.device})
66 // Add the initial device to the local model
67 log.Debug("device-agent-started")
68}
69
70// stop stops the device dh. Not much to do for now
71func (dh *DeviceHandler) stop(ctx context.Context) {
72 dh.lockDevice.Lock()
73 defer dh.lockDevice.Unlock()
74 log.Debug("stopping-device-agent")
75 dh.exitChannel <- 1
76 log.Debug("device-agent-stopped")
77}
78
79func macAddressToUint32Array(mac string) []uint32 {
80 slist := strings.Split(mac, ":")
81 result := make([]uint32, len(slist))
82 var err error
83 var tmp int64
84 for index, val := range slist {
85 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
86 return []uint32{1, 2, 3, 4, 5, 6}
87 }
88 result[index] = uint32(tmp)
89 }
90 return result
91}
92
93func (dh *DeviceHandler) AdoptDevice(device *voltha.Device) {
94 log.Debugw("AdoptDevice", log.Fields{"deviceId": device.Id})
95
96 // Update the device info
97 cloned := proto.Clone(device).(*voltha.Device)
98 cloned.Root = false
99 cloned.Vendor = "simulators"
100 cloned.Model = "go-simulators"
khenaidoocee54fd2019-03-06 12:03:03 -0500101 //cloned.SerialNumber = com.GetRandomSerialNumber()
khenaidood2b6df92018-12-13 16:37:20 -0500102 cloned.MacAddress = strings.ToUpper(com.GetRandomMacAddress())
103
104 // Synchronous call to update device - this method is run in its own go routine
105 if err := dh.coreProxy.DeviceUpdate(nil, cloned); err != nil {
106 log.Errorw("error-updating-device", log.Fields{"deviceId": device.Id, "error": err})
107 }
108
khenaidoo0a822f92019-05-08 15:15:57 -0400109 // Update the device state to DISCOVERED
110 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
111 cloned.OperStatus = voltha.OperStatus_DISCOVERED
112 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
113 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
114 }
115
116 // Sleep to mimic the omci management channel creation with the OLT
117 time.Sleep(10 * time.Millisecond)
118
119 // Update the device state to ACTIVATING
120 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
121 cloned.OperStatus = voltha.OperStatus_ACTIVATING
122 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
123 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
124 }
125
126 // Sleep to mimic the omci discovery ( usually takes a few seconds but for ease of simulated environment we are
127 // setting it to 100ms only.
128 time.Sleep(100 * time.Millisecond)
129
khenaidoo54544ae2019-03-18 13:22:39 -0400130 // Use the channel Id, assigned by the parent device to me, as the port number
131 uni_port := uint32(2)
132 if device.ProxyAddress != nil {
133 if device.ProxyAddress.ChannelId != 0 {
134 uni_port = device.ProxyAddress.ChannelId
135 }
136 }
137
138 // Now create the UNI Port
khenaidood2b6df92018-12-13 16:37:20 -0500139 dh.uniPort = &voltha.Port{
khenaidoo54544ae2019-03-18 13:22:39 -0400140 PortNo: uni_port,
141 Label: fmt.Sprintf("uni-%d", uni_port),
khenaidood2b6df92018-12-13 16:37:20 -0500142 Type: voltha.Port_ETHERNET_UNI,
143 AdminState: voltha.AdminState_ENABLED,
144 OperStatus: voltha.OperStatus_ACTIVE,
145 }
146
147 // Synchronous call to update device - this method is run in its own go routine
148 if err := dh.coreProxy.PortCreated(nil, cloned.Id, dh.uniPort); err != nil {
149 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
150 }
khenaidooce5969c2019-04-26 12:07:21 -0400151 // use Pon port number on which this ONU has been detected
152 ponPortNo := uint32(1)
153 if device.ParentPortNo != 0 {
154 ponPortNo = device.ParentPortNo
mkoodali252f7672019-03-25 12:13:12 +0530155 }
khenaidood2b6df92018-12-13 16:37:20 -0500156 // Now create the PON Port
157 dh.ponPort = &voltha.Port{
mkoodali252f7672019-03-25 12:13:12 +0530158 PortNo: ponPortNo,
159 Label: fmt.Sprintf("pon-%d", ponPortNo),
khenaidood2b6df92018-12-13 16:37:20 -0500160 Type: voltha.Port_PON_ONU,
161 AdminState: voltha.AdminState_ENABLED,
162 OperStatus: voltha.OperStatus_ACTIVE,
mkoodali252f7672019-03-25 12:13:12 +0530163 Peers: []*voltha.Port_PeerPort{{DeviceId: cloned.ParentId, // Peer device is OLT
khenaidoo2c6a0992019-04-29 13:46:56 -0400164 PortNo: uni_port}}, // Peer port is UNI port
khenaidood2b6df92018-12-13 16:37:20 -0500165 }
166
167 // Synchronous call to update device - this method is run in its own go routine
168 if err := dh.coreProxy.PortCreated(nil, cloned.Id, dh.ponPort); err != nil {
169 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
170 }
171
172 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
173 cloned.OperStatus = voltha.OperStatus_ACTIVE
174
175 // Update the device state
176 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
177 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
178 }
179
180 dh.device = cloned
181}
182
183func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
184 cap := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
185 return &ic.PortCapability{
186 Port: &voltha.LogicalPort{
187 OfpPort: &of.OfpPort{
188 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
189 Config: 0,
190 State: uint32(of.OfpPortState_OFPPS_LIVE),
191 Curr: cap,
192 Advertised: cap,
193 Peer: cap,
194 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
195 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
196 },
197 DeviceId: dh.device.Id,
198 DevicePortNo: uint32(portNo),
199 },
200 }, nil
201}
202
203func (dh *DeviceHandler) Process_inter_adapter_message(msg *ic.InterAdapterMessage) error {
204 log.Debugw("Process_inter_adapter_message", log.Fields{"msgId": msg.Header.Id})
205 return nil
206}
khenaidoo3ab34882019-05-02 21:33:30 -0400207
208func (dh *DeviceHandler) DisableDevice(device *voltha.Device) {
209 cloned := proto.Clone(device).(*voltha.Device)
210 // Update the all ports state on that device to disable
211 if err := dh.coreProxy.PortsStateUpdate(nil, cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
212 log.Errorw("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
213 return
214 }
215
216 //Update the device state
217 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
218 cloned.OperStatus = voltha.OperStatus_UNKNOWN
219 dh.device = cloned
220
221 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
222 log.Errorw("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
223 return
224 }
225 log.Debugw("DisableDevice-end", log.Fields{"deviceId": device.Id})
226}
227
228func (dh *DeviceHandler) ReEnableDevice(device *voltha.Device) {
229
230 cloned := proto.Clone(device).(*voltha.Device)
231 // Update the all ports state on that device to enable
232 if err := dh.coreProxy.PortsStateUpdate(nil, cloned.Id, voltha.OperStatus_ACTIVE); err != nil {
233 log.Errorw("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
234 return
235 }
236
237 //Update the device state
238 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
239 cloned.OperStatus = voltha.OperStatus_ACTIVE
240 dh.device = cloned
241
242 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
243 log.Errorw("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
244 return
245 }
246 log.Debugw("ReEnableDevice-end", log.Fields{"deviceId": device.Id})
247}
khenaidoo0a822f92019-05-08 15:15:57 -0400248
249func (dh *DeviceHandler) DeleteDevice(device *voltha.Device) {
250 cloned := proto.Clone(device).(*voltha.Device)
251 // Update the all ports state on that device to disable
252 if err := dh.coreProxy.DeleteAllPorts(nil, cloned.Id); err != nil {
253 log.Errorw("delete-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
254 return
255 }
256
257 log.Debugw("DeleteDevice-end", log.Fields{"deviceId": device.Id})
258}
khenaidoo0458db62019-06-20 08:50:36 -0400259
260func (dh *DeviceHandler) UpdateFlowsBulk(device *voltha.Device, flows *voltha.Flows, groups *voltha.FlowGroups) {
261 log.Debugw("UpdateFlowsBulk", log.Fields{"deviceId": device.Id, "flows": flows, "groups": groups})
262 // For now we do nothing with it
263 return
264}
265
266func (dh *DeviceHandler) UpdateFlowsIncremental(device *voltha.Device, flowChanges *of.FlowChanges, groupChanges *of.FlowGroupChanges) {
267 log.Debugw("UpdateFlowsIncremental", log.Fields{"deviceId": device.Id, "flowChanges": flowChanges, "groupChanges": groupChanges})
268 // For now we do nothing with it
269 return
270}