Commit to support OF Version negotiation
https://jira.opencord.org/browse/VOL-38
Addressed review comments
Change-Id: Ia731e7da3167dec01d87c6c61f1e37c96bffd55d
diff --git a/ofagent/loxi/of13/common.py b/ofagent/loxi/of13/common.py
index 4bf1750..eb95605 100644
--- a/ofagent/loxi/of13/common.py
+++ b/ofagent/loxi/of13/common.py
@@ -1947,6 +1947,21 @@
 
 hello_elem.subtypes[1] = hello_elem_versionbitmap
 
+class hello_elem_bitmap(loxi.OFObject):
+
+    def __init__(self, version_list=None):
+        if version_list != None:
+            self.version_list = version_list
+        else:
+            self.version_list = []
+        self.bitmap = 0
+        for version in version_list:
+            self.bitmap = self.bitmap | 1 << version
+        return
+
+    def pack(self):
+        return struct.pack("!L", self.bitmap)
+
 class match_v3(loxi.OFObject):
     type = 1
 
diff --git a/ofagent/loxi/of13/util.py b/ofagent/loxi/of13/util.py
index 5eadb10..3735787 100644
--- a/ofagent/loxi/of13/util.py
+++ b/ofagent/loxi/of13/util.py
@@ -121,3 +121,13 @@
 def unpack_checksum_128(reader):
     hi, lo = reader.read("!QQ")
     return (hi << 64) | lo
+
+def bitmap_to_version(bitmaps):
+    versions = [i * 32 + shift
+                for i, bitmap in enumerate(bitmaps)
+                for shift in range(31) if bitmap & (1 << shift)]
+    return versions
+
+def verify_version_support(msg,version_list):
+    version_list_sup = bitmap_to_version([msg.elements[0].bitmaps[0].value])
+    return any(i in version_list_sup for i in version_list)
diff --git a/ofagent/of_protocol_handler.py b/ofagent/of_protocol_handler.py
index bc6aa66..1780244 100644
--- a/ofagent/of_protocol_handler.py
+++ b/ofagent/of_protocol_handler.py
@@ -27,6 +27,8 @@
 
 class OpenFlowProtocolHandler(object):
 
+    ofp_version = [4]  # OFAgent supported versions
+
     def __init__(self, datapath_id, device_id, agent, cxn, rpc):
         """
         The upper half of the OpenFlow protocol, focusing on message
@@ -51,16 +53,22 @@
         log.debug('starting')
 
         try:
+            support = False
             # send initial hello message
-            self.cxn.send(ofp.message.hello())
-
+            self.cxn.send(ofp.message.hello(elements=[ofp.common.hello_elem_versionbitmap(
+                bitmaps = [ofp.common.hello_elem_bitmap(self.ofp_version)])]))
             # expect to receive a hello message
             msg = yield self.cxn.recv_class(ofp.message.hello)
-            # verify version compatibility (must list version 1.3)
-            # and negotiate if not.
-            # see https://jira.opencord.org/browse/CORD-822
+            # supports only ofp_versions till 31 and single bitmap.
+            if msg:
+                support = ofp.util.verify_version_support(msg,self.ofp_version)
+                if not support:
+                    self.cxn.send(ofp.message.hello_failed_error_msg(
+                        xid=msg.xid, code=ofp.OFPHFC_INCOMPATIBLE,
+                        data='i support only 1.3'))
+                    log.error('peer-do-not-support-OpenFlow-version',self.ofp_version)
 
-            while True:
+            while support:
                 req = yield self.cxn.recv_any()
                 handler = self.main_handlers.get(req.type, None)
                 if handler: