[VOL-1349] EPON ONU adapter (package B)
Change-Id: I609ba349c429bc7e87c74b66bb1121841f9caef6
diff --git a/internal/pkg/onuadaptercore/onu_uni_port.go b/internal/pkg/onuadaptercore/onu_uni_port.go
new file mode 100644
index 0000000..9bfe1e9
--- /dev/null
+++ b/internal/pkg/onuadaptercore/onu_uni_port.go
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//Package adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+
+
+ "github.com/opencord/voltha-lib-go/v3/pkg/log"
+ vc "github.com/opencord/voltha-protos/v3/go/common"
+ of "github.com/opencord/voltha-protos/v3/go/openflow_13"
+ "github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+type uniPortType uint8
+
+// UniPPTP Interface type - re-use values from G.988 TP type definition (directly used in OMCI!)
+const (
+ uniPPTP uniPortType = 1 // relates to PPTP
+ uniVEIP uniPortType = 11 // relates to VEIP
+)
+
+//onuUniPort structure holds information about the ONU attached Uni Ports
+type onuUniPort struct {
+ enabled bool
+ name string
+ portNo uint32
+ portType uniPortType
+ ofpPortNo string
+ uniID uint8
+ macBpNo uint8
+ entityID uint16
+ adminState vc.AdminState_Types
+ operState vc.OperStatus_Types
+ pPort *voltha.Port
+}
+
+//newOnuUniPort returns a new instance of a OnuUniPort
+func newOnuUniPort(aUniID uint8, aPortNo uint32, aInstNo uint16,
+ aPortType uniPortType) *onuUniPort {
+ logger.Infow("init-onuUniPort", log.Fields{"uniID": aUniID,
+ "portNo": aPortNo, "InstNo": aInstNo, "type": aPortType})
+ var onuUniPort onuUniPort
+ onuUniPort.enabled = false
+ onuUniPort.name = "uni-" + strconv.FormatUint(uint64(aPortNo), 10)
+ onuUniPort.portNo = aPortNo
+ onuUniPort.portType = aPortType
+ onuUniPort.ofpPortNo = onuUniPort.name
+ onuUniPort.uniID = aUniID
+ onuUniPort.macBpNo = aUniID + 1 //ensure >0 instanceNo
+ onuUniPort.entityID = aInstNo
+ onuUniPort.adminState = vc.AdminState_ENABLED //enabled per create
+ onuUniPort.operState = vc.OperStatus_UNKNOWN
+ onuUniPort.pPort = nil // to be set on create
+ return &onuUniPort
+}
+
+//createVolthaPort creates the Voltha port based on ONU UNI Port and informs the core about it
+func (oo *onuUniPort) createVolthaPort(apDeviceHandler *deviceHandler) error {
+ logger.Debugw("creating-voltha-uni-port", log.Fields{
+ "device-id": apDeviceHandler.device.Id, "portNo": oo.portNo})
+ name := apDeviceHandler.device.SerialNumber + "-" + strconv.FormatUint(uint64(oo.macBpNo), 10)
+
+ var macOctets [6]uint8
+ macOctets[5] = 0x08
+ macOctets[4] = uint8(apDeviceHandler.ponPortNumber >> 8)
+ macOctets[3] = uint8(apDeviceHandler.ponPortNumber)
+ macOctets[2] = uint8(oo.portNo >> 16)
+ macOctets[1] = uint8(oo.portNo >> 8)
+ macOctets[0] = uint8(oo.portNo)
+ onuEntry := apDeviceHandler.getOnuDeviceEntry(false)
+ if onuEntry == nil {
+ logger.Debugw("not-found-onu-device-entry", log.Fields{"error": "not found"})
+ } else {
+ if len(onuEntry.macAddress) == 12 {
+ for idx := 0; idx < 6; idx++ {
+ if v, err := strconv.ParseInt(onuEntry.macAddress[idx*2:(idx*2)+2], 16, 8); err == nil {
+ macOctets[5-idx] = uint8(v)
+ }
+ }
+ }
+ }
+ hwAddr := genMacFromOctets(macOctets)
+ ofHwAddr := macAddressToUint32Array(hwAddr)
+ capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
+ ofUniPortState := of.OfpPortState_OFPPS_LINK_DOWN
+ /* as the VOLTHA port create is only called directly after Uni Port create
+ the OfPortOperState is always Down
+ Note: this way the OfPortOperState won't ever change (directly in adapter)
+ maybe that was already always the case, but looks a bit weird - to be kept in mind ...
+ if pUniPort.operState == vc.OperStatus_ACTIVE {
+ ofUniPortState = of.OfpPortState_OFPPS_LIVE
+ }
+ */
+ logger.Debugw("ofPort values", log.Fields{
+ "forUniPortName": oo.name, "forMacBase": hwAddr,
+ "name": name, "hwAddr": ofHwAddr, "OperState": ofUniPortState})
+
+ pUniPort := &voltha.Port{
+ PortNo: oo.portNo,
+ Label: oo.name,
+ Type: voltha.Port_ETHERNET_UNI,
+ AdminState: oo.adminState,
+ OperStatus: oo.operState,
+ // obviously empty peer setting
+ OfpPort: &of.OfpPort{
+ Name: name,
+ HwAddr: ofHwAddr,
+ Config: 0,
+ State: uint32(ofUniPortState),
+ Curr: capacity,
+ Advertised: capacity,
+ Peer: capacity,
+ CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+ MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+ },
+ }
+ if pUniPort != nil {
+ if err := apDeviceHandler.coreProxy.PortCreated(context.TODO(),
+ apDeviceHandler.deviceID, pUniPort); err != nil {
+ logger.Fatalf("adding-uni-port: create-VOLTHA-Port-failed-%s", err)
+ return err
+ }
+ logger.Infow("Voltha onuUniPort-added", log.Fields{
+ "device-id": apDeviceHandler.device.Id, "PortNo": oo.portNo})
+ oo.pPort = pUniPort
+ oo.operState = vc.OperStatus_DISCOVERED
+ } else {
+ logger.Warnw("could not create Voltha UniPort", log.Fields{
+ "device-id": apDeviceHandler.device.Id, "PortNo": oo.portNo})
+ return errors.New("create Voltha UniPort failed")
+ }
+ return nil
+}
+
+//setOperState modifies OperState of the the UniPort
+func (oo *onuUniPort) setOperState(aNewOperState vc.OperStatus_Types) {
+ oo.operState = aNewOperState
+}
+
+// uni port related utility functions (so far only used here)
+func genMacFromOctets(aOctets [6]uint8) string {
+ return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
+ aOctets[5], aOctets[4], aOctets[3],
+ aOctets[2], aOctets[1], aOctets[0])
+}
+
+//copied from OLT Adapter: unify centrally ?
+func macAddressToUint32Array(mac string) []uint32 {
+ slist := strings.Split(mac, ":")
+ result := make([]uint32, len(slist))
+ var err error
+ var tmp int64
+ for index, val := range slist {
+ if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
+ return []uint32{1, 2, 3, 4, 5, 6}
+ }
+ result[index] = uint32(tmp)
+ }
+ return result
+}