VOL-2171: MDS values calculated incorrectly

G.984 and G.988 both specify the MDS increment
must not include 0.  Fix that.

Also when reconciliation is complete use the successes
value for setting the new mds on the onu.  This value
is more reliable as the old mds increment was based on
the previous sync.

Also this forces the mds set to not be based on a query thats
subject to the event bus on_set_response queue, that may still be
catching up recording the updates to the database.  Setting the MDS from
within the on_set_response using what was actually sent allows all other
events to be processed in order and ensures that whats set on the onu matches
what is set in openomci database.  Before the mds was queried and set too
soon and updates came in later and the values did not match.

Also provide a way to query vendor_id

Change-Id: I0883b25ae59ef5eef409cd76f7c0e1012e8388fe
diff --git a/VERSION b/VERSION
index 7b06a96..21bb5e1 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.5-dev0
+2.2.5
diff --git a/pyvoltha/adapters/extensions/omci/onu_configuration.py b/pyvoltha/adapters/extensions/omci/onu_configuration.py
index 092f669..69823ef 100644
--- a/pyvoltha/adapters/extensions/omci/onu_configuration.py
+++ b/pyvoltha/adapters/extensions/omci/onu_configuration.py
@@ -140,6 +140,17 @@
         return ontg[ATTRIBUTES_KEY].get('version')
 
     @property
+    def vendor_id(self):
+        """
+        This attribute identifies the vendor id of the onu. e.g BRCM, ADTN, ALCL
+        """
+        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
+        if ontg is None or ATTRIBUTES_KEY not in ontg:
+            return None
+
+        return ontg[ATTRIBUTES_KEY].get('vendor_id')
+
+    @property
     def serial_number(self):
         """
         The serial number is unique for each ONU
diff --git a/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py b/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py
index d38cbaf..a128816 100644
--- a/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py
+++ b/pyvoltha/adapters/extensions/omci/state_machines/mib_sync.py
@@ -226,7 +226,8 @@
     def increment_mib_data_sync(self):
         self._mib_data_sync += 1
         if self._mib_data_sync > 255:
-            self._mib_data_sync = 0
+            # per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
+            self._mib_data_sync = 1
 
         if self._database is not None:
             self._database.save_mib_data_sync(self._device_id,
@@ -885,10 +886,18 @@
                                   unsupported_attribute_mask=rx_omci_msg['unsupported_attributes_mask'],
                                   failed_attribute_mask=rx_omci_msg['failed_attributes_mask'])
 
-                # Save to the database. A set of MDS in the OntData class results in
-                # an increment. However, we do not save that within the class/entity
-                # portion of the database.
+                # Save to the database.
+                #
+                # If an MDS was being set and succeeded use the value that was sent and store in our local db.
+                # A set of MDS in the OntData class also results in an increment of that value on the onu. Reflect that as well.
+                # We do not save MDS within the class/entity portion of the database as it has its own attribute
                 if class_id == OntData.class_id and len(attributes) > 0:
+                    self.log.debug("set-response-ontdata", attributes=attributes)
+                    if 'mib_data_sync' in attributes:
+                        # setting requires mds in higher order bits.  shift back down again to get true value
+                        self._mib_data_sync = (attributes['mib_data_sync'] >> 8) & 0xFF
+                        self._database.save_mib_data_sync(self._device_id,
+                                                          self._mib_data_sync)
                     self.increment_mib_data_sync()
 
                 elif len(attributes) > 0:
diff --git a/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py b/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py
index 046d306..bd3fe08 100644
--- a/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py
+++ b/pyvoltha/adapters/extensions/omci/tasks/mib_reconcile_task.py
@@ -151,7 +151,7 @@
 
             # Success? Update MIB-data-sync
             if failures == 0:
-                results = yield self.update_mib_data_sync()
+                results = yield self.update_mib_data_sync(successes)
                 successes += results[0]
                 failures += results[1]
 
@@ -671,7 +671,7 @@
         returnValue(mds)
 
     @inlineCallbacks
-    def update_mib_data_sync(self):
+    def update_mib_data_sync(self, successes):
         """
         As the final step of MIB resynchronization, the OLT sets the MIB data sync
         attribute of the ONU data ME to some suitable value of its own choice. It
@@ -681,26 +681,23 @@
         :return: (int, int) success, failure counts
         """
         # Get MDS to set
-        self._sync_sm.increment_mib_data_sync()
-        new_mds_value = self._sync_sm.mib_data_sync
+        new_mds_value = self.calculate_new_mds(successes)
+        self.log.debug('mds-from-successes', successes=successes, new_mds=new_mds_value)
 
         # Update it.  The set response will be sent on the OMCI-CC pub/sub bus
         # and the MIB Synchronizer will update this MDS value in the database
         # if successful.
         try:
-            # previous_mds = yield self._get_current_mds()
+            previous_mds = yield self._get_current_mds()
 
             frame = OntDataFrame(mib_data_sync=new_mds_value).set()
 
             results = yield self._device.omci_cc.send(frame)
-            self.check_status_and_state(results, 'ont-data-mbs-update')
+            self.check_status_and_state(results, 'ont-data-mds-update')
 
-            #########################################
-            # Debug.  Verify new MDS value was received. Should be 1 greater
-            #         than what was sent
-            # new_mds = yield self._get_current_mds()
-            # self.log.info('mds-update', previous=previous_mds, new=new_mds_value, now=new_mds)
-            # Done
+            # Verify new MDS value was received. Should be 1 greater than what was sent
+            new_mds = yield self._get_current_mds()
+            self.log.info('mds-set', onu_old_mds=previous_mds, sent_mds=new_mds_value, onu_new_mds=new_mds)
             returnValue((1, 0))
 
         except TimeoutError as e:
@@ -753,3 +750,11 @@
         return [(cid, eid) for cid, eid in cid_eid_list if cid in me_map and
                 (OP.Create in me_map[cid].mandatory_operations or
                  OP.Create in me_map[cid].optional_operations)]
+
+    def calculate_new_mds(self, counter):
+        new_mds_value = counter % 255
+        if new_mds_value == 0:
+            # per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
+            new_mds_value = 1
+
+        return new_mds_value