blob: ef6582d22a3fa47661aebbf33cb74921c968c1bd [file] [log] [blame]
Elia Battistone1cecb22022-03-21 10:05:25 +01001/*
2* Copyright 2022-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 */
16
17package core
18
19import (
20 "fmt"
Elia Battiston4750d3c2022-07-14 13:24:56 +000021 "time"
Elia Battistone1cecb22022-03-21 10:05:25 +010022
Elia Battiston589addb2022-04-04 16:40:01 +020023 "github.com/opencord/voltha-protos/v5/go/common"
Elia Battistone1cecb22022-03-21 10:05:25 +010024 "github.com/opencord/voltha-protos/v5/go/voltha"
25)
26
27const (
Elia Battiston4750d3c2022-07-14 13:24:56 +000028 DeviceAggregationModule = "bbf-device-aggregation"
29 DevicesPath = "/" + DeviceAggregationModule + ":devices"
Elia Battiston589addb2022-04-04 16:40:01 +020030
31 //Device types
32 DeviceTypeOlt = "bbf-device-types:olt"
33 DeviceTypeOnu = "bbf-device-types:onu"
34
35 //Admin states
36 ietfAdminStateUnknown = "unknown"
37 ietfAdminStateLocked = "locked"
38 ietfAdminStateUnlocked = "unlocked"
39
40 //Oper states
41 ietfOperStateUnknown = "unknown"
42 ietfOperStateDisabled = "disabled"
43 ietfOperStateEnabled = "enabled"
44 ietfOperStateTesting = "testing"
Elia Battiston4750d3c2022-07-14 13:24:56 +000045 ietfOperStateUp = "up"
46 ietfOperStateDown = "down"
47
48 //Keys of useful values in device events
49 eventContextKeyPonId = "pon-id"
50 eventContextKeyOnuSn = "serial-number"
51 eventContextKeyOltSn = "olt-serial-number"
Elia Battistone1cecb22022-03-21 10:05:25 +010052)
53
54type YangItem struct {
55 Path string
56 Value string
57}
58
59//getDevicePath returns the yang path to the root of the device with a specific ID
60func getDevicePath(id string) string {
61 return fmt.Sprintf("%s/device[name='%s']", DevicesPath, id)
62}
63
Elia Battiston589addb2022-04-04 16:40:01 +020064//getDevicePath returns the yang path to the root of the device's hardware module in its data mountpoint
65func getDeviceHardwarePath(id string) string {
Elia Battiston4750d3c2022-07-14 13:24:56 +000066 return fmt.Sprintf("%s/device[name='%s']/data/ietf-hardware:hardware/component[name='%s']", DevicesPath, id, id)
Elia Battiston589addb2022-04-04 16:40:01 +020067}
68
69//ietfHardwareAdminState returns the string that represents the ietf-hardware admin state
70//enum value corresponding to the one of VOLTHA
71func ietfHardwareAdminState(volthaAdminState voltha.AdminState_Types) string {
72 //TODO: verify this mapping is correct
73 switch volthaAdminState {
74 case common.AdminState_UNKNOWN:
75 return ietfAdminStateUnknown
76 case common.AdminState_PREPROVISIONED:
77 case common.AdminState_DOWNLOADING_IMAGE:
78 case common.AdminState_ENABLED:
79 return ietfAdminStateUnlocked
80 case common.AdminState_DISABLED:
81 return ietfAdminStateLocked
82 }
83
84 //TODO: does something map to "shutting-down" ?
85
86 return ietfAdminStateUnknown
87}
88
89//ietfHardwareOperState returns the string that represents the ietf-hardware oper state
90//enum value corresponding to the one of VOLTHA
91func ietfHardwareOperState(volthaOperState voltha.OperStatus_Types) string {
92 //TODO: verify this mapping is correct
93 switch volthaOperState {
94 case common.OperStatus_UNKNOWN:
95 return ietfOperStateUnknown
96 case common.OperStatus_TESTING:
97 return ietfOperStateTesting
98 case common.OperStatus_ACTIVE:
99 return ietfOperStateEnabled
100 case common.OperStatus_DISCOVERED:
101 case common.OperStatus_ACTIVATING:
102 case common.OperStatus_FAILED:
103 case common.OperStatus_RECONCILING:
104 case common.OperStatus_RECONCILING_FAILED:
105 return ietfOperStateDisabled
106 }
107
108 return ietfOperStateUnknown
109}
110
Elia Battiston4750d3c2022-07-14 13:24:56 +0000111//ietfHardwareOperState returns the string that represents the ietf-interfaces oper state
112//enum value corresponding to the one of VOLTHA
113func ietfInterfacesOperState(volthaOperState voltha.OperStatus_Types) string {
114 //TODO: verify this mapping is correct
115 switch volthaOperState {
116 case common.OperStatus_UNKNOWN:
117 return ietfOperStateUnknown
118 case common.OperStatus_TESTING:
119 return ietfOperStateTesting
120 case common.OperStatus_ACTIVE:
121 return ietfOperStateUp
122 case common.OperStatus_DISCOVERED:
123 case common.OperStatus_ACTIVATING:
124 case common.OperStatus_FAILED:
125 case common.OperStatus_RECONCILING:
126 case common.OperStatus_RECONCILING_FAILED:
127 return ietfOperStateDown
128 }
129
130 return ietfOperStateUnknown
131}
132
Elia Battistone1cecb22022-03-21 10:05:25 +0100133//translateDevice returns a slice of yang items that represent a voltha device
Elia Battiston4750d3c2022-07-14 13:24:56 +0000134func translateDevice(device *voltha.Device) []YangItem {
Elia Battistone1cecb22022-03-21 10:05:25 +0100135 devicePath := getDevicePath(device.Id)
Elia Battiston589addb2022-04-04 16:40:01 +0200136 hardwarePath := getDeviceHardwarePath(device.Id)
Elia Battistone1cecb22022-03-21 10:05:25 +0100137
Elia Battiston589addb2022-04-04 16:40:01 +0200138 result := []YangItem{}
Elia Battistone1cecb22022-03-21 10:05:25 +0100139
Elia Battiston589addb2022-04-04 16:40:01 +0200140 //Device type
Elia Battistone1cecb22022-03-21 10:05:25 +0100141 if device.Root {
Elia Battiston4750d3c2022-07-14 13:24:56 +0000142 //OLT
Elia Battiston589addb2022-04-04 16:40:01 +0200143 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000144 Path: devicePath + "/type",
Elia Battiston589addb2022-04-04 16:40:01 +0200145 Value: DeviceTypeOlt,
146 })
Elia Battistone1cecb22022-03-21 10:05:25 +0100147 } else {
Elia Battiston4750d3c2022-07-14 13:24:56 +0000148 //ONU
Elia Battiston589addb2022-04-04 16:40:01 +0200149 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000150 Path: devicePath + "/type",
Elia Battiston589addb2022-04-04 16:40:01 +0200151 Value: DeviceTypeOnu,
152 })
Elia Battistone1cecb22022-03-21 10:05:25 +0100153 }
154
Elia Battiston589addb2022-04-04 16:40:01 +0200155 //Vendor name
156 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000157 Path: hardwarePath + "/mfg-name",
Elia Battiston589addb2022-04-04 16:40:01 +0200158 Value: device.Vendor,
159 })
160
161 //Model
162 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000163 Path: hardwarePath + "/model-name",
Elia Battiston589addb2022-04-04 16:40:01 +0200164 Value: device.Model,
165 })
166
167 //Hardware version
168 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000169 Path: hardwarePath + "/hardware-rev",
Elia Battiston589addb2022-04-04 16:40:01 +0200170 Value: device.HardwareVersion,
171 })
172
173 //Firmware version
174 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000175 Path: hardwarePath + "/firmware-rev",
Elia Battiston589addb2022-04-04 16:40:01 +0200176 Value: device.FirmwareVersion,
177 })
178
179 //Serial number
180 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000181 Path: hardwarePath + "/serial-num",
Elia Battiston589addb2022-04-04 16:40:01 +0200182 Value: device.SerialNumber,
183 })
184
185 //Administrative state
186 //Translates VOLTHA admin state enum to ietf-hardware enum
187 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000188 Path: hardwarePath + "/state/admin-state",
Elia Battiston589addb2022-04-04 16:40:01 +0200189 Value: ietfHardwareAdminState(device.AdminState),
190 })
191
192 //Operative state
193 result = append(result, YangItem{
Elia Battiston4750d3c2022-07-14 13:24:56 +0000194 Path: hardwarePath + "/state/oper-state",
Elia Battiston589addb2022-04-04 16:40:01 +0200195 Value: ietfHardwareOperState(device.OperStatus),
196 })
197
198 return result
Elia Battistone1cecb22022-03-21 10:05:25 +0100199}
200
Elia Battiston4750d3c2022-07-14 13:24:56 +0000201//translateOnuPorts returns a slice of yang items that represent the UNIs of an ONU
202func translateOnuPorts(deviceId string, ports *voltha.Ports) ([]YangItem, error) {
203 interfacesPath := getDevicePath(deviceId) + "/data/ietf-interfaces:interfaces"
Elia Battistone1cecb22022-03-21 10:05:25 +0100204 result := []YangItem{}
205
Elia Battiston4750d3c2022-07-14 13:24:56 +0000206 for _, port := range ports.Items {
207 if port.Type == voltha.Port_ETHERNET_UNI {
208 if port.OfpPort == nil {
209 return nil, fmt.Errorf("no-ofp-port-in-uni: %s %d", deviceId, port.PortNo)
210 }
211
212 interfacePath := fmt.Sprintf("%s/interface[name='%s']", interfacesPath, port.OfpPort.Name)
213
214 result = append(result, []YangItem{
215 {
216 Path: interfacePath + "/type",
217 Value: "bbf-xpon-if-type:onu-v-vrefpoint",
218 },
219 {
220 Path: interfacePath + "/oper-status",
221 Value: ietfInterfacesOperState(port.OperStatus),
222 },
223 }...)
224 }
Elia Battistone1cecb22022-03-21 10:05:25 +0100225 }
226
Elia Battiston4750d3c2022-07-14 13:24:56 +0000227 return result, nil
228}
229
230//TranslateOnuActivatedEvent returns a slice of yang items and the name of the channel termination to populate
231//an ONU discovery notification with data from ONU_ACTIVATED_RAISE_EVENT coming from the Kafka bus
232func TranslateOnuActivatedEvent(eventHeader *voltha.EventHeader, deviceEvent *voltha.DeviceEvent) (notification []YangItem, channelTermination []YangItem, err error) {
233
234 //TODO: the use of this notification, which requires the creation of a dummy channel termination node,
235 //is temporary, and will be substituted with a more fitting one as soon as it will be defined
236
237 //Check if the needed information is present
238 ponId, ok := deviceEvent.Context[eventContextKeyPonId]
239 if !ok {
240 return nil, nil, fmt.Errorf("missing-key-from-event-context: %s", eventContextKeyPonId)
241 }
242 oltId, ok := deviceEvent.Context[eventContextKeyOltSn]
243 if !ok {
244 return nil, nil, fmt.Errorf("missing-key-from-event-context: %s", eventContextKeyPonId)
245 }
246 ponName := oltId + "-pon-" + ponId
247
248 onuSn, ok := deviceEvent.Context[eventContextKeyOnuSn]
249 if !ok {
250 return nil, nil, fmt.Errorf("missing-key-from-event-context: %s", eventContextKeyOnuSn)
251 }
252
253 notificationPath := "/bbf-xpon-onu-states:onu-state-change"
254
255 notification = []YangItem{
256 {
257 Path: notificationPath + "/detected-serial-number",
258 Value: onuSn,
259 },
260 {
261 Path: notificationPath + "/channel-termination-ref",
262 Value: ponName,
263 },
264 {
265 Path: notificationPath + "/onu-state-last-change",
266 Value: eventHeader.RaisedTs.AsTime().Format(time.RFC3339),
267 },
268 {
269 Path: notificationPath + "/onu-state",
270 Value: "bbf-xpon-onu-types:onu-present",
271 },
272 {
273 Path: notificationPath + "/detected-registration-id",
274 Value: deviceEvent.ResourceId,
275 },
276 }
277
278 channelTermination = []YangItem{
279 {
280 Path: fmt.Sprintf("/ietf-interfaces:interfaces/interface[name='%s']/type", ponName),
281 Value: "bbf-if-type:vlan-sub-interface",
282 },
283 }
284
285 return notification, channelTermination, nil
Elia Battistone1cecb22022-03-21 10:05:25 +0100286}