blob: 2c1abbf28b1ea832673da06d5d29aace7a1f3001 [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}
khenaidoo3ab34882019-05-02 21:33:30 -0400203
204func (dh *DeviceHandler) DisableDevice(device *voltha.Device) {
205 cloned := proto.Clone(device).(*voltha.Device)
206 // Update the all ports state on that device to disable
207 if err := dh.coreProxy.PortsStateUpdate(nil, cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
208 log.Errorw("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
209 return
210 }
211
212 //Update the device state
213 cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
214 cloned.OperStatus = voltha.OperStatus_UNKNOWN
215 dh.device = cloned
216
217 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
218 log.Errorw("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
219 return
220 }
khenaidoo0a822f92019-05-08 15:15:57 -0400221
222 // Tell the Core that all child devices have been disabled (by default it's an action already taken by the Core
223 if err := dh.coreProxy.ChildDevicesLost(nil, cloned.Id); err != nil {
224 log.Errorw("lost-notif-of-child-devices-failed", log.Fields{"deviceId": device.Id, "error": err})
225 return
226 }
227
khenaidoo3ab34882019-05-02 21:33:30 -0400228 log.Debugw("DisableDevice-end", log.Fields{"deviceId": device.Id})
229}
230
231func (dh *DeviceHandler) ReEnableDevice(device *voltha.Device) {
232
233 cloned := proto.Clone(device).(*voltha.Device)
234 // Update the all ports state on that device to enable
235 if err := dh.coreProxy.PortsStateUpdate(nil, cloned.Id, voltha.OperStatus_ACTIVE); err != nil {
236 log.Errorw("updating-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
237 return
238 }
239
240 //Update the device state
241 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
242 cloned.OperStatus = voltha.OperStatus_ACTIVE
243 dh.device = cloned
244
245 if err := dh.coreProxy.DeviceStateUpdate(nil, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
246 log.Errorw("device-state-update-failed", log.Fields{"deviceId": device.Id, "error": err})
247 return
248 }
khenaidoo0a822f92019-05-08 15:15:57 -0400249
250 // Tell the Core that all child devices have been enabled
251 if err := dh.coreProxy.ChildDevicesDetected(nil, cloned.Id); err != nil {
252 log.Errorw("detection-notif-of-child-devices-failed", log.Fields{"deviceId": device.Id, "error": err})
253 return
254 }
255
khenaidoo3ab34882019-05-02 21:33:30 -0400256 log.Debugw("ReEnableDevice-end", log.Fields{"deviceId": device.Id})
257}
khenaidoo0a822f92019-05-08 15:15:57 -0400258
259func (dh *DeviceHandler) DeleteDevice(device *voltha.Device) {
260 cloned := proto.Clone(device).(*voltha.Device)
261 // Update the all ports state on that device to disable
262 if err := dh.coreProxy.DeleteAllPorts(nil, cloned.Id); err != nil {
263 log.Errorw("delete-ports-failed", log.Fields{"deviceId": device.Id, "error": err})
264 return
265 }
266
267 log.Debugw("DeleteDevice-end", log.Fields{"deviceId": device.Id})
268}
khenaidoo0458db62019-06-20 08:50:36 -0400269
270func (dh *DeviceHandler) UpdateFlowsBulk(device *voltha.Device, flows *voltha.Flows, groups *voltha.FlowGroups) {
271 log.Debugw("UpdateFlowsBulk", log.Fields{"deviceId": device.Id, "flows": flows, "groups": groups})
272 // For now we do nothing with it
273 return
274}
275
276func (dh *DeviceHandler) UpdateFlowsIncremental(device *voltha.Device, flowChanges *of.FlowChanges, groupChanges *of.FlowGroupChanges) {
277 log.Debugw("UpdateFlowsIncremental", log.Fields{"deviceId": device.Id, "flowChanges": flowChanges, "groupChanges": groupChanges})
278 // For now we do nothing with it
279 return
280}