Netopeer NETCONF server integration

Amendments:

- Removed local copy of golang package. Added instructions to download it.
- Removed cached files which are created when transapi is built.
- Added netopeer as a build-able Makefile component.
  Updated documentation.

Change-Id: I532e813b81a0531648c5a6bcb048208700cf57a4
diff --git a/netopeer/voltha-grpc-client/voltha.go b/netopeer/voltha-grpc-client/voltha.go
new file mode 100644
index 0000000..2c7853a
--- /dev/null
+++ b/netopeer/voltha-grpc-client/voltha.go
@@ -0,0 +1,497 @@
+//package voltha
+package main
+
+/*
+#include <stdlib.h>
+#include "voltha-defs.h"
+ */
+import "C"
+
+import (
+	"log"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/hashicorp/consul/api"
+	pb "github.com/opencord/voltha/netconf/translator/voltha"
+	pb_health "github.com/opencord/voltha/netconf/translator/voltha/health"
+	pb_device "github.com/opencord/voltha/netconf/translator/voltha/device"
+	pb_adapter "github.com/opencord/voltha/netconf/translator/voltha/adapter"
+	pb_logical_device "github.com/opencord/voltha/netconf/translator/voltha/logical_device"
+	pb_openflow "github.com/opencord/voltha/netconf/translator/voltha/openflow_13"
+	pb_any "github.com/golang/protobuf/ptypes/any"
+	"unsafe"
+	"fmt"
+)
+
+const (
+	default_consul_address = "10.100.198.220:8500"
+	default_grpc_address   = "localhost:50555"
+	grpc_service_name      = "voltha-grpc"
+)
+
+var (
+	GrpcConn           *grpc.ClientConn              = nil
+	VolthaGlobalClient pb.VolthaGlobalServiceClient  = nil
+	HealthClient       pb_health.HealthServiceClient = nil
+	ConsulClient       *api.Client                   = nil
+	GrpcServiceAddress string                        = "localhost:50555"
+)
+
+func init() {
+	ConsulClient = connect_to_consul(default_consul_address)
+	GrpcServiceAddress = get_consul_service_address(grpc_service_name)
+	GrpcConn = connect_to_grpc(GrpcServiceAddress)
+
+	VolthaGlobalClient = pb.NewVolthaGlobalServiceClient(GrpcConn)
+	HealthClient = pb_health.NewHealthServiceClient(GrpcConn)
+}
+
+func connect_to_consul(consul_address string) *api.Client {
+	cfg := api.Config{Address: consul_address }
+
+	log.Printf("Connecting to consul - address: %s", consul_address)
+
+	client, err := api.NewClient(&cfg)
+	if err != nil {
+		panic(err)
+	}
+
+	log.Printf("Connected to consul - address: %s", consul_address)
+
+	return client
+}
+
+func get_consul_service_address(service_name string) string {
+	var service []*api.CatalogService
+	var err error
+
+	log.Printf("Getting consul service - name:%s", service_name)
+
+	if service, _, _ = ConsulClient.Catalog().Service(service_name, "", nil); err != nil {
+		panic(err)
+	}
+
+	address := fmt.Sprintf("%s:%d", service[0].ServiceAddress, service[0].ServicePort)
+
+	log.Printf("Got consul service - name:%s, address:%s", service_name, address)
+
+	return address
+}
+
+func connect_to_grpc(grpc_address string) *grpc.ClientConn {
+	var err error
+	var client *grpc.ClientConn
+
+	log.Printf("Connecting to grpc - address: %s", grpc_address)
+
+	// Set up a connection to the server.
+	client, err = grpc.Dial(grpc_address, grpc.WithInsecure())
+	if err != nil {
+		log.Fatalf("did not connect: %s", err.Error())
+	}
+
+	log.Printf("Connected to grpc - address: %s", grpc_address)
+
+	return client
+}
+// Utility methods
+
+// -------------------------------------------------
+// C to Protobuf conversion methods
+// -------------------------------------------------
+
+func _c_to_proto_Address(address C.isDevice_Address) *pb_device.Device {
+	var device *pb_device.Device
+
+	// Identify the address type to assign
+	switch address.Type {
+	case C.MAC:
+		device.Address = &pb_device.Device_MacAddress{
+			MacAddress: C.GoString(address.Value),
+		}
+		break
+	case C.IPV4:
+		device.Address = &pb_device.Device_Ipv4Address{
+			Ipv4Address: C.GoString(address.Value),
+		}
+		break
+	case C.IPV6:
+		device.Address = &pb_device.Device_Ipv6Address{
+			Ipv6Address: C.GoString(address.Value),
+		}
+		break
+	case C.HOST_AND_PORT:
+		device.Address = &pb_device.Device_HostAndPort{
+			HostAndPort: C.GoString(address.Value),
+		}
+		break
+	}
+
+	return device
+}
+
+// -------------------------------------------------
+// Protobuf to C conversion methods
+// -------------------------------------------------
+
+func _proto_to_c_Adapters(instances []*pb_adapter.Adapter) C.AdapterArray {
+	// TODO: not implemented
+	var result C.AdapterArray
+	return result
+}
+func _proto_to_c_LogicalDevices(instances []*pb_logical_device.LogicalDevice) C.LogicalDeviceArray {
+	// TODO: not implemented
+	var result C.LogicalDeviceArray
+	return result
+}
+func _proto_to_c_DeviceTypes(instances []*pb_device.DeviceType) C.DeviceTypeArray {
+	// TODO: not implemented
+	var result C.DeviceTypeArray
+	return result
+}
+func _proto_to_c_AlarmFilters(instances []*pb.AlarmFilter) C.AlarmFilterArray {
+	// TODO: not implemented
+	var result C.AlarmFilterArray
+	return result
+}
+func _proto_to_c_DeviceGroups(instances []*pb.DeviceGroup) C.DeviceGroupArray {
+	// TODO: not implemented
+	var result C.DeviceGroupArray
+	return result
+}
+func _proto_to_c_ProxyAddress(proxyAddress *pb_device.Device_ProxyAddress) *C.Device_ProxyAddress {
+	// TODO: not implemented
+	var result *C.Device_ProxyAddress
+	defer C.free(unsafe.Pointer(result))
+	return result
+}
+func _proto_to_c_Ports(ports []*pb_device.Port) C.PortArray {
+	// TODO: not implemented
+	var result C.PortArray
+	return result
+}
+func _proto_to_c_Flows(flows *pb_openflow.Flows) *C.Flows {
+	// TODO: not implemented
+	var result *C.Flows
+	defer C.free(unsafe.Pointer(result))
+	return result
+}
+func _proto_to_c_FlowGroups(groups *pb_openflow.FlowGroups) *C.FlowGroups {
+	// TODO: not implemented
+	var result *C.FlowGroups
+	defer C.free(unsafe.Pointer(result))
+	return result
+}
+func _proto_to_c_PmConfigs(configs *pb_device.PmConfigs) *C.PmConfigs {
+	// TODO: not implemented
+	var result *C.PmConfigs
+	defer C.free(unsafe.Pointer(result))
+	return result
+}
+func _proto_to_c_Custom(configs *pb_any.Any) *C.Any {
+	// TODO: not implemented
+	var result *C.Any
+	defer C.free(unsafe.Pointer(result))
+	return result
+}
+func _proto_to_c_HealthStatus(health *pb_health.HealthStatus) C.HealthStatus {
+	var result C.HealthStatus
+
+	var c_string *C.char
+	defer C.free(unsafe.Pointer(c_string))
+
+	if c_string = C.CString(health.GetState().String()); c_string != nil {
+		result.State = c_string
+	}
+
+	return result
+}
+
+func _proto_to_c_VolthaInstances(instances []*pb.VolthaInstance) C.VolthaInstanceArray {
+	var result C.VolthaInstanceArray
+	var c_string *C.char
+	var c_voltha_instance C.VolthaInstance
+	defer C.free(unsafe.Pointer(c_string))
+
+	sizeof := unsafe.Sizeof(c_voltha_instance)
+	count := len(instances)
+	result.size = C.int(count)
+
+	c_items := C.malloc(C.size_t(result.size) * C.size_t(sizeof))
+	defer C.free(unsafe.Pointer(c_items))
+
+	// Array to the allocated space
+	c_array := (*[1<<30 - 1]C.VolthaInstance)(c_items)
+
+	for index, value := range instances {
+		if c_string = C.CString(value.GetInstanceId()); c_string != nil {
+			c_voltha_instance.InstanceId = c_string
+		}
+		if c_string = C.CString(value.GetVersion()); c_string != nil {
+			c_voltha_instance.Version = c_string
+		}
+		if c_string = C.CString(value.GetLogLevel().String()); c_string != nil {
+			c_voltha_instance.LogLevel = c_string
+		}
+		c_voltha_instance.Health = _proto_to_c_HealthStatus(value.GetHealth())
+		c_voltha_instance.Adapters = _proto_to_c_Adapters(value.GetAdapters())
+		c_voltha_instance.LogicalDevices = _proto_to_c_LogicalDevices(value.GetLogicalDevices())
+		c_voltha_instance.Devices = _proto_to_c_Devices(value.GetDevices())
+		c_voltha_instance.DeviceTypes = _proto_to_c_DeviceTypes(value.GetDeviceTypes())
+		c_voltha_instance.DeviceGroups = _proto_to_c_DeviceGroups(value.GetDeviceGroups())
+		c_voltha_instance.AlarmFilters = _proto_to_c_AlarmFilters(value.GetAlarmFilters())
+
+		c_array[index] = c_voltha_instance
+	}
+
+	result.items = (*C.VolthaInstance)(unsafe.Pointer(c_array))
+
+	return result
+}
+func _proto_to_c_Devices(instances []*pb_device.Device) C.DeviceArray {
+	var result C.DeviceArray
+	var c_string *C.char
+	var c_device_instance C.Device
+	defer C.free(unsafe.Pointer(c_string))
+
+	sizeof := unsafe.Sizeof(c_device_instance)
+	count := len(instances)
+	result.size = C.int(count)
+
+	c_items := C.malloc(C.size_t(result.size) * C.size_t(sizeof))
+	defer C.free(unsafe.Pointer(c_items))
+
+	c_array := (*[1<<30 - 1]C.Device)(c_items)
+
+	for index, value := range instances {
+		c_array[index] = _proto_to_c_Device(value)
+	}
+
+	result.items = (*C.Device)(unsafe.Pointer(c_array))
+
+	return result
+}
+func _proto_to_c_Voltha(voltha *pb.Voltha) C.Voltha {
+	var result C.Voltha
+	var c_string *C.char
+	defer C.free(unsafe.Pointer(c_string))
+
+	if c_string = C.CString(voltha.GetVersion()); c_string != nil {
+		result.Version = c_string
+	}
+	if c_string = C.CString(voltha.GetLogLevel().String()); c_string != nil {
+		result.LogLevel = c_string
+	}
+
+	result.Instances = _proto_to_c_VolthaInstances(voltha.GetInstances())
+	result.Adapters = _proto_to_c_Adapters(voltha.GetAdapters())
+	result.LogicalDevices = _proto_to_c_LogicalDevices(voltha.GetLogicalDevices())
+	result.Devices = _proto_to_c_Devices(voltha.GetDevices())
+	result.DeviceGroups = _proto_to_c_DeviceGroups(voltha.GetDeviceGroups())
+
+	return result
+}
+
+func _proto_to_c_Address(device *pb_device.Device) C.isDevice_Address {
+	var address C.isDevice_Address
+	var c_string *C.char
+	defer C.free(unsafe.Pointer(c_string))
+
+	switch device.GetAddress().(type) {
+	case *pb_device.Device_MacAddress:
+		address.Type = C.MAC
+		c_string = C.CString(device.GetMacAddress())
+		address.Value = c_string
+	case *pb_device.Device_Ipv4Address:
+		address.Type = C.IPV4
+		c_string = C.CString(device.GetIpv4Address())
+		address.Value = c_string
+	case *pb_device.Device_Ipv6Address:
+		address.Type = C.IPV6
+		c_string = C.CString(device.GetIpv6Address())
+		address.Value = c_string
+	case *pb_device.Device_HostAndPort:
+		address.Type = C.HOST_AND_PORT
+		c_string = C.CString(device.GetHostAndPort())
+		address.Value = c_string
+	}
+	return address
+}
+
+func _proto_to_c_Device(device *pb_device.Device) C.Device {
+	var result C.Device
+	var c_string *C.char
+	defer C.free(unsafe.Pointer(c_string))
+
+	if c_string = C.CString(device.GetId()); c_string != nil {
+		result.Id = c_string
+	}
+	if c_string = C.CString(device.GetType()); c_string != nil {
+		result.Type = c_string
+	}
+	if device.GetRoot() {
+		result.Root = C.int(1)
+	} else {
+		result.Root = C.int(0)
+	}
+	if c_string = C.CString(device.GetParentId()); c_string != nil {
+		result.ParentId = c_string
+	}
+
+	result.ParentPortNo = C.uint32_t(device.GetParentPortNo())
+
+	if c_string = C.CString(device.GetVendor()); c_string != nil {
+		result.Vendor = c_string
+	}
+	if c_string = C.CString(device.GetModel()); c_string != nil {
+		result.Model = c_string
+	}
+	if c_string = C.CString(device.GetHardwareVersion()); c_string != nil {
+		result.HardwareVersion = c_string
+	}
+	if c_string = C.CString(device.GetFirmwareVersion()); c_string != nil {
+		result.FirmwareVersion = c_string
+	}
+	if c_string = C.CString(device.GetSoftwareVersion()); c_string != nil {
+		result.SoftwareVersion = c_string
+	}
+	if c_string = C.CString(device.GetSerialNumber()); c_string != nil {
+		result.SerialNumber = c_string
+	}
+	if c_string = C.CString(device.GetAdapter()); c_string != nil {
+		result.Adapter = c_string
+	}
+
+	result.Vlan = C.uint32_t(device.GetVlan())
+	result.ProxyAddress = _proto_to_c_ProxyAddress(device.GetProxyAddress())
+
+	if c_string = C.CString(device.GetAdminState().String()); c_string != nil {
+		result.AdminState = c_string
+	}
+	if c_string = C.CString(device.GetOperStatus().String()); c_string != nil {
+		result.OperStatus = c_string
+	}
+	if c_string = C.CString(device.GetReason()); c_string != nil {
+		result.Reason = c_string
+	}
+	if c_string = C.CString(device.GetConnectStatus().String()); c_string != nil {
+		result.ConnectStatus = c_string
+	}
+
+	result.Custom = _proto_to_c_Custom(device.GetCustom())
+	result.Ports = _proto_to_c_Ports(device.GetPorts())
+	result.Flows = _proto_to_c_Flows(device.GetFlows())
+	result.FlowGroups = _proto_to_c_FlowGroups(device.GetFlowGroups())
+	result.PmConfigs = _proto_to_c_PmConfigs(device.GetPmConfigs())
+	result.Address = _proto_to_c_Address(device)
+
+	return result
+}
+
+// ---------------------------------------------------------
+// Exported methods accessible through the shared library
+// ---------------------------------------------------------
+
+//export GetHealthStatus
+func GetHealthStatus() C.HealthStatus {
+	var output *pb_health.HealthStatus
+	var err error
+
+	if output, err = HealthClient.GetHealthStatus(context.Background(), &empty.Empty{}); output == nil || err != nil {
+		log.Fatalf("Failed to retrieve health status: %s", err.Error())
+	}
+
+	return _proto_to_c_HealthStatus(output)
+}
+
+//export GetVoltha
+func GetVoltha() C.Voltha {
+	var output *pb.Voltha
+	var err error
+	if output, err = VolthaGlobalClient.GetVoltha(context.Background(), &empty.Empty{}); output == nil || err != nil {
+		log.Fatalf("Failed to retrieve voltha information: %s", err.Error())
+	}
+
+	return _proto_to_c_Voltha(output)
+}
+
+//export ListDevices
+func ListDevices() C.DeviceArray {
+	var output *pb_device.Devices
+	var err error
+	if output, err = VolthaGlobalClient.ListDevices(context.Background(), &empty.Empty{});
+		output == nil || err != nil {
+		log.Fatalf("Failed to retrieve voltha information: %s", err.Error())
+	}
+
+	return _proto_to_c_Devices(output.Items)
+}
+
+//export ListVolthaInstances
+func ListVolthaInstances() *C.char {
+	return nil
+}
+
+//export ListLogicalDevices
+func ListLogicalDevices() *C.char {
+	return nil
+}
+
+//export GetLogicalDevice
+func GetLogicalDevice(input *C.char) *C.char {
+	return nil
+}
+
+//export ListLogicalDevicePorts
+func ListLogicalDevicePorts(input *C.char) *C.char {
+	return nil
+}
+
+//export ListLogicalDeviceFlows
+func ListLogicalDeviceFlows(input *C.char) *C.char {
+	return nil
+}
+
+//export CreateDevice
+func CreateDevice(input C.Device) C.Device {
+	log.Printf("Incoming C Device - type:%v, address_type: %v, address_value:%s",
+		C.GoString(input.Type),
+		C.int(input.Address.Type),
+		C.GoString(input.Address.Value),
+	)
+
+	device := _c_to_proto_Address(input.Address)
+	device.Type = C.GoString(input.Type)
+
+	var output *pb_device.Device
+	var err error
+
+	if output, err = VolthaGlobalClient.CreateDevice(context.Background(), device);
+		output == nil || err != nil {
+		log.Fatalf("Failed to create device: %s", err.Error())
+	}
+
+	return _proto_to_c_Device(output)
+}
+
+// Debugging code
+func TestSerialize() {
+	var object C.Device
+
+	object.Type = C.CString("simulated_olt")
+	object.Address.Type = 3
+	object.Address.Value = C.CString("172.16.1.233:123")
+
+	//xmlObject, _ := xml.Marshal(object)
+	//
+	//log.Printf("object: %+v", string(xmlObject))
+
+	CreateDevice(object)
+}
+
+func main() {
+	// We need the main function to make possible
+	// CGO compiler to compile the package as C shared library
+	//TestSerialize()
+}