| #include "stats_collection.h" |
| |
| #include <unistd.h> |
| #include <pthread.h> |
| |
| #include <openolt.grpc.pb.h> |
| #include "indications.h" |
| |
| extern "C" |
| { |
| #include <bcmos_system.h> |
| #include <bal_api.h> |
| #include <bal_api_end.h> |
| #include <flow_fsm.h> |
| } |
| |
| #define COLLECTION_PERIOD 15 |
| //FIXME |
| #define FLOWS_COUNT 100 |
| |
| bool isCollectingStatistics; |
| bcmbal_flow_key* flows_keys = new bcmbal_flow_key[FLOWS_COUNT]; |
| bool init_done = false; |
| |
| |
| void start_collecting_statistics() { |
| if (!init_done) { |
| memset(flows_keys, 0, FLOWS_COUNT * sizeof(bcmbal_flow_key)); |
| init_done = true; |
| } |
| pthread_t statisticsCollectionThread; |
| isCollectingStatistics = true; |
| pthread_create(&statisticsCollectionThread, NULL, stats_collection, NULL); |
| |
| std::cout << "Statistics collection thread started" << std::endl; |
| } |
| |
| void stop_collecting_statistics() { |
| isCollectingStatistics = false; |
| } |
| |
| openolt::PortStatistics* get_default_port_statistics() { |
| openolt::PortStatistics* port_stats = new openolt::PortStatistics; |
| port_stats->set_intf_id(-1); |
| port_stats->set_rx_bytes(-1); |
| port_stats->set_rx_packets(-1); |
| port_stats->set_rx_ucast_packets(-1); |
| port_stats->set_rx_mcast_packets(-1); |
| port_stats->set_rx_bcast_packets(-1); |
| port_stats->set_rx_error_packets(-1); |
| port_stats->set_tx_bytes(-1); |
| port_stats->set_tx_packets(-1); |
| port_stats->set_tx_ucast_packets(-1); |
| port_stats->set_tx_mcast_packets(-1); |
| port_stats->set_tx_bcast_packets(-1); |
| port_stats->set_tx_error_packets(-1); |
| port_stats->set_rx_crc_errors(-1); |
| port_stats->set_bip_errors(-1); |
| |
| return port_stats; |
| } |
| |
| #if 0 |
| openolt::FlowStatistics* get_default_flow_statistics() { |
| openolt::FlowStatistics* flow_stats = new openolt::FlowStatistics; |
| flow_stats->set_flow_id(-1); |
| flow_stats->set_rx_bytes(-1); |
| flow_stats->set_rx_packets(-1); |
| flow_stats->set_tx_bytes(-1); |
| flow_stats->set_tx_packets(-1); |
| |
| return flow_stats; |
| } |
| #endif |
| |
| openolt::PortStatistics* collectPortStatistics(int intf_id, bcmbal_intf_type intf_type) { |
| |
| bcmos_errno err; |
| bcmbal_interface_stat stat; /**< declare main API struct */ |
| bcmbal_interface_key key = { }; /**< declare key */ |
| bcmos_bool clear_on_read = false; |
| |
| openolt::PortStatistics* port_stats = get_default_port_statistics(); |
| // build key |
| key.intf_id = (bcmbal_intf_id) intf_id; |
| key.intf_type = intf_type; |
| |
| /* init the API struct */ |
| BCMBAL_STAT_INIT(&stat, interface, key); |
| BCMBAL_STAT_PROP_GET(&stat, interface, all_properties); |
| |
| /* call API */ |
| err = bcmbal_stat_get(DEFAULT_ATERM_ID, &stat.hdr, clear_on_read); |
| if (err == BCM_ERR_OK) |
| { |
| //std::cout << "Interface statistics retrieved" |
| // << " intf_id:" << intf_id << std::endl; |
| |
| port_stats->set_rx_bytes(stat.data.rx_bytes); |
| port_stats->set_rx_packets(stat.data.rx_packets); |
| port_stats->set_rx_ucast_packets(stat.data.rx_ucast_packets); |
| port_stats->set_rx_mcast_packets(stat.data.rx_mcast_packets); |
| port_stats->set_rx_bcast_packets(stat.data.rx_bcast_packets); |
| port_stats->set_rx_error_packets(stat.data.rx_error_packets); |
| port_stats->set_tx_bytes(stat.data.tx_bytes); |
| port_stats->set_tx_packets(stat.data.tx_packets); |
| port_stats->set_tx_ucast_packets(stat.data.tx_ucast_packets); |
| port_stats->set_tx_mcast_packets(stat.data.tx_mcast_packets); |
| port_stats->set_tx_bcast_packets(stat.data.tx_bcast_packets); |
| port_stats->set_tx_error_packets(stat.data.tx_error_packets); |
| port_stats->set_rx_crc_errors(stat.data.rx_crc_errors); |
| port_stats->set_bip_errors(stat.data.bip_errors); |
| |
| } else { |
| std::cout << "ERROR: Failed to retrieve port statistics" |
| << " intf_id:" << intf_id |
| << " intf_type:" << intf_type << std::endl; |
| } |
| |
| return port_stats; |
| |
| } |
| |
| #if 0 |
| openolt::FlowStatistics* collectFlowStatistics(bcmbal_flow_id flow_id, bcmbal_flow_type flow_type) { |
| |
| bcmos_errno err; |
| bcmbal_flow_stat stat; /**< declare main API struct */ |
| bcmbal_flow_key key = { }; /**< declare key */ |
| bcmos_bool clear_on_read = false; |
| |
| openolt::FlowStatistics* flow_stats = get_default_flow_statistics(); |
| //Key |
| key.flow_id = flow_id; |
| key.flow_type = flow_type; |
| |
| /* init the API struct */ |
| BCMBAL_STAT_INIT(&stat, flow, key); |
| BCMBAL_STAT_PROP_GET(&stat, flow, all_properties); |
| |
| err = bcmbal_stat_get(DEFAULT_ATERM_ID, &stat.hdr, clear_on_read); |
| |
| if (err == BCM_ERR_OK) |
| { |
| std::cout << "Flow statistics retrieved" |
| << " flow_id:" << flow_id |
| << " flow_type:" << flow_type << std::endl; |
| |
| flow_stats->set_rx_bytes(stat.data.rx_bytes); |
| flow_stats->set_rx_packets(stat.data.rx_packets); |
| flow_stats->set_tx_bytes(stat.data.tx_bytes); |
| flow_stats->set_tx_packets(stat.data.tx_packets); |
| |
| } else { |
| std::cout << "ERROR: Failed to retrieve flow statistics" |
| << " flow_id:" << flow_id |
| << " flow_type:" << flow_type << std::endl; |
| } |
| |
| return flow_stats; |
| } |
| #endif |
| |
| |
| void* stats_collection(void* x) { |
| |
| time_t now; |
| |
| while(isCollectingStatistics) { |
| |
| std::cout << "Collecting statistics" << std::endl; |
| |
| //Ports statistics |
| |
| //Uplink ports |
| for (int i = 0; i < 4; i++) { |
| openolt::PortStatistics* port_stats = collectPortStatistics(i, BCMBAL_INTF_TYPE_NNI); |
| //FIXME Use clean port translation |
| port_stats->set_intf_id(128 + i); |
| time(&now); |
| port_stats->set_timestamp((int)now); |
| openolt::Indication ind; |
| ind.set_allocated_port_stats(port_stats); |
| oltIndQ.push(ind); |
| } |
| //Pon ports |
| for (int i = 0; i < 16; i++) { |
| openolt::PortStatistics* port_stats = collectPortStatistics(i, BCMBAL_INTF_TYPE_PON); |
| //FIXME Use clean port translation |
| port_stats->set_intf_id((0x2 << 28) + i); |
| time(&now); |
| port_stats->set_timestamp((int)now); |
| openolt::Indication ind; |
| ind.set_allocated_port_stats(port_stats); |
| oltIndQ.push(ind); |
| } |
| |
| //Flows statistics |
| // flow_inst *current_entry = NULL; |
| // |
| // TAILQ_FOREACH(current_entry, |
| // &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list, |
| // flow_inst_next) { |
| // int flows_measurements = 0; |
| // |
| // for (int i = 0; i < FLOWS_COUNT; i++) { |
| // |
| // // bcmbal_flow_id flow_id = current_entry->api_req_flow_info.key.flow_id; |
| // // bcmbal_flow_type flow_type = current_entry->api_req_flow_info.key.flow_type; |
| // |
| // if (flows_keys[i].flow_id != 0) { |
| // openolt::FlowStatistics* flow_stats = collectFlowStatistics(flows_keys[i].flow_id, flows_keys[i].flow_type); |
| // if (flow_stats->rx_packets() == -1) { |
| // //It Failed |
| // flows_keys[i].flow_id = 0; |
| // } else { |
| // flow_stats->set_flow_id(flows_keys[i].flow_id); |
| // time(&now); |
| // flow_stats->set_timestamp((int)now); |
| // openolt::Indication ind; |
| // ind.set_allocated_flow_stats(flow_stats); |
| // oltIndQ.push(ind); |
| // flows_measurements ++; |
| // } |
| // } |
| // |
| // } |
| // std::cout << "Stats of " << flows_measurements << " flows retrieved" << std::endl; |
| |
| sleep(COLLECTION_PERIOD); |
| |
| } |
| |
| std::cout << "Statistics collection thread terminated" << std::endl; |
| |
| |
| } |
| |
| /* Storing flow keys, temporary */ |
| void register_new_flow(bcmbal_flow_key key) { |
| for (int i = 0; i < FLOWS_COUNT; i++) { |
| if (flows_keys[i].flow_id == 0) { |
| flows_keys[i] = key; |
| break; |
| } |
| } |
| } |