blob: 9aaeea4f768c58a3ace99b8bec882a99bdf35ffe [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"
30)
31
32//DeviceHandler follows the same patterns as ponsim_olt. The only difference is that it does not
33// interact with an OLT device.
34type DeviceHandler struct {
35 deviceId string
36 deviceType string
37 device *voltha.Device
38 coreProxy *com.CoreProxy
39 simulatedOLT *SimulatedOLT
40 nniPort *voltha.Port
41 ponPort *voltha.Port
42 exitChannel chan int
43 lockDevice sync.RWMutex
44}
45
46//NewDeviceHandler creates a new device handler
47func NewDeviceHandler(cp *com.CoreProxy, device *voltha.Device, adapter *SimulatedOLT) *DeviceHandler {
48 var dh DeviceHandler
49 dh.coreProxy = cp
50 cloned := (proto.Clone(device)).(*voltha.Device)
51 dh.deviceId = cloned.Id
52 dh.deviceType = cloned.Type
53 dh.device = cloned
54 dh.simulatedOLT = adapter
55 dh.exitChannel = make(chan int, 1)
56 dh.lockDevice = sync.RWMutex{}
57 return &dh
58}
59
60// start save the device to the data model
61func (dh *DeviceHandler) start(ctx context.Context) {
62 dh.lockDevice.Lock()
63 defer dh.lockDevice.Unlock()
64 log.Debugw("starting-device-agent", log.Fields{"device": dh.device})
65 // Add the initial device to the local model
66 log.Debug("device-agent-started")
67}
68
69// stop stops the device dh. Not much to do for now
70func (dh *DeviceHandler) stop(ctx context.Context) {
71 dh.lockDevice.Lock()
72 defer dh.lockDevice.Unlock()
73 log.Debug("stopping-device-agent")
74 dh.exitChannel <- 1
75 log.Debug("device-agent-stopped")
76}
77
78func macAddressToUint32Array(mac string) []uint32 {
79 slist := strings.Split(mac, ":")
80 result := make([]uint32, len(slist))
81 var err error
82 var tmp int64
83 for index, val := range slist {
84 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
85 return []uint32{1, 2, 3, 4, 5, 6}
86 }
87 result[index] = uint32(tmp)
88 }
89 return result
90}
91
92func (dh *DeviceHandler) AdoptDevice(device *voltha.Device) {
93 log.Debugw("AdoptDevice", log.Fields{"deviceId": device.Id})
94
95 // Update the device info
96 cloned := proto.Clone(device).(*voltha.Device)
97 cloned.Root = true
98 cloned.Vendor = "simulators"
99 cloned.Model = "go-simulators"
100 cloned.SerialNumber = com.GetRandomSerialNumber()
101 cloned.MacAddress = strings.ToUpper(com.GetRandomMacAddress())
102
103 // Synchronous call to update device - this method is run in its own go routine
104 if err := dh.coreProxy.DeviceUpdate(nil, cloned); err != nil {
105 log.Errorw("error-updating-device", log.Fields{"deviceId": device.Id, "error": err})
106 }
107
108 // Now create the NNI Port
109 dh.nniPort = &voltha.Port{
110 PortNo: 2,
khenaidoo54544ae2019-03-18 13:22:39 -0400111 Label: fmt.Sprintf("nni-%d", 2),
khenaidood2b6df92018-12-13 16:37:20 -0500112 Type: voltha.Port_ETHERNET_NNI,
113 OperStatus: voltha.OperStatus_ACTIVE,
114 }
115
116 // Synchronous call to update device - this method is run in its own go routine
117 if err := dh.coreProxy.PortCreated(nil, cloned.Id, dh.nniPort); err != nil {
118 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
119 }
120
121 // Now create the PON Port
122 dh.ponPort = &voltha.Port{
123 PortNo: 1,
khenaidoo54544ae2019-03-18 13:22:39 -0400124 Label: fmt.Sprintf("pon-%d", 1),
khenaidood2b6df92018-12-13 16:37:20 -0500125 Type: voltha.Port_PON_OLT,
126 OperStatus: voltha.OperStatus_ACTIVE,
127 }
128
129 // Synchronous call to update device - this method is run in its own go routine
130 if err := dh.coreProxy.PortCreated(nil, cloned.Id, dh.ponPort); err != nil {
131 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
132 }
133
134 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
135 cloned.OperStatus = voltha.OperStatus_ACTIVE
136
khenaidoo6d055132019-02-12 16:51:19 -0500137 dh.device = cloned
138 //dh.device.SerialNumber = cloned.SerialNumber
139
khenaidood2b6df92018-12-13 16:37:20 -0500140 // Update the device state
141 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
142 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": device.Id, "error": err})
143 }
144
145 // Register Child device
146 initialUniPortNo := 100
147 log.Debugw("registering-onus", log.Fields{"total": dh.simulatedOLT.numOnus})
148 for i := 0; i < dh.simulatedOLT.numOnus; i++ {
149 go dh.coreProxy.ChildDeviceDetected(
150 nil,
151 cloned.Id,
152 1,
153 "simulated_onu",
khenaidoocee54fd2019-03-06 12:03:03 -0500154 initialUniPortNo+i,
155 "simulated_onu",
156 com.GetRandomSerialNumber(),
157 int64(i))
khenaidood2b6df92018-12-13 16:37:20 -0500158 }
khenaidood2b6df92018-12-13 16:37:20 -0500159}
160
161func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
162 return &ic.SwitchCapability{
163 Desc: &of.OfpDesc{
164 HwDesc: "simulated_pon",
165 SwDesc: "simulated_pon",
166 SerialNum: dh.device.SerialNumber,
167 },
168 SwitchFeatures: &of.OfpSwitchFeatures{
169 NBuffers: 256,
170 NTables: 2,
171 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
172 of.OfpCapabilities_OFPC_TABLE_STATS |
173 of.OfpCapabilities_OFPC_PORT_STATS |
174 of.OfpCapabilities_OFPC_GROUP_STATS),
175 },
176 }, nil
177}
178
179func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
180 cap := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
181 return &ic.PortCapability{
182 Port: &voltha.LogicalPort{
183 OfpPort: &of.OfpPort{
184 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
185 Config: 0,
186 State: uint32(of.OfpPortState_OFPPS_LIVE),
187 Curr: cap,
188 Advertised: cap,
189 Peer: cap,
190 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
191 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
192 },
193 DeviceId: dh.device.Id,
194 DevicePortNo: uint32(portNo),
195 },
196 }, nil
197}
198
199func (dh *DeviceHandler) Process_inter_adapter_message(msg *ic.InterAdapterMessage) error {
200 log.Debugw("Process_inter_adapter_message", log.Fields{"msgId": msg.Header.Id})
201 return nil
202}