[VOL-936] add changes for onu distance from OLT

Change-Id: If6201799946ac753780d0424c4bd986e2fb394d2
diff --git a/common/core/northbound/grpc/default_api_handler.go b/common/core/northbound/grpc/default_api_handler.go
index 3c38459..a350bc3 100644
--- a/common/core/northbound/grpc/default_api_handler.go
+++ b/common/core/northbound/grpc/default_api_handler.go
@@ -386,3 +386,7 @@
 func (handler *DefaultAPIHandler) StartOmciTestAction(ctx context.Context, omcitestrequest *voltha.OmciTestRequest) (*voltha.TestResponse, error) {
 	return nil, errors.New("StartOmciTestAction-unimplemented")
 }
+func (handler *DefaultAPIHandler) GetExtValue(ctx context.Context, values *voltha.ValueSpecifier) (*voltha.ReturnValues, error) {
+	log.Debugw("GetExtValue-unimplemented", log.Fields{"onuid": values.Id})
+	return nil, nil
+}
diff --git a/go.mod b/go.mod
old mode 100644
new mode 100755
index b8e07f8..c49c6d2
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@
 	github.com/gogo/protobuf v1.3.0
 	github.com/golang/protobuf v1.3.2
 	github.com/google/uuid v1.1.1
-	github.com/opencord/voltha-lib-go/v3 v3.1.6
+	github.com/opencord/voltha-lib-go/v3 v3.1.7
 	github.com/opencord/voltha-protos/v3 v3.3.3
 	github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
 	github.com/stretchr/testify v1.4.0
diff --git a/go.sum b/go.sum
index a86240b..930abf8 100644
--- a/go.sum
+++ b/go.sum
@@ -196,10 +196,8 @@
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
 github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/opencord/voltha-lib-go/v3 v3.1.6 h1:lGQWLyYD/DbNMC/MSpoP78cBgXg1cLNgA4X4ygbiPFA=
-github.com/opencord/voltha-lib-go/v3 v3.1.6/go.mod h1:s8rmoVjsI0qjOf7xJIh4VmUSxZLOn/XEiFAT3Amf3y4=
-github.com/opencord/voltha-protos/v3 v3.3.2 h1:a3PKf+jaiCD15iXpgL8dqW+WvfgiM0qv7mFA4nIJtH8=
-github.com/opencord/voltha-protos/v3 v3.3.2/go.mod h1:nl1ETp5Iw3avxOaKD8BJlYY5wYI4KeV95aT1pL63nto=
+github.com/opencord/voltha-lib-go/v3 v3.1.7 h1:hPaXrYkH/gaTW5CN7F8pyeCWXAay5SHXG78uMorcyPg=
+github.com/opencord/voltha-lib-go/v3 v3.1.7/go.mod h1:26TG6ABl+ppP754YWhhgao9wKNL3SuUf/KztQcJFqrQ=
 github.com/opencord/voltha-protos/v3 v3.3.3 h1:OO0H+YMxjLFQifoYXwBp1JN5rpEVMQnhGGEdP6pLrY0=
 github.com/opencord/voltha-protos/v3 v3.3.3/go.mod h1:nl1ETp5Iw3avxOaKD8BJlYY5wYI4KeV95aT1pL63nto=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/rw_core/core/api/grpc_nbi_handler.go b/rw_core/core/api/grpc_nbi_handler.go
index 0bacb33..3e06cf7 100755
--- a/rw_core/core/api/grpc_nbi_handler.go
+++ b/rw_core/core/api/grpc_nbi_handler.go
@@ -807,6 +807,6 @@
 }
 
 func (handler *NBIHandler) GetExtValue(ctx context.Context, valueparam *voltha.ValueSpecifier) (*voltha.ReturnValues, error) {
-	log.Debugw("GetValue-request", log.Fields{"onu-id": valueparam.Id})
-	return nil, errors.New("UnImplemented")
+	log.Debugw("GetExtValue-request", log.Fields{"onu-id": valueparam.Id})
+	return handler.deviceMgr.GetExtValue(ctx, valueparam)
 }
diff --git a/rw_core/core/device/agent.go b/rw_core/core/device/agent.go
index 264b44f..3857a6b 100755
--- a/rw_core/core/device/agent.go
+++ b/rw_core/core/device/agent.go
@@ -1732,3 +1732,34 @@
 	logger.Debugw("Omci_test_Request-Success-device-agent", log.Fields{"testResp": testResp})
 	return testResp, nil
 }
+
+func (agent *Agent) getExtValue(ctx context.Context, pdevice *voltha.Device, cdevice *voltha.Device, valueparam *voltha.ValueSpecifier) (*voltha.ReturnValues, error) {
+	log.Debugw("getExtValue", log.Fields{"device-id": agent.deviceID, "onuid": valueparam.Id, "valuetype": valueparam.Value})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return nil, err
+	}
+
+	//send request to adapter
+	ch, err := agent.adapterProxy.GetExtValue(ctx, pdevice, cdevice, valueparam.Id, valueparam.Value)
+	agent.requestQueue.RequestComplete()
+	if err != nil {
+		return nil, err
+	}
+
+	// Wait for the adapter response
+	rpcResponse, ok := <-ch
+	if !ok {
+		return nil, status.Errorf(codes.Aborted, "channel-closed-device-id-%s", agent.deviceID)
+	}
+	if rpcResponse.Err != nil {
+		return nil, rpcResponse.Err
+	}
+
+	// Unmarshal and return the response
+	Resp := &voltha.ReturnValues{}
+	if err := ptypes.UnmarshalAny(rpcResponse.Reply, Resp); err != nil {
+		return nil, status.Errorf(codes.InvalidArgument, "%s", err.Error())
+	}
+	logger.Debugw("getExtValue-Success-device-agent", log.Fields{"Resp": Resp})
+	return Resp, nil
+}
diff --git a/rw_core/core/device/manager.go b/rw_core/core/device/manager.go
index cd73f35..ad2af57 100755
--- a/rw_core/core/device/manager.go
+++ b/rw_core/core/device/manager.go
@@ -1563,3 +1563,25 @@
 	}
 	return nil, status.Errorf(codes.NotFound, "%s", omcitestrequest.Id)
 }
+
+func (dMgr *Manager) GetExtValue(ctx context.Context, value *voltha.ValueSpecifier) (*voltha.ReturnValues, error) {
+	log.Debugw("getExtValue", log.Fields{"onu-id": value.Id})
+	cDevice, err := dMgr.GetDevice(ctx, value.Id)
+	if err != nil {
+		return nil, status.Errorf(codes.Aborted, "%s", err.Error())
+	}
+	pDevice, err := dMgr.GetDevice(ctx, cDevice.ParentId)
+	if err != nil {
+		return nil, status.Errorf(codes.Aborted, "%s", err.Error())
+	}
+	if agent := dMgr.getDeviceAgent(ctx, cDevice.ParentId); agent != nil {
+		resp, err := agent.getExtValue(ctx, pDevice, cDevice, value)
+		if err != nil {
+			return nil, err
+		}
+		log.Debugw("getExtValue-result", log.Fields{"result": resp})
+		return resp, nil
+	}
+	return nil, status.Errorf(codes.NotFound, "%s", value.Id)
+
+}
diff --git a/rw_core/core/device/remote/adapter_proxy.go b/rw_core/core/device/remote/adapter_proxy.go
index 4b04ee5..f4579ef 100755
--- a/rw_core/core/device/remote/adapter_proxy.go
+++ b/rw_core/core/device/remote/adapter_proxy.go
@@ -430,3 +430,30 @@
 		&kafka.KVArg{Key: "device", Value: device},
 		&kafka.KVArg{Key: "omcitestrequest", Value: omcitestrequest})
 }
+
+func (ap *AdapterProxy) GetExtValue(ctx context.Context, pdevice *voltha.Device, cdevice *voltha.Device, id string, valuetype voltha.ValueType_Type) (chan *kafka.RpcResponse, error) {
+	log.Debugw("GetExtValue", log.Fields{"device-id": pdevice.Id, "onuid": id})
+	rpc := "get_ext_value"
+	toTopic, err := ap.getAdapterTopic(pdevice.Id, pdevice.Adapter)
+	if err != nil {
+		return nil, err
+	}
+	// Use a device specific topic to send the request.  The adapter handling the device creates a device
+	// specific topic
+	args := []*kafka.KVArg{
+		{
+			Key:   "pDeviceId",
+			Value: &ic.StrType{Val: pdevice.Id},
+		},
+		{
+			Key:   "device",
+			Value: cdevice,
+		},
+		{
+			Key:   "valuetype",
+			Value: &ic.IntType{Val: int64(valuetype)},
+		}}
+
+	replyToTopic := ap.getCoreTopic()
+	return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, pdevice.Id, args...)
+}
diff --git a/rw_core/mocks/adapter.go b/rw_core/mocks/adapter.go
index 6a8fb22..e14457d 100644
--- a/rw_core/mocks/adapter.go
+++ b/rw_core/mocks/adapter.go
@@ -259,3 +259,7 @@
 func (ta *Adapter) Start_omci_test(device *voltha.Device, request *voltha.OmciTestRequest) (*voltha.TestResponse, error) { //nolint
 	return nil, nil
 }
+
+func (ta *Adapter) Get_ext_value(deviceId string, device *voltha.Device, valueflag voltha.ValueType_Type) (*voltha.ReturnValues, error) { //nolint
+	return nil, nil
+}
diff --git a/rw_core/mocks/adapter_olt.go b/rw_core/mocks/adapter_olt.go
index 5f67da7..07077c8 100644
--- a/rw_core/mocks/adapter_olt.go
+++ b/rw_core/mocks/adapter_olt.go
@@ -332,3 +332,10 @@
 
 	oltA.flows = map[uint64]*voltha.OfpFlowStats{}
 }
+
+func (oltA *OLTAdapter) Get_ext_value(deviceId string, device *voltha.Device, valueflag voltha.ValueType_Type) (*voltha.ReturnValues, error) { // nolint
+	_ = deviceId
+	_ = device
+	_ = valueflag
+	return nil, errors.New("get-ext-value-not-implemented")
+}
diff --git a/rw_core/mocks/adapter_onu.go b/rw_core/mocks/adapter_onu.go
index 549e016..5f4a5e6 100644
--- a/rw_core/mocks/adapter_onu.go
+++ b/rw_core/mocks/adapter_onu.go
@@ -18,6 +18,7 @@
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"strings"
 	"sync"
@@ -240,3 +241,10 @@
 
 	onuA.flows = map[uint64]*voltha.OfpFlowStats{}
 }
+
+func (onuA *ONUAdapter) Get_ext_value(deviceId string, device *voltha.Device, valueflag voltha.ValueType_Type) (*voltha.ReturnValues, error) { // nolint
+	_ = deviceId
+	_ = device
+	_ = valueflag
+	return nil, errors.New("get-ext-value-not-implemented")
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/common/request_handler.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/common/request_handler.go
index 843b95c..a97ae62 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/common/request_handler.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/common/request_handler.go
@@ -735,3 +735,37 @@
 	}
 	return result, nil
 }
+func (rhp *RequestHandlerProxy) Get_ext_value(args []*ic.Argument) (*voltha.ReturnValues, error) {
+	if len(args) < 3 {
+		logger.Warn("invalid-number-of-args", log.Fields{"args": args})
+		return nil, errors.New("invalid-number-of-args")
+	}
+
+	pDeviceId := &ic.StrType{}
+	device := &voltha.Device{}
+	valuetype := &ic.IntType{}
+	for _, arg := range args {
+		switch arg.Key {
+		case "device":
+			if err := ptypes.UnmarshalAny(arg.Value, device); err != nil {
+				logger.Warnw("cannot-unmarshal-device", log.Fields{"error": err})
+				return nil, err
+			}
+		case "pDeviceId":
+			if err := ptypes.UnmarshalAny(arg.Value, pDeviceId); err != nil {
+				logger.Warnw("cannot-unmarshal-parent-deviceId", log.Fields{"error": err})
+				return nil, err
+			}
+		case "valuetype":
+			if err := ptypes.UnmarshalAny(arg.Value, valuetype); err != nil {
+				logger.Warnw("cannot-unmarshal-valuetype", log.Fields{"error": err})
+				return nil, err
+			}
+		default:
+			logger.Warnw("key-not-found", log.Fields{"arg.Key": arg.Key})
+		}
+	}
+
+	//Invoke the Get_value API on the adapter
+	return rhp.adapter.Get_ext_value(pDeviceId.Val, device, voltha.ValueType_Type(valuetype.Val))
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/iAdapter.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/iAdapter.go
index 112fb94..9436963 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/iAdapter.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/adapters/iAdapter.go
@@ -53,4 +53,5 @@
 	Disable_port(deviceId string, port *voltha.Port) error
 	Child_device_lost(parentDeviceId string, parentPortNo uint32, onuID uint32) error
 	Start_omci_test(device *voltha.Device, request *voltha.OmciTestRequest) (*voltha.TestResponse, error)
+	Get_ext_value(deviceId string, device *voltha.Device, valueflag voltha.ValueType_Type) (*voltha.ReturnValues, error)
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index b81647f..dc46454 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -99,7 +99,7 @@
 github.com/modern-go/concurrent
 # github.com/modern-go/reflect2 v1.0.1
 github.com/modern-go/reflect2
-# github.com/opencord/voltha-lib-go/v3 v3.1.6
+# github.com/opencord/voltha-lib-go/v3 v3.1.7
 github.com/opencord/voltha-lib-go/v3/pkg/adapters
 github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif
 github.com/opencord/voltha-lib-go/v3/pkg/adapters/common