[VOL-5291] - Implement get alloc stats, pon-stats, nni-stats

Change-Id: I1fda9b20297641aabcb2642006e516ba3933e184
Signed-off-by: Akash Reddy Kankanala <akash.kankanala@radisys.com>
diff --git a/agent/src/stats_collection.cc b/agent/src/stats_collection.cc
index 5065f6b..20e512a 100644
--- a/agent/src/stats_collection.cc
+++ b/agent/src/stats_collection.cc
@@ -32,6 +32,7 @@
 
 //FIXME
 #define FLOWS_COUNT 100
+#define ALLOC_STATS_GET_INTERVAL 10
 
 bcmolt_flow_key* flows_keys = new bcmolt_flow_key[FLOWS_COUNT];
 bcmolt_odid device_id = 0;
@@ -40,8 +41,8 @@
     memset(flows_keys, 0, FLOWS_COUNT * sizeof(bcmolt_flow_key));
 }
 
-openolt::PortStatistics* get_default_port_statistics() {
-    openolt::PortStatistics* port_stats = new openolt::PortStatistics;
+common::PortStatistics* get_default_port_statistics() {
+    common::PortStatistics* port_stats = new common::PortStatistics;
     port_stats->set_intf_id(-1);
     port_stats->set_rx_bytes(-1);
     port_stats->set_rx_packets(-1);
@@ -79,6 +80,30 @@
     port_stats->set_tx_frames_4096_9216(-1);
     port_stats->set_tx_frames_9217_16383(-1);
     port_stats->set_bip_errors(-1);
+    port_stats->set_bip_units(-1);
+    port_stats->set_rxgem(-1);
+    port_stats->set_rxgemdropped(-1);
+    port_stats->set_rxgemidle(-1);
+    port_stats->set_rxgemcorrected(-1);
+    port_stats->set_rxfragmenterror(-1);
+    port_stats->set_rxpacketsdropped(-1);
+    port_stats->set_rxcpuomcipacketsdropped(-1);
+    port_stats->set_rxcpu(-1);
+    port_stats->set_rxomci(-1);
+    port_stats->set_rxomcipacketscrcerror(-1);
+    port_stats->set_rxgemillegal(-1);
+    port_stats->set_txgem(-1);
+    port_stats->set_txcpu(-1);
+    port_stats->set_txomci(-1);
+    port_stats->set_txdroppedillegallength(-1);
+    port_stats->set_txdroppedtpidmiss(-1);
+    port_stats->set_txdroppedvidmiss(-1);
+    port_stats->set_txdroppedtotal(-1);
+    port_stats->set_rxfcserrorpackets(-1);
+    port_stats->set_rxundersizepackets(-1);
+    port_stats->set_rxoversizepackets(-1);
+    port_stats->set_txundersizepackets(-1);
+    port_stats->set_txoversizepackets(-1);
 
     return port_stats;
 }
@@ -126,6 +151,16 @@
     return gemport_stats;
 }
 
+openolt::OnuAllocIdStatistics get_default_alloc_statistics() {
+    openolt::OnuAllocIdStatistics alloc_stats;
+
+    alloc_stats.set_intfid(-1);
+    alloc_stats.set_allocid(-1);
+    alloc_stats.set_rxbytes(-1);
+
+    return alloc_stats;
+}
+
 #if 0
 openolt::FlowStatistics* get_default_flow_statistics() {
     openolt::FlowStatistics* flow_stats = new openolt::FlowStatistics;
@@ -139,9 +174,9 @@
 }
 #endif
 
-openolt::PortStatistics* collectPortStatistics(bcmolt_intf_ref intf_ref) {
+common::PortStatistics* collectPortStatistics(bcmolt_intf_ref intf_ref) {
 
-    openolt::PortStatistics* port_stats = get_default_port_statistics();
+    common::PortStatistics* port_stats = get_default_port_statistics();
 #ifndef TEST_MODE
     bcmos_errno err;
     bcmolt_stat_flags clear_on_read = BCMOLT_STAT_FLAGS_NONE;
@@ -334,6 +369,164 @@
 
 }
 
+bcmos_errno get_port_statistics(bcmolt_intf_ref intf_ref, common::PortStatistics* port_stats) {
+    bcmos_errno err = BCM_ERR_OK;
+    common::PortStatistics* port_stats_temp = get_default_port_statistics();
+    memcpy(port_stats, port_stats_temp, sizeof(common::PortStatistics));
+    delete port_stats_temp;
+    
+#ifndef TEST_MODE
+    bcmolt_stat_flags clear_on_read = BCMOLT_STAT_FLAGS_NONE;
+    bcmolt_nni_interface_stats nni_stats;
+    bcmolt_pon_interface_itu_pon_stats itu_pon_stats;
+
+    switch (intf_ref.intf_type) {
+        case BCMOLT_INTERFACE_TYPE_NNI:
+        {
+            bcmolt_nni_interface_key nni_intf_key;
+            nni_intf_key.id = intf_ref.intf_id;
+            /* init the API struct */
+            BCMOLT_STAT_INIT(&nni_stats, nni_interface, stats, nni_intf_key);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_bytes);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_ucast_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_mcast_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_bcast_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_error_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_fcs_error_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_undersize_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_oversize_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_64);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_65_127);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_128_255);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_256_511);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_512_1023);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_1024_1518);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_1519_2047);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_2048_4095);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_4096_9216);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, rx_frames_9217_16383);
+
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_bytes);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_ucast_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_mcast_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_bcast_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_error_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_undersize_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_oversize_packets);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_64);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_65_127);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_128_255);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_256_511);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_512_1023);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_1024_1518);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_1519_2047);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_2048_4095);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_4096_9216);
+            BCMOLT_MSG_FIELD_GET(&nni_stats, tx_frames_9217_16383);
+
+            /* call API */
+            err = bcmolt_stat_get((bcmolt_oltid)device_id, &nni_stats.hdr, clear_on_read);
+            if (err == BCM_ERR_OK)
+            {
+                port_stats->set_rx_bytes(nni_stats.data.rx_bytes);
+                port_stats->set_rx_packets(nni_stats.data.rx_packets);
+                port_stats->set_rx_ucast_packets(nni_stats.data.rx_ucast_packets);
+                port_stats->set_rx_mcast_packets(nni_stats.data.rx_mcast_packets);
+                port_stats->set_rx_bcast_packets(nni_stats.data.rx_bcast_packets);
+                port_stats->set_rx_error_packets(nni_stats.data.rx_error_packets);
+                port_stats->set_rxfcserrorpackets(nni_stats.data.rx_fcs_error_packets);
+                port_stats->set_rxundersizepackets(nni_stats.data.rx_undersize_packets);
+                port_stats->set_rxoversizepackets(nni_stats.data.rx_oversize_packets);
+                port_stats->set_tx_bytes(nni_stats.data.tx_bytes);
+                port_stats->set_tx_packets(nni_stats.data.tx_packets);
+                port_stats->set_tx_ucast_packets(nni_stats.data.tx_ucast_packets);
+                port_stats->set_tx_mcast_packets(nni_stats.data.tx_mcast_packets);
+                port_stats->set_tx_bcast_packets(nni_stats.data.tx_bcast_packets);
+                port_stats->set_tx_error_packets(nni_stats.data.tx_error_packets);
+                port_stats->set_txundersizepackets(nni_stats.data.tx_undersize_packets);
+                port_stats->set_txoversizepackets(nni_stats.data.tx_oversize_packets);
+
+            } else {
+                OPENOLT_LOG(ERROR, openolt_log_id,  "Failed to retrieve port statistics, intf_id %d, intf_type %d, err = %s\n",
+                    (int)intf_ref.intf_id, (int)intf_ref.intf_type, bcmos_strerror(err));
+                return err;
+            }
+            break;
+        }
+        case BCMOLT_INTERFACE_TYPE_PON:
+        {
+            bcmolt_pon_interface_key key;
+            key.pon_ni = (bcmolt_interface)intf_ref.intf_id;
+            BCMOLT_STAT_INIT(&itu_pon_stats, pon_interface, itu_pon_stats, key);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, bip_units);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, bip_errors);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_packets);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_gem);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_gem_dropped);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_gem_idle);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_gem_corrected);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_crc_error);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_fragment_error);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_packets_dropped);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_cpu_omci_packets_dropped);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_cpu);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_omci);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_omci_packets_crc_error);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_gem_illegal);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_packets);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_gem);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_cpu);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_omci);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_dropped_illegal_length);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_dropped_tpid_miss);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_dropped_vid_miss);
+            BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_dropped_total);
+            
+            /* call API */
+            err = bcmolt_stat_get((bcmolt_oltid)device_id, &itu_pon_stats.hdr, clear_on_read);
+            if (err == BCM_ERR_OK) {
+                port_stats->set_bip_units(itu_pon_stats.data.bip_units);
+                port_stats->set_bip_errors(itu_pon_stats.data.bip_errors);
+                port_stats->set_rx_packets(itu_pon_stats.data.rx_packets);
+                port_stats->set_rxgem(itu_pon_stats.data.rx_gem);
+                port_stats->set_rxgemdropped(itu_pon_stats.data.rx_gem_dropped);
+                port_stats->set_rxgemidle(itu_pon_stats.data.rx_gem_idle);
+                port_stats->set_rxgemcorrected(itu_pon_stats.data.rx_gem_corrected);
+                port_stats->set_rx_crc_errors(itu_pon_stats.data.rx_crc_error);
+                port_stats->set_rxfragmenterror(itu_pon_stats.data.rx_fragment_error);
+                port_stats->set_rxpacketsdropped(itu_pon_stats.data.rx_packets_dropped);
+                port_stats->set_rxcpuomcipacketsdropped(itu_pon_stats.data.rx_cpu_omci_packets_dropped);
+                port_stats->set_rxcpu(itu_pon_stats.data.rx_cpu);
+                port_stats->set_rxomci(itu_pon_stats.data.rx_omci);
+                port_stats->set_rxomcipacketscrcerror(itu_pon_stats.data.rx_omci_packets_crc_error);
+                port_stats->set_rxgemillegal(itu_pon_stats.data.rx_gem_illegal);
+                port_stats->set_tx_packets(itu_pon_stats.data.tx_packets);
+                port_stats->set_txgem(itu_pon_stats.data.tx_gem);
+                port_stats->set_txcpu(itu_pon_stats.data.tx_cpu);
+                port_stats->set_txomci(itu_pon_stats.data.tx_omci);
+                port_stats->set_txdroppedillegallength(itu_pon_stats.data.tx_dropped_illegal_length);
+                port_stats->set_txdroppedtpidmiss(itu_pon_stats.data.tx_dropped_tpid_miss);
+                port_stats->set_txdroppedvidmiss(itu_pon_stats.data.tx_dropped_vid_miss);
+                port_stats->set_txdroppedtotal(itu_pon_stats.data.tx_dropped_total);
+            } else {
+                OPENOLT_LOG(ERROR, openolt_log_id,  "Failed to retrieve port statistics, intf_id %d, intf_type %d, err = %s\n",
+                    (int)intf_ref.intf_id, (int)intf_ref.intf_type, bcmos_strerror(err));
+                return err;
+            }
+            break;
+        }
+    }
+
+    port_stats->set_intf_id(interface_key_to_port_no((bcmolt_interface_id)intf_ref.intf_id, (bcmolt_interface_type)intf_ref.intf_type));
+    time_t now;
+    time(&now);
+    port_stats->set_timestamp((int)now);
+#endif
+    return err;
+}
+
 bcmos_errno get_onu_statistics(bcmolt_interface_id intf_id, bcmolt_onu_id onu_id, openolt::OnuStatistics* onu_stats) {
     bcmos_errno err = BCM_ERR_OK;
 
@@ -457,6 +650,74 @@
     return err;
 }
 
+bcmos_errno set_collect_alloc_stats(bcmolt_interface_id intf_id, bcmolt_alloc_id alloc_id, bcmos_bool collect_stats) {
+    bcmos_errno err = BCM_ERR_OK;
+    bcmolt_itupon_alloc_cfg cfg;
+    bcmolt_itupon_alloc_key key;
+    key.pon_ni = intf_id;
+    key.alloc_id = alloc_id;
+
+    BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
+    BCMOLT_FIELD_SET(&cfg.data, itupon_alloc_cfg_data, collect_stats, collect_stats);
+    err = bcmolt_cfg_set((bcmolt_oltid)device_id, &cfg.hdr);
+    return err;
+}
+
+bcmos_errno get_alloc_statistics(bcmolt_interface_id intf_id, bcmolt_alloc_id alloc_id, openolt::OnuAllocIdStatistics* allocid_stats) {
+    bcmos_errno err = BCM_ERR_OK;
+
+#ifndef TEST_MODE
+
+    bcmos_errno err1 = BCM_ERR_OK;
+    err1 = set_collect_alloc_stats(intf_id, alloc_id, BCMOS_TRUE);
+    if (err1 == BCM_ERR_OK) {
+        *allocid_stats = get_default_alloc_statistics();
+        bcmolt_stat_flags clear_on_read = BCMOLT_STAT_FLAGS_NONE;
+        bcmolt_itupon_alloc_stats alloc_stats;
+        bcmolt_itupon_alloc_key key;
+        key.pon_ni = intf_id;
+        key.alloc_id = alloc_id;
+
+        // Wait to collect alloc stats after enabling it
+        sleep(ALLOC_STATS_GET_INTERVAL);
+
+        BCMOLT_STAT_INIT(&alloc_stats, itupon_alloc, stats, key);
+        BCMOLT_MSG_FIELD_GET(&alloc_stats, rx_bytes);
+
+        /* call API */
+        err = bcmolt_stat_get((bcmolt_oltid)device_id, &alloc_stats.hdr, clear_on_read);
+        if (err == BCM_ERR_OK) {
+            allocid_stats->set_rxbytes(alloc_stats.data.rx_bytes);
+            allocid_stats->set_intfid(intf_id);
+            allocid_stats->set_allocid(alloc_id);
+        } else {
+            OPENOLT_LOG(ERROR, openolt_log_id,  "Failed to retrieve ALLOC_ID statistics, intf_id %d, alloc_id %d, err no: %d - %s\n",
+                        (int)intf_id, (int)alloc_id, err, bcmos_strerror(err));
+            err1 = set_collect_alloc_stats(intf_id, alloc_id, BCMOS_FALSE);
+            if (err1 != BCM_ERR_OK) {
+            OPENOLT_LOG(ERROR, openolt_log_id,  "Failed to disable collect_stats for ALLOC_ID, intf_id %d, alloc_id %d, err no: %d - %s\n",
+                        (int)intf_id, (int)alloc_id, err, bcmos_strerror(err));
+            }
+            return err;
+        }
+    } else {
+        OPENOLT_LOG(ERROR, openolt_log_id,  "Failed to enable collect_stats for ALLOC_ID, intf_id %d, alloc_id %d, err no: %d - %s\n",
+                        (int)intf_id, (int)alloc_id, err, bcmos_strerror(err));
+        return err1;
+    }
+    
+    err1 = set_collect_alloc_stats(intf_id, alloc_id, BCMOS_FALSE);
+    if (err1 != BCM_ERR_OK) {
+        OPENOLT_LOG(ERROR, openolt_log_id,  "Failed to disable collect_stats for ALLOC_ID, intf_id %d, alloc_id %d, err no: %d - %s\n",
+                        (int)intf_id, (int)alloc_id, err, bcmos_strerror(err));
+        return err1;
+    }
+
+#endif
+
+    return err;
+}
+
 #if 0
 openolt::FlowStatistics* collectFlowStatistics(bcmbal_flow_id flow_id, bcmbal_flow_type flow_type) {
 
@@ -518,7 +779,7 @@
         intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_NNI;
         intf_ref.intf_id = i;
 
-        openolt::PortStatistics* port_stats =
+        common::PortStatistics* port_stats =
             collectPortStatistics(intf_ref);
 
         ::openolt::Indication ind;
@@ -531,7 +792,7 @@
         intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_PON;
         intf_ref.intf_id = i;
 
-        openolt::PortStatistics* port_stats =
+        common::PortStatistics* port_stats =
             collectPortStatistics(intf_ref);
 
         ::openolt::Indication ind;