21 #include <sys/types.h> 25 #include <boost/filesystem.hpp> 26 #include <boost/filesystem/fstream.hpp> 27 #include <boost/property_tree/json_parser.hpp> 28 #include <boost/algorithm/string.hpp> 36 : fd_(-1), begin_(NULL), end_(NULL), next_(NULL), buffer_(NULL)
40 throw std::exception();
55 fd_ =
::open(fname.c_str(), O_RDONLY);
59 if (fstat(fd_, &stat_) < 0) {
60 close (fd_); fd_ = -1;
64 begin_ = (std::uint8_t *) mmap(0, stat_.st_size, PROT_READ, MAP_SHARED, fd_, 0);
65 if (begin_ == MAP_FAILED) {
67 size_t bsize (stat_.st_size > 0 ? stat_.st_size : 32768);
68 buffer_ =
new std::uint8_t[bsize];
69 if ((bsize = ::read(fd_, buffer_, bsize)) <= 0) {
70 close (fd_); fd_ = -1;
71 delete buffer_; buffer_ = NULL;
75 end_ = begin_ + bsize;
77 end_ = begin_ + stat_.st_size;
106 return off_t(end_ - begin_);
130 invalidEntries_(0), ioErrors_(0)
132 debugFsPath_ = debugFS +
"/wifi_statistics/" + ifName +
"/";
143 std::string file (debugFsPath_ +
"active");
145 if ((fd = open( file.c_str(), O_WRONLY)) != -1) {
146 senf::IGNORE(write( fd, on ?
"1" :
"0", 1));
156 if (timestamp_ and (tag_ == tag))
163 boost::property_tree::ptree pt;
164 boost::property_tree::read_json(debugFsPath_ +
"stats", pt);
166 for (
auto const & v : pt) {
169 for (
auto const & it : v.second) {
170 if (it.first ==
"signal") {
172 std::uint32_t
count(0);
173 std::uint64_t
sum2 (0);
174 for (
auto const & s : it.second) {
175 if (s.first ==
"sum")
176 sum = std::stoi(s.second.data());
177 if (s.first ==
"sum2")
178 sum2 = std::stoull(s.second.data());
179 if (s.first ==
"min")
180 min = std::stoi(s.second.data());
181 if (s.first ==
"max")
182 max = std::stoi(s.second.data());
183 if (s.first ==
"count")
184 count = std::stoul(s.second.data());
189 else if (it.first ==
"signalNonData") {
192 std::uint32_t
count(0);
193 std::uint64_t
sum2 (0);
194 for (
auto const & s : it.second) {
195 if (s.first ==
"sum")
196 sum = std::stoi(s.second.data());
197 if (s.first ==
"sum2")
198 sum2 = std::stoull(s.second.data());
199 if (s.first ==
"min")
200 min = std::stoi(s.second.data());
201 if (s.first ==
"max")
202 max = std::stoi(s.second.data());
203 if (s.first ==
"count")
204 count = std::stoul(s.second.data());
208 else if (it.first ==
"bitrate") {
211 std::uint64_t
sum2 (0);
212 for (
auto const & s : it.second) {
213 if (s.first ==
"sum")
214 sum = std::stoul(s.second.data());
215 if (s.first ==
"sum2")
216 sum2 = std::stoull(s.second.data());
217 if (s.first ==
"min")
218 min = std::stoul(s.second.data());
219 if (s.first ==
"max")
220 max = std::stoul(s.second.data());
221 if (s.first ==
"count")
222 count = std::stoul(s.second.data());
226 else if (it.first ==
"bitrateNonData") {
229 std::uint64_t
sum2 (0);
230 for (
auto const & s : it.second) {
231 if (s.first ==
"sum")
232 sum = std::stoul(s.second.data());
233 if (s.first ==
"sum2")
234 sum2 = std::stoull(s.second.data());
235 if (s.first ==
"min")
236 min = std::stoul(s.second.data());
237 if (s.first ==
"max")
238 max = std::stoul(s.second.data());
239 if (s.first ==
"count")
240 count = std::stoul(s.second.data());
244 else if (it.first ==
"badFCS") {
245 data.
badFCS = std::stoul(it.second.data());
248 else if (it.first ==
"badFCSBytes") {
252 else if (it.first ==
"rTx") {
253 data.
rTx = std::stoul(it.second.data());
256 else if (it.first ==
"rTxBytes") {
257 data.
rTxBytes = std::stoul(it.second.data());
260 else if (it.first ==
"total") {
261 data.
total = std::stoul(it.second.data());
264 else if (it.first ==
"totalBytes") {
265 data.
totalBytes = std::stoul(it.second.data());
268 else if (it.first ==
"airTime") {
269 data.
airTime = std::stoul(it.second.data());
272 else if (it.first ==
"bssId") {
276 else if (it.first ==
"ssId") {
278 data.
ssId = it.second.data();
280 else if (it.first ==
"type") {
284 else if (it.first ==
"lastSeen") {
298 }
catch(std::exception
const & ex) {
305 timestamp_ = senf::scheduler::now();
310 static void fast_split(
char *
str,
char sep, std::vector<char *> & tokens)
312 unsigned int start = 0, stop;
313 for (stop = 0;
str[stop]; stop++) {
314 if (
str[stop] == sep) {
316 tokens.emplace_back(
str + start);
318 }
else if (
str[stop] ==
'\n') {
322 tokens.emplace_back(
str + start);
325 static inline std::uint32_t atou(
const char *
str)
328 while (*str !=
'\0') {
329 x = (x*10) + (*str -
'0');
335 static inline std::uint64_t atoull(
const char *
str)
337 return strtoull(str, NULL, 10);
342 if (timestamp_ and (tag_ == tag))
351 if ((statsFile = fopen((debugFsPath_ +
"stats_csv").c_str(),
"r")) != NULL) {
352 while (fgets(dataLine,
sizeof(dataLine) -1, statsFile)) {
353 std::vector<char *> tokens;
354 fast_split(dataLine,
',', tokens);
355 if (tokens.size() == 32) {
359 atoi(tokens[3]), atoi(tokens[4]),
360 atou(tokens[5])).
data();
362 atoi(tokens[8]), atoi(tokens[9]),
363 atou(tokens[10])).
data();
365 atou(tokens[13]), atou(tokens[14]),
366 atou(tokens[15])).
data();
368 atou(tokens[18]), atou(tokens[19]),
369 atou(tokens[20])).
data();
371 data.
badFCS = atou(tokens[21]);
373 data.
rTx = atou(tokens[23]);
375 data.
total = atou(tokens[25]);
377 data.
airTime = atou(tokens[27]);
381 data.
ssId = tokens[31];
403 timestamp_ = senf::scheduler::now();
410 if (timestamp_ and (tag_ == tag))
417 mmapFile stats(debugFsPath_ +
"stats_bin");
434 timestamp_ = senf::scheduler::now();
461 return invalidEntries_;
config::time_type clock_type
senf::StatisticsData bitrate
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_milliseconds(clock_type const &v)
std::string str(T const &t)
mmapFile(std::string const &fname)
senf::StatisticsData signal
StatsDataPktCountsKernel pktCounts
u8 data[SPECTRAL_HT20_NUM_BINS]
StatsDataCollectorKernel bitrate
static MACAddress from_string(std::string const &s)
bool pollStatisticsBIN(std::uint32_t tag, senf::ClockService::clock_type const &maxAge)
bool enable(bool on=true)
std::uint32_t invalidEntries() const
std::uint32_t rTx_packets
WifiStatistics(std::string ifName, std::string debugFS="/sys/kernel/debug")
bool pollStatistics(std::uint32_t tag, senf::ClockService::clock_type const &maxAge)
ClockService::clock_type const & timestamp() const
StatsDataCollectorKernel signal
senf::StatisticsData signalNonData
static SENF_CLOCKSERVICE_CONSTEXPR clock_type milliseconds(int64_type const &v)
WifiStatisticsMap const & map() const
std::uint32_t bad_fcs_bytes
bool pollStatisticsCSV(std::uint32_t tag, senf::ClockService::clock_type const &maxAge)
boost::unordered_map< senf::MACAddress, WifiStatisticsData > WifiStatisticsMap
StatsDataCollectorKernel signalNonData
StatsDataCollectorKernel bitrateNonData
std::uint32_t ioErrors() const
WifiStatisticsMap const & statisticsMap(std::uint32_t tag, senf::ClockService::clock_type const &maxAge)
void * open(std::string const &fname)
senf::ClockService::clock_type lastSeen
std::uint32_t badFCSBytes
std::uint32_t bad_fcs_packets
static MACAddress from_data(InputIterator i)
senf::StatisticsData bitrateNonData
std::uint32_t tag() const