blob: 5f67da7fa10333e9c3b706674ed302574d8338da [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"
Scott Baker432f9be2020-03-26 11:56:30 -070021 "errors"
khenaidooab1f7bd2019-11-14 14:00:27 -050022 "fmt"
npujar1d86a522019-11-14 17:11:16 +053023 "strings"
khenaidoo67b22152020-03-02 16:01:25 -050024 "sync"
npujar1d86a522019-11-14 17:11:16 +053025
khenaidooab1f7bd2019-11-14 14:00:27 -050026 "github.com/gogo/protobuf/proto"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080027 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
28 com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
29 "github.com/opencord/voltha-lib-go/v3/pkg/log"
30 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
31 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
32 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidooab1f7bd2019-11-14 14:00:27 -050033)
34
35const (
khenaidoo67b22152020-03-02 16:01:25 -050036 numONUPerOLT = 4
37 startingUNIPortNo = 100
khenaidooab1f7bd2019-11-14 14:00:27 -050038)
39
npujar1d86a522019-11-14 17:11:16 +053040// OLTAdapter represent OLT adapter
khenaidooab1f7bd2019-11-14 14:00:27 -050041type OLTAdapter struct {
khenaidoo67b22152020-03-02 16:01:25 -050042 flows map[uint64]*voltha.OfpFlowStats
43 lock sync.Mutex
khenaidooab1f7bd2019-11-14 14:00:27 -050044 Adapter
45}
46
npujar1d86a522019-11-14 17:11:16 +053047// NewOLTAdapter - creates OLT adapter instance
khenaidooab1f7bd2019-11-14 14:00:27 -050048func NewOLTAdapter(cp adapterif.CoreProxy) *OLTAdapter {
khenaidoo67b22152020-03-02 16:01:25 -050049 return &OLTAdapter{
50 flows: map[uint64]*voltha.OfpFlowStats{},
51 Adapter: Adapter{
52 coreProxy: cp,
53 },
54 }
khenaidooab1f7bd2019-11-14 14:00:27 -050055}
56
npujar1d86a522019-11-14 17:11:16 +053057// Adopt_device creates new handler for added device
58func (oltA *OLTAdapter) Adopt_device(device *voltha.Device) error { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -050059 go func() {
60 d := proto.Clone(device).(*voltha.Device)
61 d.Root = true
62 d.Vendor = "olt_adapter_mock"
63 d.Model = "go-mock"
64 d.SerialNumber = com.GetRandomSerialNumber()
65 d.MacAddress = strings.ToUpper(com.GetRandomMacAddress())
66 oltA.storeDevice(d)
67 if res := oltA.coreProxy.DeviceUpdate(context.TODO(), d); res != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000068 logger.Fatalf("deviceUpdate-failed-%s", res)
khenaidooab1f7bd2019-11-14 14:00:27 -050069 }
70 nniPort := &voltha.Port{
71 PortNo: 2,
72 Label: fmt.Sprintf("nni-%d", 2),
73 Type: voltha.Port_ETHERNET_NNI,
74 OperStatus: voltha.OperStatus_ACTIVE,
75 }
76 var err error
77 if err = oltA.coreProxy.PortCreated(context.TODO(), d.Id, nniPort); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000078 logger.Fatalf("PortCreated-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -050079 }
80
81 ponPort := &voltha.Port{
82 PortNo: 1,
83 Label: fmt.Sprintf("pon-%d", 1),
84 Type: voltha.Port_PON_OLT,
85 OperStatus: voltha.OperStatus_ACTIVE,
86 }
87 if err = oltA.coreProxy.PortCreated(context.TODO(), d.Id, ponPort); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000088 logger.Fatalf("PortCreated-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -050089 }
90
91 d.ConnectStatus = voltha.ConnectStatus_REACHABLE
92 d.OperStatus = voltha.OperStatus_ACTIVE
93
94 if err = oltA.coreProxy.DeviceStateUpdate(context.TODO(), d.Id, d.ConnectStatus, d.OperStatus); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000095 logger.Fatalf("Device-state-update-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -050096 }
97
98 //Get the latest device data from the Core
99 if d, err = oltA.coreProxy.GetDevice(context.TODO(), d.Id, d.Id); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000100 logger.Fatalf("getting-device-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500101 }
102
103 if err = oltA.updateDevice(d); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000104 logger.Fatalf("saving-device-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500105 }
106
107 // Register Child devices
khenaidoo67b22152020-03-02 16:01:25 -0500108 initialUniPortNo := startingUNIPortNo
khenaidooab1f7bd2019-11-14 14:00:27 -0500109 for i := 0; i < numONUPerOLT; i++ {
110 go func(seqNo int) {
111 if _, err := oltA.coreProxy.ChildDeviceDetected(
112 context.TODO(),
113 d.Id,
114 1,
115 "onu_adapter_mock",
116 initialUniPortNo+seqNo,
117 "onu_adapter_mock",
118 com.GetRandomSerialNumber(),
119 int64(seqNo)); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000120 logger.Fatalf("failure-sending-child-device-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500121 }
122 }(i)
123 }
124 }()
125 return nil
126}
127
npujar1d86a522019-11-14 17:11:16 +0530128// Get_ofp_device_info returns ofp device info
129func (oltA *OLTAdapter) Get_ofp_device_info(device *voltha.Device) (*ic.SwitchCapability, error) { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500130 if d := oltA.getDevice(device.Id); d == nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000131 logger.Fatalf("device-not-found-%s", device.Id)
khenaidooab1f7bd2019-11-14 14:00:27 -0500132 }
133 return &ic.SwitchCapability{
134 Desc: &of.OfpDesc{
135 HwDesc: "olt_adapter_mock",
136 SwDesc: "olt_adapter_mock",
137 SerialNum: "12345678",
138 },
139 SwitchFeatures: &of.OfpSwitchFeatures{
140 NBuffers: 256,
141 NTables: 2,
142 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
143 of.OfpCapabilities_OFPC_TABLE_STATS |
144 of.OfpCapabilities_OFPC_PORT_STATS |
145 of.OfpCapabilities_OFPC_GROUP_STATS),
146 },
147 }, nil
148}
149
npujar1d86a522019-11-14 17:11:16 +0530150// Get_ofp_port_info returns ofp port info
151func (oltA *OLTAdapter) Get_ofp_port_info(device *voltha.Device, portNo int64) (*ic.PortCapability, error) { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500152 if d := oltA.getDevice(device.Id); d == nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000153 logger.Fatalf("device-not-found-%s", device.Id)
khenaidooab1f7bd2019-11-14 14:00:27 -0500154 }
155 capability := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
156 return &ic.PortCapability{
157 Port: &voltha.LogicalPort{
158 OfpPort: &of.OfpPort{
159 HwAddr: macAddressToUint32Array("11:22:33:44:55:66"),
160 Config: 0,
161 State: uint32(of.OfpPortState_OFPPS_LIVE),
162 Curr: capability,
163 Advertised: capability,
164 Peer: capability,
165 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
166 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
167 },
168 DeviceId: device.Id,
npujar1d86a522019-11-14 17:11:16 +0530169 DevicePortNo: uint32(portNo),
khenaidooab1f7bd2019-11-14 14:00:27 -0500170 },
171 }, nil
172}
173
npujar1d86a522019-11-14 17:11:16 +0530174// GetNumONUPerOLT returns number of ONUs per OLT
khenaidooab1f7bd2019-11-14 14:00:27 -0500175func (oltA *OLTAdapter) GetNumONUPerOLT() int {
176 return numONUPerOLT
177}
178
khenaidoo67b22152020-03-02 16:01:25 -0500179// Returns the starting UNI port number
180func (oltA *OLTAdapter) GetStartingUNIPortNo() int {
181 return startingUNIPortNo
182}
183
npujar1d86a522019-11-14 17:11:16 +0530184// Disable_device disables device
185func (oltA *OLTAdapter) Disable_device(device *voltha.Device) error { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500186 go func() {
187 if d := oltA.getDevice(device.Id); d == nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000188 logger.Fatalf("device-not-found-%s", device.Id)
khenaidooab1f7bd2019-11-14 14:00:27 -0500189 }
190
191 cloned := proto.Clone(device).(*voltha.Device)
192 // Update the all ports state on that device to disable
193 if err := oltA.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000194 logger.Warnw("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500195 }
196
Girish Gowdra408cd962020-03-11 14:31:31 -0700197 //Update the device operational state
khenaidooab1f7bd2019-11-14 14:00:27 -0500198 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdra408cd962020-03-11 14:31:31 -0700199 // The device is still reachable after it has been disabled, so the connection status should not be changed.
khenaidooab1f7bd2019-11-14 14:00:27 -0500200
201 if err := oltA.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400202 // Device may already have been deleted in the core
Girish Kumarf56a4682020-03-20 20:07:46 +0000203 logger.Warnw("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo442e7c72020-03-10 16:13:48 -0400204 return
khenaidooab1f7bd2019-11-14 14:00:27 -0500205 }
206
207 if err := oltA.updateDevice(cloned); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000208 logger.Fatalf("saving-device-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500209 }
210
211 // Tell the Core that all child devices have been disabled (by default it's an action already taken by the Core
212 if err := oltA.coreProxy.ChildDevicesLost(context.TODO(), cloned.Id); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400213 // Device may already have been deleted in the core
Girish Kumarf56a4682020-03-20 20:07:46 +0000214 logger.Warnw("lost-notif-of-child-devices-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500215 }
216 }()
217 return nil
218}
219
npujar1d86a522019-11-14 17:11:16 +0530220// Reenable_device reenables device
221func (oltA *OLTAdapter) Reenable_device(device *voltha.Device) error { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500222 go func() {
223 if d := oltA.getDevice(device.Id); d == nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000224 logger.Fatalf("device-not-found-%s", device.Id)
khenaidooab1f7bd2019-11-14 14:00:27 -0500225 }
226
227 cloned := proto.Clone(device).(*voltha.Device)
228 // Update the all ports state on that device to enable
229 if err := oltA.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000230 logger.Fatalf("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500231 }
232
233 //Update the device state
khenaidooab1f7bd2019-11-14 14:00:27 -0500234 cloned.OperStatus = voltha.OperStatus_ACTIVE
235
236 if err := oltA.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000237 logger.Fatalf("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500238 }
239
240 // Tell the Core that all child devices have been enabled
241 if err := oltA.coreProxy.ChildDevicesDetected(context.TODO(), cloned.Id); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000242 logger.Fatalf("detection-notif-of-child-devices-failed", log.Fields{"deviceId": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500243 }
244 }()
245 return nil
246}
kesavandbc2d1622020-01-21 00:42:01 -0500247
248// Enable_port -
249func (oltA *OLTAdapter) Enable_port(deviceId string, Port *voltha.Port) error { //nolint
250 go func() {
251
252 if Port.Type == voltha.Port_PON_OLT {
253 if err := oltA.coreProxy.PortStateUpdate(context.TODO(), deviceId, voltha.Port_PON_OLT, Port.PortNo, voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000254 logger.Fatalf("updating-ports-failed", log.Fields{"device-id": deviceId, "error": err})
kesavandbc2d1622020-01-21 00:42:01 -0500255 }
256 }
257
258 }()
259 return nil
260}
261
262// Disable_port -
263func (oltA *OLTAdapter) Disable_port(deviceId string, Port *voltha.Port) error { //nolint
264 go func() {
265
266 if Port.Type == voltha.Port_PON_OLT {
267 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 -0400268 // Corresponding device may have been deleted
Girish Kumarf56a4682020-03-20 20:07:46 +0000269 logger.Warnw("updating-ports-failed", log.Fields{"device-id": deviceId, "error": err})
kesavandbc2d1622020-01-21 00:42:01 -0500270 }
271 }
272 }()
273 return nil
274}
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500275
276// Child_device_lost deletes ONU and its references
277func (oltA *OLTAdapter) Child_device_lost(deviceID string, pPortNo uint32, onuID uint32) error { // nolint
278 return nil
279}
khenaidoo67b22152020-03-02 16:01:25 -0500280
281// Update_flows_incrementally mocks the incremental flow update
282func (oltA *OLTAdapter) Update_flows_incrementally(device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error { // nolint
283 oltA.lock.Lock()
284 defer oltA.lock.Unlock()
285
286 if flows.ToAdd != nil {
287 for _, f := range flows.ToAdd.Items {
288 oltA.flows[f.Id] = f
289 }
290 }
291 if flows.ToRemove != nil {
292 for _, f := range flows.ToRemove.Items {
293 delete(oltA.flows, f.Id)
294 }
295 }
296 return nil
297}
298
Girish Gowdra408cd962020-03-11 14:31:31 -0700299// Reboot_device -
300func (oltA *OLTAdapter) Reboot_device(device *voltha.Device) error { // nolint
Girish Kumarf56a4682020-03-20 20:07:46 +0000301 logger.Infow("reboot-device", log.Fields{"deviceId": device.Id})
Girish Gowdra408cd962020-03-11 14:31:31 -0700302
303 go func() {
304 if err := oltA.coreProxy.DeviceStateUpdate(context.TODO(), device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000305 logger.Fatalf("device-state-update-failed", log.Fields{"device-id": device.Id})
Girish Gowdra408cd962020-03-11 14:31:31 -0700306 }
307 if err := oltA.coreProxy.PortsStateUpdate(context.TODO(), device.Id, voltha.OperStatus_UNKNOWN); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000308 logger.Fatalf("port-update-failed", log.Fields{"device-id": device.Id})
Girish Gowdra408cd962020-03-11 14:31:31 -0700309 }
310 }()
311 return nil
312}
313
Scott Baker432f9be2020-03-26 11:56:30 -0700314// TODO: REMOVE Start_omci_test begins an omci self-test
315func (oltA *OLTAdapter) Start_omci_test(device *voltha.Device, request *voltha.OmciTestRequest) (*ic.TestResponse, error) { // nolint
316 _ = device
317 return nil, errors.New("start-omci-test-not-implemented")
318}
319
khenaidoo67b22152020-03-02 16:01:25 -0500320// GetFlowCount returns the total number of flows presently under this adapter
321func (oltA *OLTAdapter) GetFlowCount() int {
322 oltA.lock.Lock()
323 defer oltA.lock.Unlock()
324
325 return len(oltA.flows)
326}
327
328// ClearFlows removes all flows in this adapter
329func (oltA *OLTAdapter) ClearFlows() {
330 oltA.lock.Lock()
331 defer oltA.lock.Unlock()
332
333 oltA.flows = map[uint64]*voltha.OfpFlowStats{}
334}