blob: d5669c390b7514663b755e4e8efb41c0c29796ec [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"
khenaidood948f772021-08-11 17:49:24 -040022 "strconv"
Kent Hagerman2a07b862020-06-19 15:23:07 -040023 "strings"
24
khenaidood948f772021-08-11 17:49:24 -040025 "github.com/golang/protobuf/ptypes/empty"
26 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
27 "github.com/opencord/voltha-lib-go/v7/pkg/probe"
28 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo9beaaf12021-10-19 17:32:01 -040029 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidood948f772021-08-11 17:49:24 -040030 "github.com/opencord/voltha-protos/v5/go/extension"
31 "github.com/phayes/freeport"
32
khenaidooab1f7bd2019-11-14 14:00:27 -050033 "github.com/gogo/protobuf/proto"
khenaidood948f772021-08-11 17:49:24 -040034 com "github.com/opencord/voltha-lib-go/v7/pkg/adapters/common"
35 "github.com/opencord/voltha-lib-go/v7/pkg/log"
khenaidoo9beaaf12021-10-19 17:32:01 -040036 "github.com/opencord/voltha-protos/v5/go/omci"
khenaidood948f772021-08-11 17:49:24 -040037 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
38 "github.com/opencord/voltha-protos/v5/go/voltha"
khenaidooab1f7bd2019-11-14 14:00:27 -050039)
40
npujar1d86a522019-11-14 17:11:16 +053041// ONUAdapter represent ONU adapter attributes
khenaidooab1f7bd2019-11-14 14:00:27 -050042type ONUAdapter struct {
khenaidoo8b4abbf2020-04-24 17:04:30 -040043 *Adapter
khenaidood948f772021-08-11 17:49:24 -040044 grpcServer *vgrpc.GrpcServer
khenaidooab1f7bd2019-11-14 14:00:27 -050045}
46
npujar1d86a522019-11-14 17:11:16 +053047// NewONUAdapter creates ONU adapter
khenaidood948f772021-08-11 17:49:24 -040048func NewONUAdapter(ctx context.Context, coreEndpoint string, deviceType string, vendor string) *ONUAdapter {
49 // Get an available port
50 grpcPort, err := freeport.GetFreePort()
51 if err != nil {
52 logger.Fatalw(ctx, "no-free-port", log.Fields{"error": err})
khenaidoo67b22152020-03-02 16:01:25 -050053 }
khenaidood948f772021-08-11 17:49:24 -040054 listeningAddress := fmt.Sprintf("127.0.0.1:%s", strconv.Itoa(grpcPort))
55 onuAdapter := &ONUAdapter{Adapter: NewAdapter(listeningAddress, coreEndpoint, deviceType, vendor)}
56
57 onuAdapter.start(ctx)
58 return onuAdapter
59}
60
61func (onuA *ONUAdapter) onuRestarted(ctx context.Context, endPoint string) error {
62 logger.Errorw(ctx, "remote-restarted", log.Fields{"endpoint": endPoint})
63 return nil
64}
65
66func (onuA *ONUAdapter) start(ctx context.Context) {
67
68 // Set up the probe service
69 onuA.Probe = &probe.Probe{}
70 probePort, err := freeport.GetFreePort()
71 if err != nil {
72 logger.Fatal(ctx, "Cannot get a freeport for probePort")
73 }
74 probeAddress := "127.0.0.1:" + strconv.Itoa(probePort)
75 go onuA.Probe.ListenAndServe(ctx, probeAddress)
76
77 probeCtx := context.WithValue(ctx, probe.ProbeContextKey, onuA.Probe)
78
79 onuA.Probe.RegisterService(ctx, "onu-grpc-service", onuA.coreEnpoint)
80
81 // start gRPC handler
82 onuA.grpcServer = vgrpc.NewGrpcServer(onuA.serviceEndpoint, nil, false, nil)
83
84 logger.Debugw(ctx, "ONUAdapter-address", log.Fields{"address": onuA.serviceEndpoint})
85
86 go onuA.startGRPCService(ctx, onuA.grpcServer, onuA, "onu-grpc-service")
87
88 // Establish grpc connection to Core
khenaidoo25057da2021-12-08 14:40:45 -050089 if onuA.coreClient, err = vgrpc.NewClient(
90 "onu-endpoint",
91 onuA.coreEnpoint,
92 onuA.onuRestarted); err != nil {
khenaidood948f772021-08-11 17:49:24 -040093 logger.Fatal(ctx, "grpc-client-not-created")
94 }
95 go onuA.coreClient.Start(probeCtx, setAndTestCoreServiceHandler)
96
97 logger.Debugw(ctx, "ONUAdapter-started", log.Fields{"grpc-address": onuA.serviceEndpoint})
98}
99
100// Stop brings down core services
101func (onuA *ONUAdapter) StopGrpcClient() {
102 // Stop the grpc clients
103 onuA.coreClient.Stop(context.Background())
104}
105
106func (onuA *ONUAdapter) Stop() {
107 if onuA.grpcServer != nil {
108 onuA.grpcServer.Stop()
109 }
110 logger.Debugw(context.Background(), "ONUAdapter-stopped", log.Fields{"grpc-address": onuA.serviceEndpoint})
khenaidooab1f7bd2019-11-14 14:00:27 -0500111}
112
npujar1d86a522019-11-14 17:11:16 +0530113// Adopt_device creates new handler for added device
khenaidood948f772021-08-11 17:49:24 -0400114func (onuA *ONUAdapter) AdoptDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
115 logger.Debugw(ctx, "AdoptDevice", log.Fields{"device": device.AdapterEndpoint, "device-type": onuA.DeviceType})
khenaidooab1f7bd2019-11-14 14:00:27 -0500116 go func() {
117 d := proto.Clone(device).(*voltha.Device)
118 d.Root = false
khenaidood948f772021-08-11 17:49:24 -0400119 d.Vendor = onuA.vendor
khenaidooab1f7bd2019-11-14 14:00:27 -0500120 d.Model = "go-mock"
121 d.SerialNumber = com.GetRandomSerialNumber()
122 d.MacAddress = strings.ToUpper(com.GetRandomMacAddress())
123 onuA.storeDevice(d)
khenaidood948f772021-08-11 17:49:24 -0400124
125 c, err := onuA.GetCoreClient()
126 if err != nil {
127 return
128 }
129 if _, err := c.DeviceUpdate(context.TODO(), d); err != nil {
130 logger.Fatalf(ctx, "deviceUpdate-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500131 }
khenaidooab1f7bd2019-11-14 14:00:27 -0500132
khenaidood948f772021-08-11 17:49:24 -0400133 d.ConnectStatus = common.ConnectStatus_REACHABLE
134 d.OperStatus = common.OperStatus_DISCOVERED
khenaidoo93181522020-01-23 12:43:21 -0500135
khenaidoo9beaaf12021-10-19 17:32:01 -0400136 if _, err = c.DeviceStateUpdate(context.TODO(), &ca.DeviceStateFilter{DeviceId: d.Id, OperStatus: d.OperStatus, ConnStatus: d.ConnectStatus}); err != nil {
khenaidood948f772021-08-11 17:49:24 -0400137 logger.Fatalf(ctx, "PortCreated-failed-%s", err)
khenaidoo442e7c72020-03-10 16:13:48 -0400138 }
khenaidooab1f7bd2019-11-14 14:00:27 -0500139
140 uniPortNo := uint32(2)
141 if device.ProxyAddress != nil {
142 if device.ProxyAddress.ChannelId != 0 {
143 uniPortNo = device.ProxyAddress.ChannelId
144 }
145 }
146
khenaidooc6c7bda2020-06-17 17:20:18 -0400147 capability := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
khenaidooab1f7bd2019-11-14 14:00:27 -0500148 uniPort := &voltha.Port{
khenaidood948f772021-08-11 17:49:24 -0400149 DeviceId: d.Id,
khenaidooab1f7bd2019-11-14 14:00:27 -0500150 PortNo: uniPortNo,
151 Label: fmt.Sprintf("uni-%d", uniPortNo),
152 Type: voltha.Port_ETHERNET_UNI,
khenaidood948f772021-08-11 17:49:24 -0400153 OperStatus: common.OperStatus_ACTIVE,
khenaidooc6c7bda2020-06-17 17:20:18 -0400154 OfpPort: &of.OfpPort{
155 HwAddr: macAddressToUint32Array("12:12:12:12:12:12"),
156 Config: 0,
157 State: uint32(of.OfpPortState_OFPPS_LIVE),
158 Curr: capability,
159 Advertised: capability,
160 Peer: capability,
161 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
162 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
163 },
khenaidooab1f7bd2019-11-14 14:00:27 -0500164 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400165
khenaidood948f772021-08-11 17:49:24 -0400166 if _, err = c.PortCreated(context.TODO(), uniPort); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000167 logger.Fatalf(ctx, "PortCreated-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500168 }
169
170 ponPortNo := uint32(1)
171 if device.ParentPortNo != 0 {
172 ponPortNo = device.ParentPortNo
173 }
174
175 ponPort := &voltha.Port{
khenaidood948f772021-08-11 17:49:24 -0400176 DeviceId: d.Id,
khenaidooab1f7bd2019-11-14 14:00:27 -0500177 PortNo: ponPortNo,
178 Label: fmt.Sprintf("pon-%d", ponPortNo),
179 Type: voltha.Port_PON_ONU,
khenaidood948f772021-08-11 17:49:24 -0400180 OperStatus: common.OperStatus_ACTIVE,
khenaidooab1f7bd2019-11-14 14:00:27 -0500181 Peers: []*voltha.Port_PeerPort{{DeviceId: d.ParentId, // Peer device is OLT
khenaidoo6e55d9e2019-12-12 18:26:26 -0500182 PortNo: device.ParentPortNo}}, // Peer port is parent's port number
khenaidooab1f7bd2019-11-14 14:00:27 -0500183 }
khenaidood948f772021-08-11 17:49:24 -0400184
185 if _, err = c.PortCreated(context.TODO(), ponPort); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000186 logger.Fatalf(ctx, "PortCreated-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500187 }
188
khenaidood948f772021-08-11 17:49:24 -0400189 d.ConnectStatus = common.ConnectStatus_REACHABLE
190 d.OperStatus = common.OperStatus_ACTIVE
khenaidooab1f7bd2019-11-14 14:00:27 -0500191
khenaidoo9beaaf12021-10-19 17:32:01 -0400192 if _, err = c.DeviceStateUpdate(context.TODO(), &ca.DeviceStateFilter{DeviceId: d.Id, OperStatus: d.OperStatus, ConnStatus: d.ConnectStatus}); err != nil {
khenaidood948f772021-08-11 17:49:24 -0400193 logger.Fatalf(ctx, "PortCreated-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500194 }
khenaidood948f772021-08-11 17:49:24 -0400195
khenaidooab1f7bd2019-11-14 14:00:27 -0500196 //Get the latest device data from the Core
khenaidood948f772021-08-11 17:49:24 -0400197 if d, err = c.GetDevice(context.TODO(), &common.ID{Id: d.Id}); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000198 logger.Fatalf(ctx, "getting-device-failed-%s", err)
khenaidooab1f7bd2019-11-14 14:00:27 -0500199 }
200
khenaidoo8b4abbf2020-04-24 17:04:30 -0400201 onuA.updateDevice(d)
khenaidooab1f7bd2019-11-14 14:00:27 -0500202 }()
khenaidood948f772021-08-11 17:49:24 -0400203 return &empty.Empty{}, nil
khenaidooab1f7bd2019-11-14 14:00:27 -0500204}
205
Andrea Campanella025667e2021-01-14 11:50:07 +0100206// Single_get_value_request retrieves a single value.
207func (onuA *ONUAdapter) Single_get_value_request(ctx context.Context, // nolint
208 request extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error) {
209 logger.Fatalf(ctx, "Single_get_value_request unimplemented")
210 return nil, nil
211}
212
npujar1d86a522019-11-14 17:11:16 +0530213// Disable_device disables device
khenaidood948f772021-08-11 17:49:24 -0400214func (onuA *ONUAdapter) DisableDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500215 go func() {
216 if d := onuA.getDevice(device.Id); d == nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000217 logger.Fatalf(ctx, "device-not-found-%s", device.Id)
khenaidooab1f7bd2019-11-14 14:00:27 -0500218 }
khenaidood948f772021-08-11 17:49:24 -0400219
khenaidooab1f7bd2019-11-14 14:00:27 -0500220 cloned := proto.Clone(device).(*voltha.Device)
221 // Update the all ports state on that device to disable
khenaidood948f772021-08-11 17:49:24 -0400222 c, err := onuA.GetCoreClient()
223 if err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400224 return
khenaidooab1f7bd2019-11-14 14:00:27 -0500225 }
khenaidooab1f7bd2019-11-14 14:00:27 -0500226
khenaidood948f772021-08-11 17:49:24 -0400227 if _, err := c.PortsStateUpdate(context.TODO(),
khenaidoo9beaaf12021-10-19 17:32:01 -0400228 &ca.PortStateFilter{
khenaidood948f772021-08-11 17:49:24 -0400229 DeviceId: cloned.Id,
230 PortTypeFilter: 0,
231 OperStatus: common.OperStatus_UNKNOWN,
232 }); err != nil {
233 logger.Warnw(ctx, "updating-ports-failed", log.Fields{"device-id": device.Id, "error": err})
234 }
235
236 //Update the device operational state
237 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
238 cloned.OperStatus = common.OperStatus_UNKNOWN
239
khenaidoo9beaaf12021-10-19 17:32:01 -0400240 if _, err := c.DeviceStateUpdate(context.TODO(), &ca.DeviceStateFilter{
khenaidood948f772021-08-11 17:49:24 -0400241 DeviceId: cloned.Id,
242 OperStatus: cloned.OperStatus,
243 ConnStatus: cloned.ConnectStatus,
244 }); err != nil {
245 // Device may already have been deleted in the core
divyadesaicb8b59d2020-08-18 09:55:47 +0000246 logger.Warnw(ctx, "device-state-update-failed", log.Fields{"device-id": device.Id, "error": err})
khenaidoo442e7c72020-03-10 16:13:48 -0400247 return
khenaidooab1f7bd2019-11-14 14:00:27 -0500248 }
khenaidood948f772021-08-11 17:49:24 -0400249
khenaidoo8b4abbf2020-04-24 17:04:30 -0400250 onuA.updateDevice(cloned)
khenaidood948f772021-08-11 17:49:24 -0400251
khenaidooab1f7bd2019-11-14 14:00:27 -0500252 }()
khenaidood948f772021-08-11 17:49:24 -0400253 return &empty.Empty{}, nil
khenaidooab1f7bd2019-11-14 14:00:27 -0500254}
255
khenaidood948f772021-08-11 17:49:24 -0400256func (onuA *ONUAdapter) ReEnableDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) { // nolint
khenaidooab1f7bd2019-11-14 14:00:27 -0500257 go func() {
258 if d := onuA.getDevice(device.Id); d == nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000259 logger.Fatalf(ctx, "device-not-found-%s", device.Id)
khenaidooab1f7bd2019-11-14 14:00:27 -0500260 }
261
262 cloned := proto.Clone(device).(*voltha.Device)
khenaidood948f772021-08-11 17:49:24 -0400263
264 c, err := onuA.GetCoreClient()
265 if err != nil {
266 return
267 }
268
khenaidooab1f7bd2019-11-14 14:00:27 -0500269 // Update the all ports state on that device to enable
khenaidood948f772021-08-11 17:49:24 -0400270 if _, err := c.PortsStateUpdate(context.TODO(),
khenaidoo9beaaf12021-10-19 17:32:01 -0400271 &ca.PortStateFilter{
khenaidood948f772021-08-11 17:49:24 -0400272 DeviceId: cloned.Id,
273 PortTypeFilter: 0,
274 OperStatus: common.OperStatus_ACTIVE,
275 }); err != nil {
276 logger.Warnw(ctx, "updating-ports-failed", log.Fields{"device-id": device.Id, "error": err})
khenaidooab1f7bd2019-11-14 14:00:27 -0500277 }
278
279 //Update the device state
khenaidood948f772021-08-11 17:49:24 -0400280 cloned.ConnectStatus = common.ConnectStatus_REACHABLE
281 cloned.OperStatus = common.OperStatus_ACTIVE
khenaidooab1f7bd2019-11-14 14:00:27 -0500282
khenaidoo9beaaf12021-10-19 17:32:01 -0400283 if _, err := c.DeviceStateUpdate(context.TODO(), &ca.DeviceStateFilter{
khenaidood948f772021-08-11 17:49:24 -0400284 DeviceId: cloned.Id,
285 OperStatus: cloned.OperStatus,
286 ConnStatus: cloned.ConnectStatus,
287 }); err != nil {
288 // Device may already have been deleted in the core
divyadesaicb8b59d2020-08-18 09:55:47 +0000289 logger.Fatalf(ctx, "device-state-update-failed", log.Fields{"device-id": device.Id, "error": err})
khenaidood948f772021-08-11 17:49:24 -0400290 return
khenaidooab1f7bd2019-11-14 14:00:27 -0500291 }
khenaidoo8b4abbf2020-04-24 17:04:30 -0400292 onuA.updateDevice(cloned)
khenaidooab1f7bd2019-11-14 14:00:27 -0500293 }()
khenaidood948f772021-08-11 17:49:24 -0400294 return &empty.Empty{}, nil
khenaidooab1f7bd2019-11-14 14:00:27 -0500295}
khenaidoo67b22152020-03-02 16:01:25 -0500296
khenaidoo9beaaf12021-10-19 17:32:01 -0400297func (onuA *ONUAdapter) StartOmciTest(ctx context.Context, _ *ca.OMCITest) (*omci.TestResponse, error) { // nolint
298 return &omci.TestResponse{Result: omci.TestResponse_SUCCESS}, nil
yasin sapli5458a1c2021-06-14 22:24:38 +0000299}