VOL-3608 Support of Get External OMCI Attribute values - GetOnuUniInfoResponse in golang OpenONU adapter
Change-Id: I8c944d66e9ad71a49b817814ff4f130ebdcc17c9
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 5e6e499..f690e38 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -36,6 +36,7 @@
flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
"github.com/opencord/voltha-lib-go/v4/pkg/log"
vc "github.com/opencord/voltha-protos/v4/go/common"
+ "github.com/opencord/voltha-protos/v4/go/extension"
ic "github.com/opencord/voltha-protos/v4/go/inter_container"
"github.com/opencord/voltha-protos/v4/go/openflow_13"
of "github.com/opencord/voltha-protos/v4/go/openflow_13"
@@ -2701,3 +2702,9 @@
}
}
}
+
+func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
+
+ portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
+ return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
+}
diff --git a/internal/pkg/onuadaptercore/openonu.go b/internal/pkg/onuadaptercore/openonu.go
index 598be4a..51978dc 100644
--- a/internal/pkg/onuadaptercore/openonu.go
+++ b/internal/pkg/onuadaptercore/openonu.go
@@ -519,9 +519,21 @@
return nil, errors.New("unImplemented")
}
-// Single_get_value_request - unimplemented
+//Single_get_value_request handles the core request to retrieve uni status
func (oo *OpenONUAC) Single_get_value_request(ctx context.Context, request extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error) {
- return nil, errors.New("unImplemented")
+ logger.Infow(ctx, "Single_get_value_request", log.Fields{"request": request})
+
+ if handler := oo.getDeviceHandler(ctx, request.TargetId, false); handler != nil {
+ switch reqType := request.GetRequest().GetRequest().(type) {
+ case *extension.GetValueRequest_UniInfo:
+ return handler.getUniPortStatus(ctx, reqType.UniInfo), nil
+ default:
+ return postUniStatusErrResponse(extension.GetValueResponse_UNSUPPORTED), nil
+
+ }
+ }
+ logger.Errorw(ctx, "Single_get_value_request failed ", log.Fields{"request": request})
+ return postUniStatusErrResponse(extension.GetValueResponse_INVALID_DEVICE_ID), nil
}
// Adapter interface required methods ################ end #########
diff --git a/internal/pkg/onuadaptercore/uniportstatus.go b/internal/pkg/onuadaptercore/uniportstatus.go
new file mode 100644
index 0000000..ba4bdf0
--- /dev/null
+++ b/internal/pkg/onuadaptercore/uniportstatus.go
@@ -0,0 +1,164 @@
+/*
+ * 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"
+ "github.com/opencord/omci-lib-go"
+ me "github.com/opencord/omci-lib-go/generated"
+ "github.com/opencord/voltha-lib-go/v4/pkg/log"
+ "github.com/opencord/voltha-protos/v4/go/extension"
+ "time"
+)
+
+const (
+ uniStatusTimeout = 3
+ adminState = "AdministrativeState"
+ operationalState = "OperationalState"
+ configInd = "ConfigurationInd"
+)
+
+//UniPortStatus implements methods to get uni port status info
+type UniPortStatus struct {
+ omciRespChn chan Message
+ pOmiCC *omciCC
+ pLastTxMeInstance *me.ManagedEntity
+}
+
+//NewUniPortStatus creates a new instance of UniPortStatus
+func NewUniPortStatus(pOmicc *omciCC) *UniPortStatus {
+ return &UniPortStatus{
+ omciRespChn: make(chan Message),
+ pOmiCC: pOmicc,
+ }
+
+}
+
+func (portStatus *UniPortStatus) getUniPortStatus(ctx context.Context, uniIdx uint32) *extension.SingleGetValueResponse {
+ for _, uniPort := range portStatus.pOmiCC.pBaseDeviceHandler.uniEntityMap {
+
+ if uniPort.uniID == uint8(uniIdx) && uniPort.portType == uniPPTP {
+
+ requestedAttributes := me.AttributeValueMap{adminState: 0, operationalState: 0, configInd: 0}
+ if meInstance := portStatus.pOmiCC.sendGetMe(ctx, me.PhysicalPathTerminationPointEthernetUniClassID, uniPort.entityID, requestedAttributes, ConstDefaultOmciTimeout, true, portStatus.omciRespChn); meInstance != nil {
+ portStatus.pLastTxMeInstance = meInstance
+
+ //verify response
+ return portStatus.waitforgetUniPortStatus(ctx, meInstance)
+ }
+ }
+ }
+ logger.Errorw(ctx, "getUniPortStatus uniIdx is not valid", log.Fields{"uniIdx": uniIdx})
+ return postUniStatusErrResponse(extension.GetValueResponse_INVALID_PORT_TYPE)
+}
+
+func (portStatus *UniPortStatus) waitforgetUniPortStatus(ctx context.Context, apMeInstance *me.ManagedEntity) *extension.SingleGetValueResponse {
+
+ select {
+ // maybe be also some outside cancel (but no context modeled for the moment ...)
+ case <-ctx.Done():
+ logger.Errorf(ctx, "waitforgetUniPortStatus Context done")
+ return postUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+ case <-time.After(uniStatusTimeout * time.Second):
+ logger.Errorf(ctx, "waitforgetUniPortStatus timeout")
+ return postUniStatusErrResponse(extension.GetValueResponse_TIMEOUT)
+
+ case omciMsg := <-portStatus.omciRespChn:
+ if omciMsg.Type != OMCI {
+ return postUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+ }
+ msg, _ := omciMsg.Data.(OmciMessage)
+ return portStatus.processGetUnitStatusResp(ctx, msg)
+ }
+
+}
+
+func (portStatus *UniPortStatus) processGetUnitStatusResp(ctx context.Context, msg OmciMessage) *extension.SingleGetValueResponse {
+ logger.Debugw(ctx, "processGetUniStatusResp:", log.Fields{"msg.Omci.MessageType": msg.OmciMsg.MessageType,
+ "msg.OmciMsg.TransactionID": msg.OmciMsg.TransactionID, "DeviceIdentfier": msg.OmciMsg.DeviceIdentifier})
+
+ if msg.OmciMsg.MessageType != omci.GetResponseType {
+ logger.Debugw(ctx, "processGetUniStatusResp error", log.Fields{"incorrect RespType": msg.OmciMsg.MessageType,
+ "expected": omci.GetResponseType})
+ return postUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+ }
+
+ msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
+ if msgLayer == nil {
+ logger.Errorf(ctx, "processGetUniStatusResp omci Msg layer not found - ")
+ return postUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+
+ }
+ msgObj, msgOk := msgLayer.(*omci.GetResponse)
+ if !msgOk {
+ logger.Errorf(ctx, "processGetUniStatusResp omci msgObj layer could not be found ")
+ return postUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+
+ }
+
+ if msgObj.Result != me.Success {
+ return postUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+ }
+ meAttributes := msgObj.Attributes
+
+ singleValResp := extension.SingleGetValueResponse{
+ Response: &extension.GetValueResponse{
+ Status: extension.GetValueResponse_OK,
+ Response: &extension.GetValueResponse_UniInfo{
+ UniInfo: &extension.GetOnuUniInfoResponse{},
+ },
+ },
+ }
+ if meAttributes[operationalState].(uint8) == 0 {
+ singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_ENABLED
+ } else if meAttributes[operationalState].(uint8) == 1 {
+ singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_DISABLED
+ } else {
+ singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_OPERSTATE_UNDEFINED
+ }
+
+ if meAttributes[adminState].(uint8) == 0 {
+ singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_UNLOCKED
+ } else if meAttributes[adminState].(uint8) == 1 {
+ singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_LOCKED
+ } else {
+ singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_ADMSTATE_UNDEFINED
+ }
+ configIndMap := map[uint8]extension.GetOnuUniInfoResponse_ConfigurationInd{
+ 0: 0,
+ 1: extension.GetOnuUniInfoResponse_TEN_BASE_T_FDX,
+ 2: extension.GetOnuUniInfoResponse_HUNDRED_BASE_T_FDX,
+ 3: extension.GetOnuUniInfoResponse_GIGABIT_ETHERNET_FDX,
+ 4: extension.GetOnuUniInfoResponse_TEN_G_ETHERNET_FDX,
+ 17: extension.GetOnuUniInfoResponse_TEN_BASE_T_HDX,
+ 18: extension.GetOnuUniInfoResponse_HUNDRED_BASE_T_HDX,
+ 19: extension.GetOnuUniInfoResponse_GIGABIT_ETHERNET_HDX,
+ }
+ configInd := meAttributes[configInd].(uint8)
+ singleValResp.Response.GetUniInfo().ConfigInd = configIndMap[configInd]
+ return &singleValResp
+}
+
+func postUniStatusErrResponse(reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
+ return &extension.SingleGetValueResponse{
+ Response: &extension.GetValueResponse{
+ Status: extension.GetValueResponse_ERROR,
+ ErrReason: reason,
+ },
+ }
+}