blob: 46f0e2826ec5d68fe2362084cfc1986edc2801d3 [file] [log] [blame]
khenaidooab1f7bd2019-11-14 14:00:27 -05001/*
2 * Copyright 2019-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
khenaidooab1f7bd2019-11-14 14:00:27 -050017package mocks
18
19import (
20 "context"
21 "fmt"
npujar1d86a522019-11-14 17:11:16 +053022 "strings"
khenaidoo67b22152020-03-02 16:01:25 -050023 "sync"
npujar1d86a522019-11-14 17:11:16 +053024
khenaidooab1f7bd2019-11-14 14:00:27 -050025 "github.com/gogo/protobuf/proto"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080026 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
27 com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
28 "github.com/opencord/voltha-lib-go/v3/pkg/log"
29 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
30 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
31 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidooab1f7bd2019-11-14 14:00:27 -050032)
33
34const (
khenaidoo67b22152020-03-02 16:01:25 -050035 numONUPerOLT = 4
36 startingUNIPortNo = 100
khenaidooab1f7bd2019-11-14 14:00:27 -050037)
38
npujar1d86a522019-11-14 17:11:16 +053039// OLTAdapter represent OLT adapter
khenaidooab1f7bd2019-11-14 14:00:27 -050040type OLTAdapter struct {
khenaidoo67b22152020-03-02 16:01:25 -050041 flows map[uint64]*voltha.OfpFlowStats
42 lock sync.Mutex
khenaidooab1f7bd2019-11-14 14:00:27 -050043 Adapter
44}
45
npujar1d86a522019-11-14 17:11:16 +053046// NewOLTAdapter - creates OLT adapter instance
khenaidooab1f7bd2019-11-14 14:00:27 -050047func NewOLTAdapter(cp adapterif.CoreProxy) *OLTAdapter {
khenaidoo67b22152020-03-02 16:01:25 -050048 return &OLTAdapter{
49 flows: map[uint64]*voltha.OfpFlowStats{},
50 Adapter: Adapter{
51 coreProxy: cp,
52 },
53 }
khenaidooab1f7bd2019-11-14 14:00:27 -050054}
55
npujar1d86a522019-11-14 17:11:16 +053056// Adopt_device creates new handler for added device
57func (oltA *OLTAdapter) Adopt_device(device *voltha.Device) error { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -050058 go func() {
59 d := proto.Clone(device).(*voltha.Device)
60 d.Root = true
61 d.Vendor = "olt_adapter_mock"
62 d.Model = "go-mock"
63 d.SerialNumber = com.GetRandomSerialNumber()
64 d.MacAddress = strings.ToUpper(com.GetRandomMacAddress())
65 oltA.storeDevice(d)
66 if res := oltA.coreProxy.DeviceUpdate(context.TODO(), d); res != nil {
67 log.Fatalf("deviceUpdate-failed-%s", res)
68 }
69 nniPort := &voltha.Port{
70 PortNo: 2,
71 Label: fmt.Sprintf("nni-%d", 2),
72 Type: voltha.Port_ETHERNET_NNI,
73 OperStatus: voltha.OperStatus_ACTIVE,
74 }
75 var err error
76 if err = oltA.coreProxy.PortCreated(context.TODO(), d.Id, nniPort); err != nil {
77 log.Fatalf("PortCreated-failed-%s", err)
78 }
79
80 ponPort := &voltha.Port{
81 PortNo: 1,
82 Label: fmt.Sprintf("pon-%d", 1),
83 Type: voltha.Port_PON_OLT,
84 OperStatus: voltha.OperStatus_ACTIVE,
85 }
86 if err = oltA.coreProxy.PortCreated(context.TODO(), d.Id, ponPort); err != nil {
87 log.Fatalf("PortCreated-failed-%s", err)
88 }
89
90 d.ConnectStatus = voltha.ConnectStatus_REACHABLE
91 d.OperStatus = voltha.OperStatus_ACTIVE
92
93 if err = oltA.coreProxy.DeviceStateUpdate(context.TODO(), d.Id, d.ConnectStatus, d.OperStatus); err != nil {
94 log.Fatalf("Device-state-update-failed-%s", err)
95 }
96
97 //Get the latest device data from the Core
98 if d, err = oltA.coreProxy.GetDevice(context.TODO(), d.Id, d.Id); err != nil {
99 log.Fatalf("getting-device-failed-%s", err)
100 }
101
102 if err = oltA.updateDevice(d); err != nil {
103 log.Fatalf("saving-device-failed-%s", err)
104 }
105
106 // Register Child devices
khenaidoo67b22152020-03-02 16:01:25 -0500107 initialUniPortNo := startingUNIPortNo
khenaidooab1f7bd2019-11-14 14:00:27 -0500108 for i := 0; i < numONUPerOLT; i++ {
109 go func(seqNo int) {
110 if _, err := oltA.coreProxy.ChildDeviceDetected(
111 context.TODO(),
112 d.Id,
113 1,
114 "onu_adapter_mock",
115 initialUniPortNo+seqNo,
116 "onu_adapter_mock",
117 com.GetRandomSerialNumber(),
118 int64(seqNo)); err != nil {
119 log.Fatalf("failure-sending-child-device-%s", err)
120 }
121 }(i)
122 }
123 }()
124 return nil
125}
126
npujar1d86a522019-11-14 17:11:16 +0530127// Get_ofp_device_info returns ofp device info
128func (oltA *OLTAdapter) Get_ofp_device_info(device *voltha.Device) (*ic.SwitchCapability, error) { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500129 if d := oltA.getDevice(device.Id); d == nil {
130 log.Fatalf("device-not-found-%s", device.Id)
131 }
132 return &ic.SwitchCapability{
133 Desc: &of.OfpDesc{
134 HwDesc: "olt_adapter_mock",
135 SwDesc: "olt_adapter_mock",
136 SerialNum: "12345678",
137 },
138 SwitchFeatures: &of.OfpSwitchFeatures{
139 NBuffers: 256,
140 NTables: 2,
141 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
142 of.OfpCapabilities_OFPC_TABLE_STATS |
143 of.OfpCapabilities_OFPC_PORT_STATS |
144 of.OfpCapabilities_OFPC_GROUP_STATS),
145 },
146 }, nil
147}
148
npujar1d86a522019-11-14 17:11:16 +0530149// Get_ofp_port_info returns ofp port info
150func (oltA *OLTAdapter) Get_ofp_port_info(device *voltha.Device, portNo int64) (*ic.PortCapability, error) { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500151 if d := oltA.getDevice(device.Id); d == nil {
152 log.Fatalf("device-not-found-%s", device.Id)
153 }
154 capability := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
155 return &ic.PortCapability{
156 Port: &voltha.LogicalPort{
157 OfpPort: &of.OfpPort{
158 HwAddr: macAddressToUint32Array("11:22:33:44:55:66"),
159 Config: 0,
160 State: uint32(of.OfpPortState_OFPPS_LIVE),
161 Curr: capability,
162 Advertised: capability,
163 Peer: capability,
164 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
165 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
166 },
167 DeviceId: device.Id,
npujar1d86a522019-11-14 17:11:16 +0530168 DevicePortNo: uint32(portNo),
khenaidooab1f7bd2019-11-14 14:00:27 -0500169 },
170 }, nil
171}
172
npujar1d86a522019-11-14 17:11:16 +0530173// GetNumONUPerOLT returns number of ONUs per OLT
khenaidooab1f7bd2019-11-14 14:00:27 -0500174func (oltA *OLTAdapter) GetNumONUPerOLT() int {
175 return numONUPerOLT
176}
177
khenaidoo67b22152020-03-02 16:01:25 -0500178// Returns the starting UNI port number
179func (oltA *OLTAdapter) GetStartingUNIPortNo() int {
180 return startingUNIPortNo
181}
182
npujar1d86a522019-11-14 17:11:16 +0530183// Disable_device disables device
184func (oltA *OLTAdapter) Disable_device(device *voltha.Device) error { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500185 go func() {
186 if d := oltA.getDevice(device.Id); d == nil {
187 log.Fatalf("device-not-found-%s", device.Id)
188 }
189
190 cloned := proto.Clone(device).(*voltha.Device)
191 // Update the all ports state on that device to disable
192 if err := oltA.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400193 log.Warnw("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500194 }
195
Girish Gowdra408cd962020-03-11 14:31:31 -0700196 //Update the device operational state
khenaidooab1f7bd2019-11-14 14:00:27 -0500197 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdra408cd962020-03-11 14:31:31 -0700198 // The device is still reachable after it has been disabled, so the connection status should not be changed.
khenaidooab1f7bd2019-11-14 14:00:27 -0500199
200 if err := oltA.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400201 // Device may already have been deleted in the core
202 log.Warnw("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
203 return
khenaidooab1f7bd2019-11-14 14:00:27 -0500204 }
205
206 if err := oltA.updateDevice(cloned); err != nil {
207 log.Fatalf("saving-device-failed-%s", err)
208 }
209
210 // Tell the Core that all child devices have been disabled (by default it's an action already taken by the Core
211 if err := oltA.coreProxy.ChildDevicesLost(context.TODO(), cloned.Id); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400212 // Device may already have been deleted in the core
213 log.Warnw("lost-notif-of-child-devices-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500214 }
215 }()
216 return nil
217}
218
npujar1d86a522019-11-14 17:11:16 +0530219// Reenable_device reenables device
220func (oltA *OLTAdapter) Reenable_device(device *voltha.Device) error { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500221 go func() {
222 if d := oltA.getDevice(device.Id); d == nil {
223 log.Fatalf("device-not-found-%s", device.Id)
224 }
225
226 cloned := proto.Clone(device).(*voltha.Device)
227 // Update the all ports state on that device to enable
228 if err := oltA.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_ACTIVE); err != nil {
229 log.Fatalf("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
230 }
231
232 //Update the device state
khenaidooab1f7bd2019-11-14 14:00:27 -0500233 cloned.OperStatus = voltha.OperStatus_ACTIVE
234
235 if err := oltA.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
236 log.Fatalf("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
237 }
238
239 // Tell the Core that all child devices have been enabled
240 if err := oltA.coreProxy.ChildDevicesDetected(context.TODO(), cloned.Id); err != nil {
241 log.Fatalf("detection-notif-of-child-devices-failed", log.Fields{"deviceId": device.Id, "error": err})
242 }
243 }()
244 return nil
245}
kesavandbc2d1622020-01-21 00:42:01 -0500246
247// Enable_port -
248func (oltA *OLTAdapter) Enable_port(deviceId string, Port *voltha.Port) error { //nolint
249 go func() {
250
251 if Port.Type == voltha.Port_PON_OLT {
252 if err := oltA.coreProxy.PortStateUpdate(context.TODO(), deviceId, voltha.Port_PON_OLT, Port.PortNo, voltha.OperStatus_ACTIVE); err != nil {
253 log.Fatalf("updating-ports-failed", log.Fields{"device-id": deviceId, "error": err})
254 }
255 }
256
257 }()
258 return nil
259}
260
261// Disable_port -
262func (oltA *OLTAdapter) Disable_port(deviceId string, Port *voltha.Port) error { //nolint
263 go func() {
264
265 if Port.Type == voltha.Port_PON_OLT {
266 if err := oltA.coreProxy.PortStateUpdate(context.TODO(), deviceId, voltha.Port_PON_OLT, Port.PortNo, voltha.OperStatus_DISCOVERED); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400267 // Corresponding device may have been deleted
268 log.Warnw("updating-ports-failed", log.Fields{"device-id": deviceId, "error": err})
kesavandbc2d1622020-01-21 00:42:01 -0500269 }
270 }
271 }()
272 return nil
273}
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500274
275// Child_device_lost deletes ONU and its references
276func (oltA *OLTAdapter) Child_device_lost(deviceID string, pPortNo uint32, onuID uint32) error { // nolint
277 return nil
278}
khenaidoo67b22152020-03-02 16:01:25 -0500279
280// Update_flows_incrementally mocks the incremental flow update
281func (oltA *OLTAdapter) Update_flows_incrementally(device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error { // nolint
282 oltA.lock.Lock()
283 defer oltA.lock.Unlock()
284
285 if flows.ToAdd != nil {
286 for _, f := range flows.ToAdd.Items {
287 oltA.flows[f.Id] = f
288 }
289 }
290 if flows.ToRemove != nil {
291 for _, f := range flows.ToRemove.Items {
292 delete(oltA.flows, f.Id)
293 }
294 }
295 return nil
296}
297
Girish Gowdra408cd962020-03-11 14:31:31 -0700298// Reboot_device -
299func (oltA *OLTAdapter) Reboot_device(device *voltha.Device) error { // nolint
300 log.Infow("reboot-device", log.Fields{"deviceId": device.Id})
301
302 go func() {
303 if err := oltA.coreProxy.DeviceStateUpdate(context.TODO(), device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
304 log.Fatalf("device-state-update-failed", log.Fields{"device-id": device.Id})
305 }
306 if err := oltA.coreProxy.PortsStateUpdate(context.TODO(), device.Id, voltha.OperStatus_UNKNOWN); err != nil {
307 log.Fatalf("port-update-failed", log.Fields{"device-id": device.Id})
308 }
309 }()
310 return nil
311}
312
khenaidoo67b22152020-03-02 16:01:25 -0500313// GetFlowCount returns the total number of flows presently under this adapter
314func (oltA *OLTAdapter) GetFlowCount() int {
315 oltA.lock.Lock()
316 defer oltA.lock.Unlock()
317
318 return len(oltA.flows)
319}
320
321// ClearFlows removes all flows in this adapter
322func (oltA *OLTAdapter) ClearFlows() {
323 oltA.lock.Lock()
324 defer oltA.lock.Unlock()
325
326 oltA.flows = map[uint64]*voltha.OfpFlowStats{}
327}