[VOL-4137] Receiving logical device deletion event from rw-core for immediate disconnection from ONOS

Change-Id: I82a4c2995dc76066fc4f2ed6908996e6f9194c3b
diff --git a/internal/pkg/ofagent/changeEvent.go b/internal/pkg/ofagent/changeEvent.go
index 6ea7f12..7f71701 100644
--- a/internal/pkg/ofagent/changeEvent.go
+++ b/internal/pkg/ofagent/changeEvent.go
@@ -19,13 +19,13 @@
 import (
 	"context"
 	"encoding/json"
-	"net"
-
 	"github.com/golang/protobuf/ptypes/empty"
 	ofp "github.com/opencord/goloxi/of13"
 	"github.com/opencord/ofagent-go/internal/pkg/openflow"
 	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	"github.com/opencord/voltha-protos/v5/go/openflow_13"
 	"google.golang.org/grpc"
+	"net"
 )
 
 func (ofa *OFAgent) receiveChangeEvents(ctx context.Context) {
@@ -90,8 +90,8 @@
 					log.Fields{
 						"device-id": deviceID,
 						"error":     errMsg})
-				header := errMsg.Header
 
+				header := errMsg.Header
 				ofErrMsg := ofp.NewFlowModFailedErrorMsg()
 
 				ofErrMsg.SetXid(header.Xid)
@@ -142,6 +142,16 @@
 				if err := ofa.getOFClient(ctx, deviceID).SendMessage(ctx, ofPortStatus); err != nil {
 					logger.Errorw(ctx, "handle-change-events-send-message", log.Fields{"error": err})
 				}
+			} else if deviceStatus := changeEvent.GetDeviceStatus(); deviceStatus != nil {
+				if deviceStatus.Status == openflow_13.OfpDeviceConnection_OFPDEV_DISCONNECTED {
+					logger.Debugw(ctx, "received-device-disconnect",
+						log.Fields{
+							"device-id": deviceID})
+					ofa.mapLock.Lock()
+					ofa.clientMap[deviceID].Stop()
+					delete(ofa.clientMap, deviceID)
+					ofa.mapLock.Unlock()
+				}
 			} else {
 				if logger.V(log.WarnLevel) {
 					js, _ := json.Marshal(changeEvent.GetEvent())
diff --git a/internal/pkg/openflow/client.go b/internal/pkg/openflow/client.go
index 9097444..1785d35 100644
--- a/internal/pkg/openflow/client.go
+++ b/internal/pkg/openflow/client.go
@@ -219,6 +219,11 @@
 // Stop initiates a shutdown of the OFClient
 func (ofc *OFClient) Stop() {
 	for _, connection := range ofc.connections {
+		for len(connection.sendChannel) > 0 || connection.lastUnsentMessage != nil {
+			logger.Debugw(context.Background(), "waiting for channel to be empty before closing", log.Fields{
+				"len": connection.sendChannel})
+			//do nothing, waiting for the channel to send the messages
+		}
 		connection.events <- ofcEventStop
 	}
 }