blob: 9bfe1e9cfdd31ec23edf1fa4275d7864b8185496 [file] [log] [blame]
Takahiro Suzuki241c10e2020-12-17 20:17:57 +09001/*
2 * Copyright 2020-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
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "errors"
23 "fmt"
24 "strconv"
25 "strings"
26
27
28 "github.com/opencord/voltha-lib-go/v3/pkg/log"
29 vc "github.com/opencord/voltha-protos/v3/go/common"
30 of "github.com/opencord/voltha-protos/v3/go/openflow_13"
31 "github.com/opencord/voltha-protos/v3/go/voltha"
32)
33
34type uniPortType uint8
35
36// UniPPTP Interface type - re-use values from G.988 TP type definition (directly used in OMCI!)
37const (
38 uniPPTP uniPortType = 1 // relates to PPTP
39 uniVEIP uniPortType = 11 // relates to VEIP
40)
41
42//onuUniPort structure holds information about the ONU attached Uni Ports
43type onuUniPort struct {
44 enabled bool
45 name string
46 portNo uint32
47 portType uniPortType
48 ofpPortNo string
49 uniID uint8
50 macBpNo uint8
51 entityID uint16
52 adminState vc.AdminState_Types
53 operState vc.OperStatus_Types
54 pPort *voltha.Port
55}
56
57//newOnuUniPort returns a new instance of a OnuUniPort
58func newOnuUniPort(aUniID uint8, aPortNo uint32, aInstNo uint16,
59 aPortType uniPortType) *onuUniPort {
60 logger.Infow("init-onuUniPort", log.Fields{"uniID": aUniID,
61 "portNo": aPortNo, "InstNo": aInstNo, "type": aPortType})
62 var onuUniPort onuUniPort
63 onuUniPort.enabled = false
64 onuUniPort.name = "uni-" + strconv.FormatUint(uint64(aPortNo), 10)
65 onuUniPort.portNo = aPortNo
66 onuUniPort.portType = aPortType
67 onuUniPort.ofpPortNo = onuUniPort.name
68 onuUniPort.uniID = aUniID
69 onuUniPort.macBpNo = aUniID + 1 //ensure >0 instanceNo
70 onuUniPort.entityID = aInstNo
71 onuUniPort.adminState = vc.AdminState_ENABLED //enabled per create
72 onuUniPort.operState = vc.OperStatus_UNKNOWN
73 onuUniPort.pPort = nil // to be set on create
74 return &onuUniPort
75}
76
77//createVolthaPort creates the Voltha port based on ONU UNI Port and informs the core about it
78func (oo *onuUniPort) createVolthaPort(apDeviceHandler *deviceHandler) error {
79 logger.Debugw("creating-voltha-uni-port", log.Fields{
80 "device-id": apDeviceHandler.device.Id, "portNo": oo.portNo})
81 name := apDeviceHandler.device.SerialNumber + "-" + strconv.FormatUint(uint64(oo.macBpNo), 10)
82
83 var macOctets [6]uint8
84 macOctets[5] = 0x08
85 macOctets[4] = uint8(apDeviceHandler.ponPortNumber >> 8)
86 macOctets[3] = uint8(apDeviceHandler.ponPortNumber)
87 macOctets[2] = uint8(oo.portNo >> 16)
88 macOctets[1] = uint8(oo.portNo >> 8)
89 macOctets[0] = uint8(oo.portNo)
90 onuEntry := apDeviceHandler.getOnuDeviceEntry(false)
91 if onuEntry == nil {
92 logger.Debugw("not-found-onu-device-entry", log.Fields{"error": "not found"})
93 } else {
94 if len(onuEntry.macAddress) == 12 {
95 for idx := 0; idx < 6; idx++ {
96 if v, err := strconv.ParseInt(onuEntry.macAddress[idx*2:(idx*2)+2], 16, 8); err == nil {
97 macOctets[5-idx] = uint8(v)
98 }
99 }
100 }
101 }
102 hwAddr := genMacFromOctets(macOctets)
103 ofHwAddr := macAddressToUint32Array(hwAddr)
104 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
105 ofUniPortState := of.OfpPortState_OFPPS_LINK_DOWN
106 /* as the VOLTHA port create is only called directly after Uni Port create
107 the OfPortOperState is always Down
108 Note: this way the OfPortOperState won't ever change (directly in adapter)
109 maybe that was already always the case, but looks a bit weird - to be kept in mind ...
110 if pUniPort.operState == vc.OperStatus_ACTIVE {
111 ofUniPortState = of.OfpPortState_OFPPS_LIVE
112 }
113 */
114 logger.Debugw("ofPort values", log.Fields{
115 "forUniPortName": oo.name, "forMacBase": hwAddr,
116 "name": name, "hwAddr": ofHwAddr, "OperState": ofUniPortState})
117
118 pUniPort := &voltha.Port{
119 PortNo: oo.portNo,
120 Label: oo.name,
121 Type: voltha.Port_ETHERNET_UNI,
122 AdminState: oo.adminState,
123 OperStatus: oo.operState,
124 // obviously empty peer setting
125 OfpPort: &of.OfpPort{
126 Name: name,
127 HwAddr: ofHwAddr,
128 Config: 0,
129 State: uint32(ofUniPortState),
130 Curr: capacity,
131 Advertised: capacity,
132 Peer: capacity,
133 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
134 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
135 },
136 }
137 if pUniPort != nil {
138 if err := apDeviceHandler.coreProxy.PortCreated(context.TODO(),
139 apDeviceHandler.deviceID, pUniPort); err != nil {
140 logger.Fatalf("adding-uni-port: create-VOLTHA-Port-failed-%s", err)
141 return err
142 }
143 logger.Infow("Voltha onuUniPort-added", log.Fields{
144 "device-id": apDeviceHandler.device.Id, "PortNo": oo.portNo})
145 oo.pPort = pUniPort
146 oo.operState = vc.OperStatus_DISCOVERED
147 } else {
148 logger.Warnw("could not create Voltha UniPort", log.Fields{
149 "device-id": apDeviceHandler.device.Id, "PortNo": oo.portNo})
150 return errors.New("create Voltha UniPort failed")
151 }
152 return nil
153}
154
155//setOperState modifies OperState of the the UniPort
156func (oo *onuUniPort) setOperState(aNewOperState vc.OperStatus_Types) {
157 oo.operState = aNewOperState
158}
159
160// uni port related utility functions (so far only used here)
161func genMacFromOctets(aOctets [6]uint8) string {
162 return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
163 aOctets[5], aOctets[4], aOctets[3],
164 aOctets[2], aOctets[1], aOctets[0])
165}
166
167//copied from OLT Adapter: unify centrally ?
168func macAddressToUint32Array(mac string) []uint32 {
169 slist := strings.Split(mac, ":")
170 result := make([]uint32, len(slist))
171 var err error
172 var tmp int64
173 for index, val := range slist {
174 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
175 return []uint32{1, 2, 3, 4, 5, 6}
176 }
177 result[index] = uint32(tmp)
178 }
179 return result
180}