blob: de11c72440a410686d90f849c67e62e9d02de982 [file] [log] [blame]
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001#include "stats_collection.h"
2
3#include <unistd.h>
4#include <pthread.h>
5
6#include <openolt.grpc.pb.h>
7#include "indications.h"
8
9extern "C"
10{
11#include <bcmos_system.h>
12#include <bal_api.h>
13#include <bal_api_end.h>
14#include <flow_fsm.h>
15}
16
17#define COLLECTION_PERIOD 15
18//FIXME
19#define FLOWS_COUNT 100
20
21bool isCollectingStatistics;
22bcmbal_flow_key* flows_keys = new bcmbal_flow_key[FLOWS_COUNT];
23bool init_done = false;
24
25
26void start_collecting_statistics() {
27 if (!init_done) {
28 memset(flows_keys, 0, FLOWS_COUNT * sizeof(bcmbal_flow_key));
29 init_done = true;
30 }
31 pthread_t statisticsCollectionThread;
32 isCollectingStatistics = true;
33 pthread_create(&statisticsCollectionThread, NULL, stats_collection, NULL);
34
35 std::cout << "Statistics collection thread started" << std::endl;
36}
37
38void stop_collecting_statistics() {
39 isCollectingStatistics = false;
40}
41
42openolt::PortStatistics* get_default_port_statistics() {
43 openolt::PortStatistics* port_stats = new openolt::PortStatistics;
44 port_stats->set_intf_id(-1);
45 port_stats->set_rx_bytes(-1);
46 port_stats->set_rx_packets(-1);
47 port_stats->set_rx_ucast_packets(-1);
48 port_stats->set_rx_mcast_packets(-1);
49 port_stats->set_rx_bcast_packets(-1);
50 port_stats->set_rx_error_packets(-1);
51 port_stats->set_tx_bytes(-1);
52 port_stats->set_tx_packets(-1);
53 port_stats->set_tx_ucast_packets(-1);
54 port_stats->set_tx_mcast_packets(-1);
55 port_stats->set_tx_bcast_packets(-1);
56 port_stats->set_tx_error_packets(-1);
57 port_stats->set_rx_crc_errors(-1);
58 port_stats->set_bip_errors(-1);
59
60 return port_stats;
61}
62
63openolt::FlowStatistics* get_default_flow_statistics() {
64 openolt::FlowStatistics* flow_stats = new openolt::FlowStatistics;
65 flow_stats->set_flow_id(-1);
66 flow_stats->set_rx_bytes(-1);
67 flow_stats->set_rx_packets(-1);
68 flow_stats->set_tx_bytes(-1);
69 flow_stats->set_tx_packets(-1);
70
71 return flow_stats;
72}
73
74openolt::PortStatistics* collectPortStatistics(int intf_id, bcmbal_intf_type intf_type) {
75
76 bcmos_errno err;
77 bcmbal_interface_stat stat; /**< declare main API struct */
78 bcmbal_interface_key key = { }; /**< declare key */
79 bcmos_bool clear_on_read = false;
80
81 openolt::PortStatistics* port_stats = get_default_port_statistics();
82 // build key
83 key.intf_id = (bcmbal_intf_id) intf_id;
84 key.intf_type = intf_type;
85
86 /* init the API struct */
87 BCMBAL_STAT_INIT(&stat, interface, key);
88 BCMBAL_STAT_PROP_GET(&stat, interface, all_properties);
89
90 /* call API */
91 err = bcmbal_stat_get(DEFAULT_ATERM_ID, &stat.hdr, clear_on_read);
92 if (err == BCM_ERR_OK)
93 {
94 std::cout << "Interface statistics retrieved"
95 << " intf_id:" << intf_id << std::endl;
96
97 port_stats->set_rx_bytes(stat.data.rx_bytes);
98 port_stats->set_rx_packets(stat.data.rx_packets);
99 port_stats->set_rx_ucast_packets(stat.data.rx_ucast_packets);
100 port_stats->set_rx_mcast_packets(stat.data.rx_mcast_packets);
101 port_stats->set_rx_bcast_packets(stat.data.rx_bcast_packets);
102 port_stats->set_rx_error_packets(stat.data.rx_error_packets);
103 port_stats->set_tx_bytes(stat.data.tx_bytes);
104 port_stats->set_tx_packets(stat.data.tx_packets);
105 port_stats->set_tx_ucast_packets(stat.data.tx_ucast_packets);
106 port_stats->set_tx_mcast_packets(stat.data.tx_mcast_packets);
107 port_stats->set_tx_bcast_packets(stat.data.tx_bcast_packets);
108 port_stats->set_tx_error_packets(stat.data.tx_error_packets);
109 port_stats->set_rx_crc_errors(stat.data.rx_crc_errors);
110 port_stats->set_bip_errors(stat.data.bip_errors);
111
112 } else {
113 std::cout << "ERROR: Failed to retrieve port statistics"
114 << " intf_id:" << intf_id
115 << " intf_type:" << intf_type << std::endl;
116 }
117
118 return port_stats;
119
120}
121
122openolt::FlowStatistics* collectFlowStatistics(bcmbal_flow_id flow_id, bcmbal_flow_type flow_type) {
123
124 bcmos_errno err;
125 bcmbal_flow_stat stat; /**< declare main API struct */
126 bcmbal_flow_key key = { }; /**< declare key */
127 bcmos_bool clear_on_read = false;
128
129 openolt::FlowStatistics* flow_stats = get_default_flow_statistics();
130 //Key
131 key.flow_id = flow_id;
132 key.flow_type = flow_type;
133
134 /* init the API struct */
135 BCMBAL_STAT_INIT(&stat, flow, key);
136 BCMBAL_STAT_PROP_GET(&stat, flow, all_properties);
137
138 err = bcmbal_stat_get(DEFAULT_ATERM_ID, &stat.hdr, clear_on_read);
139
140 if (err == BCM_ERR_OK)
141 {
142 std::cout << "Flow statistics retrieved"
143 << " flow_id:" << flow_id
144 << " flow_type:" << flow_type << std::endl;
145
146 flow_stats->set_rx_bytes(stat.data.rx_bytes);
147 flow_stats->set_rx_packets(stat.data.rx_packets);
148 flow_stats->set_tx_bytes(stat.data.tx_bytes);
149 flow_stats->set_tx_packets(stat.data.tx_packets);
150
151 } else {
152 std::cout << "ERROR: Failed to retrieve flow statistics"
153 << " flow_id:" << flow_id
154 << " flow_type:" << flow_type << std::endl;
155 }
156
157 return flow_stats;
158}
159
160
161void* stats_collection(void* x) {
162
163 time_t now;
164
165 while(isCollectingStatistics) {
166 //Ports statistics
167
168 //Uplink ports
169 for (int i = 0; i < 4; i++) {
170 openolt::PortStatistics* port_stats = collectPortStatistics(i, BCMBAL_INTF_TYPE_NNI);
171 //FIXME Use clean port translation
172 port_stats->set_intf_id(128 + i);
173 time(&now);
174 port_stats->set_timestamp((int)now);
175 openolt::Indication ind;
176 ind.set_allocated_port_stats(port_stats);
177 oltIndQ.push(ind);
178 }
179 //Pon ports
180 for (int i = 0; i < 16; i++) {
181 openolt::PortStatistics* port_stats = collectPortStatistics(i, BCMBAL_INTF_TYPE_PON);
182 //FIXME Use clean port translation
183 port_stats->set_intf_id((0x2 << 28) + i);
184 time(&now);
185 port_stats->set_timestamp((int)now);
186 openolt::Indication ind;
187 ind.set_allocated_port_stats(port_stats);
188 oltIndQ.push(ind);
189 }
190
191 //Flows statistics
192 // flow_inst *current_entry = NULL;
193 //
194 // TAILQ_FOREACH(current_entry,
195 // &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
196 // flow_inst_next) {
197 // int flows_measurements = 0;
198 //
199 // for (int i = 0; i < FLOWS_COUNT; i++) {
200 //
201 // // bcmbal_flow_id flow_id = current_entry->api_req_flow_info.key.flow_id;
202 // // bcmbal_flow_type flow_type = current_entry->api_req_flow_info.key.flow_type;
203 //
204 // if (flows_keys[i].flow_id != 0) {
205 // openolt::FlowStatistics* flow_stats = collectFlowStatistics(flows_keys[i].flow_id, flows_keys[i].flow_type);
206 // if (flow_stats->rx_packets() == -1) {
207 // //It Failed
208 // flows_keys[i].flow_id = 0;
209 // } else {
210 // flow_stats->set_flow_id(flows_keys[i].flow_id);
211 // time(&now);
212 // flow_stats->set_timestamp((int)now);
213 // openolt::Indication ind;
214 // ind.set_allocated_flow_stats(flow_stats);
215 // oltIndQ.push(ind);
216 // flows_measurements ++;
217 // }
218 // }
219 //
220 // }
221 // std::cout << "Stats of " << flows_measurements << " flows retrieved" << std::endl;
222
223 sleep(COLLECTION_PERIOD);
224
225 }
226
227 std::cout << "Statistics collection thread terminated" << std::endl;
228
229
230}
231
232/* Storing flow keys, temporary */
233void register_new_flow(bcmbal_flow_key key) {
234 for (int i = 0; i < FLOWS_COUNT; i++) {
235 if (flows_keys[i].flow_id == 0) {
236 flows_keys[i] = key;
237 break;
238 }
239 }
240}