VOL-1647 : Support use of any NNI port

           Removed default NNI interface ID 0 which is used for flow
           installation for a perticular device.

           It is replaced with a function to fetch the NNI interface
           ID for the perticular device for which the flow is beign
           installed.

           If successful the function return the NNI interface ID of
           the device else it returns -1 and the error which in turn
           causes the flow installtion to fail.

Change-Id: Ie8c7cc881aec180b053048169d24c9eec2c602b5
diff --git a/adaptercore/openolt_flowmgr.go b/adaptercore/openolt_flowmgr.go
index 9d4ac6a..7ccf97d 100644
--- a/adaptercore/openolt_flowmgr.go
+++ b/adaptercore/openolt_flowmgr.go
@@ -50,8 +50,6 @@
 	//FIXME - see also BRDCM_DEFAULT_VLAN in broadcom_onu.py
 	DEFAULT_MGMT_VLAN = 4091
 
-	DEFAULT_NETWORK_INTERFACE_ID = 0
-
 	// Openolt Flow
 	UPSTREAM        = "upstream"
 	DOWNSTREAM      = "downstream"
@@ -353,13 +351,18 @@
 		return
 	}
 	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
+	networkIntfId, err := f.getNniIntfID()
+	if err != nil {
+		log.Error("Error in getting NNI interface ID, Failed to add HSIA flow")
+		return
+	}
 	flow := openolt_pb2.Flow{AccessIntfId: int32(intfId),
 		OnuId:         int32(onuId),
 		UniId:         int32(uniId),
 		FlowId:        flowId,
 		FlowType:      direction,
 		AllocId:       int32(allocId),
-		NetworkIntfId: DEFAULT_NETWORK_INTERFACE_ID, // one NNI port is supported now
+		NetworkIntfId: int32(networkIntfId),
 		GemportId:     int32(gemPortId),
 		Classifier:    classifierProto,
 		Action:        actionProto,
@@ -415,6 +418,11 @@
 		log.Error("Error in making action protobuf for ul flow")
 		return
 	}
+	networkIntfId, err := f.getNniIntfID()
+	if err != nil {
+		log.Error("Error in getting NNI interface ID, Failed to add DHCP Trap Flow")
+		return
+	}
 
 	dhcpFlow = openolt_pb2.Flow{AccessIntfId: int32(intfId),
 		OnuId:         int32(onuId),
@@ -422,7 +430,7 @@
 		FlowId:        flowID,
 		FlowType:      UPSTREAM,
 		AllocId:       int32(allocId),
-		NetworkIntfId: DEFAULT_NETWORK_INTERFACE_ID, // one NNI port is supported now
+		NetworkIntfId: int32(networkIntfId),
 		GemportId:     int32(gemPortId),
 		Classifier:    classifierProto,
 		Action:        actionProto,
@@ -483,13 +491,18 @@
 		return
 	}
 	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
+	networkIntfId, err := f.getNniIntfID()
+	if err != nil {
+		log.Error("Error in getting NNI interface ID, Failed to add EAPOL Flow")
+		return
+	}
 	upstreamFlow = openolt_pb2.Flow{AccessIntfId: int32(intfId),
 		OnuId:         int32(onuId),
 		UniId:         int32(uniId),
 		FlowId:        uplinkFlowId,
 		FlowType:      UPSTREAM,
 		AllocId:       int32(allocId),
-		NetworkIntfId: DEFAULT_NETWORK_INTERFACE_ID, // one NNI port is supported now
+		NetworkIntfId: int32(networkIntfId),
 		GemportId:     int32(gemPortId),
 		Classifier:    classifierProto,
 		Action:        actionProto,
@@ -556,7 +569,7 @@
 			FlowId:        downlinkFlowId,
 			FlowType:      DOWNSTREAM,
 			AllocId:       int32(allocId),
-			NetworkIntfId: DEFAULT_NETWORK_INTERFACE_ID,
+			NetworkIntfId: int32(networkIntfId),
 			GemportId:     int32(gemPortId),
 			Classifier:    classifierProto,
 			Action:        actionProto,
@@ -1052,7 +1065,11 @@
 	uniId := -1
 	gemPortId := -1
 	allocId := -1
-	networkInterfaceId := DEFAULT_NETWORK_INTERFACE_ID
+	networkInterfaceId, err := f.getNniIntfID()
+	if err != nil {
+		log.Error("Error in getting NNI interface ID, Failed to add DHCP Trap flow on NNI")
+		return
+	}
 	flowStoreCookie := getFlowStoreCookie(classifier, uint32(0))
 	if present := f.resourceMgr.IsFlowCookieOnKVStore(uint32(networkInterfaceId), uint32(onuId), uint32(uniId), flowStoreCookie); present {
 		log.Debug("Flow-exists--not-re-adding")
@@ -1080,9 +1097,9 @@
 		UniId:         int32(uniId), // UniId not used
 		FlowId:        flowId,
 		FlowType:      DOWNSTREAM,
-		AllocId:       int32(allocId),               // AllocId not used
-		NetworkIntfId: DEFAULT_NETWORK_INTERFACE_ID, // one NNI port is supported now
-		GemportId:     int32(gemPortId),             // GemportId not used
+		AllocId:       int32(allocId), // AllocId not used
+		NetworkIntfId: int32(networkInterfaceId),
+		GemportId:     int32(gemPortId), // GemportId not used
 		Classifier:    classifierProto,
 		Action:        actionProto,
 		Priority:      int32(logicalFlow.Priority),
@@ -1100,3 +1117,22 @@
 	}
 	return
 }
+
+func (f *OpenOltFlowMgr) getNniIntfID() (int32, error) {
+	device, err := f.deviceHandler.coreProxy.GetDevice(nil, f.deviceHandler.deviceId, f.deviceHandler.deviceId)
+	if err != nil {
+		log.Errorw("Failed to get device", log.Fields{"device-id": f.deviceHandler.deviceId})
+		return -1, err
+	}
+	var portNum uint32
+	for _, port := range device.Ports {
+		if port.Type == voltha.Port_ETHERNET_NNI {
+			portNum = port.PortNo
+			break
+		}
+	}
+
+	nniIntfId := IntfIdFromNniPortNum(portNum)
+	log.Debugw("NNI interface Id", log.Fields{"intf-id": nniIntfId})
+	return int32(nniIntfId), nil
+}