blob: 2d535cfe250ef865985f4d1f433c198d197eafe8 [file] [log] [blame]
Zack Williams477ba092018-10-17 10:50:06 -07001/*
2 Copyright (C) 2018 Open Networking Foundation
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040018#include "stats_collection.h"
19
20#include <unistd.h>
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040021
22#include <openolt.grpc.pb.h>
23#include "indications.h"
Nicolas Palpacuerc09fdb72018-08-22 10:23:22 -040024#include "core.h"
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -040025#include "translation.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040026
27extern "C"
28{
29#include <bcmos_system.h>
Jason Huangd33b4d82019-05-15 18:22:57 +080030#include <bcmolt_api.h>
31#include <bcmolt_api_model_api_structs.h>
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040032}
33
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040034//FIXME
35#define FLOWS_COUNT 100
36
Jason Huangd33b4d82019-05-15 18:22:57 +080037bcmolt_flow_key* flows_keys = new bcmolt_flow_key[FLOWS_COUNT];
38bcmolt_odid device_id = 0;
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040039
Shad Ansariedef2132018-08-10 22:14:50 +000040void init_stats() {
Jason Huangd33b4d82019-05-15 18:22:57 +080041 memset(flows_keys, 0, FLOWS_COUNT * sizeof(bcmolt_flow_key));
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040042}
43
44openolt::PortStatistics* get_default_port_statistics() {
45 openolt::PortStatistics* port_stats = new openolt::PortStatistics;
46 port_stats->set_intf_id(-1);
47 port_stats->set_rx_bytes(-1);
48 port_stats->set_rx_packets(-1);
49 port_stats->set_rx_ucast_packets(-1);
50 port_stats->set_rx_mcast_packets(-1);
51 port_stats->set_rx_bcast_packets(-1);
52 port_stats->set_rx_error_packets(-1);
53 port_stats->set_tx_bytes(-1);
54 port_stats->set_tx_packets(-1);
55 port_stats->set_tx_ucast_packets(-1);
56 port_stats->set_tx_mcast_packets(-1);
57 port_stats->set_tx_bcast_packets(-1);
58 port_stats->set_tx_error_packets(-1);
59 port_stats->set_rx_crc_errors(-1);
60 port_stats->set_bip_errors(-1);
61
62 return port_stats;
63}
64
Shad Ansaricb004c52018-05-30 18:07:23 +000065#if 0
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040066openolt::FlowStatistics* get_default_flow_statistics() {
67 openolt::FlowStatistics* flow_stats = new openolt::FlowStatistics;
68 flow_stats->set_flow_id(-1);
69 flow_stats->set_rx_bytes(-1);
70 flow_stats->set_rx_packets(-1);
71 flow_stats->set_tx_bytes(-1);
72 flow_stats->set_tx_packets(-1);
73
74 return flow_stats;
75}
Shad Ansaricb004c52018-05-30 18:07:23 +000076#endif
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040077
Jason Huangd33b4d82019-05-15 18:22:57 +080078openolt::PortStatistics* collectPortStatistics(bcmolt_intf_ref intf_ref) {
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040079
Girish Gowdrae538dfd2019-09-30 11:07:30 +053080 openolt::PortStatistics* port_stats = get_default_port_statistics();
81#ifndef TEST_MODE
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040082 bcmos_errno err;
Jason Huangd33b4d82019-05-15 18:22:57 +080083 bcmolt_stat_flags clear_on_read = BCMOLT_STAT_FLAGS_NONE;
84 bcmolt_nni_interface_stats nni_stats;
85 bcmolt_onu_itu_pon_stats pon_stats;
86 bcmolt_pon_interface_itu_pon_stats itu_pon_stats;
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040087
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040088
Jason Huangd33b4d82019-05-15 18:22:57 +080089 switch (intf_ref.intf_type) {
90 case BCMOLT_INTERFACE_TYPE_NNI:
91 {
92 bcmolt_nni_interface_key nni_intf_key;
93 nni_intf_key.id = intf_ref.intf_id;
94 /* init the API struct */
95 BCMOLT_STAT_INIT(&nni_stats, nni_interface, stats, nni_intf_key);
96 BCMOLT_MSG_FIELD_GET(&nni_stats, rx_bytes);
97 BCMOLT_MSG_FIELD_GET(&nni_stats, rx_packets);
98 BCMOLT_MSG_FIELD_GET(&nni_stats, rx_ucast_packets);
99 BCMOLT_MSG_FIELD_GET(&nni_stats, rx_mcast_packets);
100 BCMOLT_MSG_FIELD_GET(&nni_stats, rx_bcast_packets);
101 BCMOLT_MSG_FIELD_GET(&nni_stats, rx_error_packets);
102 BCMOLT_MSG_FIELD_GET(&nni_stats, tx_bytes);
103 BCMOLT_MSG_FIELD_GET(&nni_stats, tx_packets);
104 BCMOLT_MSG_FIELD_GET(&nni_stats, tx_ucast_packets);
105 BCMOLT_MSG_FIELD_GET(&nni_stats, tx_mcast_packets);
106 BCMOLT_MSG_FIELD_GET(&nni_stats, tx_bcast_packets);
107 BCMOLT_MSG_FIELD_GET(&nni_stats, tx_error_packets);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400108
Jason Huangd33b4d82019-05-15 18:22:57 +0800109 /* call API */
110 err = bcmolt_stat_get((bcmolt_oltid)device_id, &nni_stats.hdr, clear_on_read);
111 if (err == BCM_ERR_OK)
112 {
113 //std::cout << "Interface statistics retrieved"
114 // << " intf_id:" << intf_id << std::endl;
115
116 port_stats->set_rx_bytes(nni_stats.data.rx_bytes);
117 port_stats->set_rx_packets(nni_stats.data.rx_packets);
118 port_stats->set_rx_ucast_packets(nni_stats.data.rx_ucast_packets);
119 port_stats->set_rx_mcast_packets(nni_stats.data.rx_mcast_packets);
120 port_stats->set_rx_bcast_packets(nni_stats.data.rx_bcast_packets);
121 port_stats->set_rx_error_packets(nni_stats.data.rx_error_packets);
122 port_stats->set_tx_bytes(nni_stats.data.tx_bytes);
123 port_stats->set_tx_packets(nni_stats.data.tx_packets);
124 port_stats->set_tx_ucast_packets(nni_stats.data.tx_ucast_packets);
125 port_stats->set_tx_mcast_packets(nni_stats.data.tx_mcast_packets);
126 port_stats->set_tx_bcast_packets(nni_stats.data.tx_bcast_packets);
127 port_stats->set_tx_error_packets(nni_stats.data.tx_error_packets);
128
129 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +0800130 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to retrieve port statistics, intf_id %d, intf_type %d\n",
Jason Huangd33b4d82019-05-15 18:22:57 +0800131 (int)intf_ref.intf_id, (int)intf_ref.intf_type);
132 }
133 break;
134 }
135 case BCMOLT_INTERFACE_TYPE_PON:
136 {
Jason Huangb6843dc2019-07-22 17:46:06 +0800137 bcmolt_pon_interface_key key;
Jason Huangd33b4d82019-05-15 18:22:57 +0800138 key.pon_ni = (bcmolt_interface)intf_ref.intf_id;
139 BCMOLT_STAT_INIT(&itu_pon_stats, pon_interface, itu_pon_stats, key);
140 BCMOLT_MSG_FIELD_GET(&itu_pon_stats, tx_packets);
141 BCMOLT_MSG_FIELD_GET(&itu_pon_stats, bip_errors);
142 BCMOLT_MSG_FIELD_GET(&itu_pon_stats, rx_crc_error);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400143
Jason Huangd33b4d82019-05-15 18:22:57 +0800144 /* call API */
145 err = bcmolt_stat_get((bcmolt_oltid)device_id, &itu_pon_stats.hdr, clear_on_read);
146 if (err == BCM_ERR_OK) {
147 port_stats->set_tx_packets(itu_pon_stats.data.tx_packets);
148 port_stats->set_bip_errors(itu_pon_stats.data.bip_errors);
149 port_stats->set_rx_crc_errors(itu_pon_stats.data.rx_crc_error);
150 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +0800151 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to retrieve port statistics, intf_id %d, intf_type %d, err %d\n",
152 (int)intf_ref.intf_id, (int)intf_ref.intf_type, err);
Jason Huangd33b4d82019-05-15 18:22:57 +0800153 }
154 {
155 bcmolt_onu_key key;
156 key.pon_ni = (bcmolt_interface)intf_ref.intf_id;
Jason Huangb1fad572019-05-28 19:02:30 +0800157 BCMOLT_STAT_INIT(&pon_stats, onu, itu_pon_stats, key);
Jason Huangd33b4d82019-05-15 18:22:57 +0800158 BCMOLT_MSG_FIELD_GET(&pon_stats, rx_bytes);
159 BCMOLT_MSG_FIELD_GET(&pon_stats, rx_packets);
160 BCMOLT_MSG_FIELD_GET(&pon_stats, tx_bytes);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400161
Jason Huangd33b4d82019-05-15 18:22:57 +0800162 /* call API */
163 err = bcmolt_stat_get((bcmolt_oltid)device_id, &pon_stats.hdr, clear_on_read);
164 if (err == BCM_ERR_OK) {
165 port_stats->set_rx_bytes(pon_stats.data.rx_bytes);
166 port_stats->set_rx_packets(pon_stats.data.rx_packets);
167 port_stats->set_tx_bytes(pon_stats.data.tx_bytes);
168 } else {
Jason Huangb6843dc2019-07-22 17:46:06 +0800169 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to retrieve port statistics, intf_id %d, intf_type %d, err %d\n",
170 (int)intf_ref.intf_id, (int)intf_ref.intf_type, err);
Jason Huangd33b4d82019-05-15 18:22:57 +0800171 }
172 }
173 break;
174 }
175 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400176
Jason Huangd33b4d82019-05-15 18:22:57 +0800177 port_stats->set_intf_id(interface_key_to_port_no((bcmolt_interface_id)intf_ref.intf_id, (bcmolt_interface_type)intf_ref.intf_type));
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400178 time_t now;
179 time(&now);
180 port_stats->set_timestamp((int)now);
Girish Gowdrae538dfd2019-09-30 11:07:30 +0530181#endif
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400182 return port_stats;
183
184}
185
Shad Ansaricb004c52018-05-30 18:07:23 +0000186#if 0
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400187openolt::FlowStatistics* collectFlowStatistics(bcmbal_flow_id flow_id, bcmbal_flow_type flow_type) {
188
189 bcmos_errno err;
190 bcmbal_flow_stat stat; /**< declare main API struct */
191 bcmbal_flow_key key = { }; /**< declare key */
192 bcmos_bool clear_on_read = false;
193
194 openolt::FlowStatistics* flow_stats = get_default_flow_statistics();
195 //Key
196 key.flow_id = flow_id;
197 key.flow_type = flow_type;
198
199 /* init the API struct */
200 BCMBAL_STAT_INIT(&stat, flow, key);
201 BCMBAL_STAT_PROP_GET(&stat, flow, all_properties);
202
203 err = bcmbal_stat_get(DEFAULT_ATERM_ID, &stat.hdr, clear_on_read);
204
205 if (err == BCM_ERR_OK)
206 {
207 std::cout << "Flow statistics retrieved"
208 << " flow_id:" << flow_id
209 << " flow_type:" << flow_type << std::endl;
210
211 flow_stats->set_rx_bytes(stat.data.rx_bytes);
212 flow_stats->set_rx_packets(stat.data.rx_packets);
213 flow_stats->set_tx_bytes(stat.data.tx_bytes);
214 flow_stats->set_tx_packets(stat.data.tx_packets);
215
216 } else {
217 std::cout << "ERROR: Failed to retrieve flow statistics"
218 << " flow_id:" << flow_id
219 << " flow_type:" << flow_type << std::endl;
220 }
221
222 return flow_stats;
223}
Shad Ansaricb004c52018-05-30 18:07:23 +0000224#endif
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400225
226
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400227void stats_collection() {
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400228
Nicolas Palpacuerc09fdb72018-08-22 10:23:22 -0400229 if (!state.is_connected()) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800230 OPENOLT_LOG(INFO, openolt_log_id, "Voltha is not connected, do not collect stats\n");
Nicolas Palpacuerc09fdb72018-08-22 10:23:22 -0400231 return;
232 }
233 if (!state.is_activated()) {
Jason Huangb6843dc2019-07-22 17:46:06 +0800234 OPENOLT_LOG(INFO, openolt_log_id, "The OLT is not up, do not collect stats\n");
Nicolas Palpacuerc09fdb72018-08-22 10:23:22 -0400235 return;
236 }
237
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400238
Jason Huangb6843dc2019-07-22 17:46:06 +0800239 OPENOLT_LOG(DEBUG, openolt_log_id, "Collecting statistics\n");
Nicolas Palpacuer3cad49d2018-07-02 14:03:24 -0400240
Shad Ansariedef2132018-08-10 22:14:50 +0000241 //Ports statistics
Nicolas Palpacuer3cad49d2018-07-02 14:03:24 -0400242
Shad Ansariedef2132018-08-10 22:14:50 +0000243 //Uplink ports
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500244 for (int i = 0; i < NumNniIf_(); i++) {
Jason Huangd33b4d82019-05-15 18:22:57 +0800245 bcmolt_intf_ref intf_ref;
246 intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_NNI;
247 intf_ref.intf_id = i;
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400248
Jason Huangd33b4d82019-05-15 18:22:57 +0800249 openolt::PortStatistics* port_stats =
250 collectPortStatistics(intf_ref);
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400251
Shad Ansariedef2132018-08-10 22:14:50 +0000252 openolt::Indication ind;
253 ind.set_allocated_port_stats(port_stats);
254 oltIndQ.push(ind);
255 }
256 //Pon ports
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500257 for (int i = 0; i < NumPonIf_(); i++) {
Jason Huangd33b4d82019-05-15 18:22:57 +0800258 bcmolt_intf_ref intf_ref;
259 intf_ref.intf_type = BCMOLT_INTERFACE_TYPE_PON;
260 intf_ref.intf_id = i;
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400261
Jason Huangd33b4d82019-05-15 18:22:57 +0800262 openolt::PortStatistics* port_stats =
263 collectPortStatistics(intf_ref);
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400264
Shad Ansariedef2132018-08-10 22:14:50 +0000265 openolt::Indication ind;
266 ind.set_allocated_port_stats(port_stats);
267 oltIndQ.push(ind);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400268 }
269
Shad Ansariedef2132018-08-10 22:14:50 +0000270 //Flows statistics
271 // flow_inst *current_entry = NULL;
272 //
273 // TAILQ_FOREACH(current_entry,
274 // &FLOW_FSM_FLOW_LIST_CTX_PTR->active_flow_list,
275 // flow_inst_next) {
276 // int flows_measurements = 0;
277 //
278 // for (int i = 0; i < FLOWS_COUNT; i++) {
279 //
280 // // bcmbal_flow_id flow_id = current_entry->api_req_flow_info.key.flow_id;
281 // // bcmbal_flow_type flow_type = current_entry->api_req_flow_info.key.flow_type;
282 //
283 // if (flows_keys[i].flow_id != 0) {
284 // openolt::FlowStatistics* flow_stats = collectFlowStatistics(flows_keys[i].flow_id, flows_keys[i].flow_type);
285 // if (flow_stats->rx_packets() == -1) {
286 // //It Failed
287 // flows_keys[i].flow_id = 0;
288 // } else {
289 // flow_stats->set_flow_id(flows_keys[i].flow_id);
290 // time(&now);
291 // flow_stats->set_timestamp((int)now);
292 // openolt::Indication ind;
293 // ind.set_allocated_flow_stats(flow_stats);
294 // oltIndQ.push(ind);
295 // flows_measurements ++;
296 // }
297 // }
298 //
299 // }
300 // std::cout << "Stats of " << flows_measurements << " flows retrieved" << std::endl;
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400301
302}
303
304/* Storing flow keys, temporary */
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400305// void register_new_flow(bcmbal_flow_key key) {
306// for (int i = 0; i < FLOWS_COUNT; i++) {
307// if (flows_keys[i].flow_id == 0) {
308// flows_keys[i] = key;
309// break;
310// }
311// }
312// }