firmware/src/airtime.cpp

140 lines
4.2 KiB
C++
Raw Normal View History

#include "airtime.h"
#include "NodeDB.h"
#include "configuration.h"
#define periodsToLog 24
AirTime *airTime;
// Don't read out of this directly. Use the helper functions.
struct airtimeStruct {
uint32_t periodTX[periodsToLog]; // AirTime transmitted
uint32_t periodRX[periodsToLog]; // AirTime received and repeated (Only valid mesh packets)
uint32_t periodRX_ALL[periodsToLog]; // AirTime received regardless of valid mesh packet. Could include noise.
uint8_t lastPeriodIndex;
} airtimes;
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{
if (reportType == TX_LOG) {
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
airtimes.periodTX[0] = airtimes.periodTX[0] + airtime_ms;
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
} else if (reportType == RX_LOG) {
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
airtimes.periodRX[0] = airtimes.periodRX[0] + airtime_ms;
myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) {
DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + airtime_ms;
} else {
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n");
}
uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
this->channelUtilization[channelUtilPeriod] = channelUtilization[channelUtilPeriod] + airtime_ms;
}
uint8_t AirTime::currentPeriodIndex()
{
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % periodsToLog);
}
void AirTime::airtimeRotatePeriod()
{
if (airtimes.lastPeriodIndex != currentPeriodIndex()) {
DEBUG_MSG("Rotating airtimes to a new period = %u\n", currentPeriodIndex());
for (int i = periodsToLog - 2; i >= 0; --i) {
airtimes.periodTX[i + 1] = airtimes.periodTX[i];
airtimes.periodRX[i + 1] = airtimes.periodRX[i];
airtimes.periodRX_ALL[i + 1] = airtimes.periodRX_ALL[i];
myNodeInfo.air_period_tx[i + 1] = myNodeInfo.air_period_tx[i];
myNodeInfo.air_period_rx[i + 1] = myNodeInfo.air_period_rx[i];
2020-12-27 06:39:43 +00:00
}
airtimes.periodTX[0] = 0;
airtimes.periodRX[0] = 0;
airtimes.periodRX_ALL[0] = 0;
myNodeInfo.air_period_tx[0] = 0;
myNodeInfo.air_period_rx[0] = 0;
airtimes.lastPeriodIndex = currentPeriodIndex();
}
}
uint32_t *airtimeReport(reportTypes reportType)
{
2020-12-27 06:39:43 +00:00
if (reportType == TX_LOG) {
return airtimes.periodTX;
2020-12-27 06:39:43 +00:00
} else if (reportType == RX_LOG) {
return airtimes.periodRX;
2020-12-27 06:39:43 +00:00
} else if (reportType == RX_ALL_LOG) {
return airtimes.periodRX_ALL;
}
2020-12-27 06:39:43 +00:00
return 0;
}
uint8_t AirTime::getPeriodsToLog()
{
return periodsToLog;
}
uint32_t AirTime::getSecondsPerPeriod()
2020-12-27 06:39:43 +00:00
{
return SECONDS_PER_PERIOD;
}
uint32_t AirTime::getSecondsSinceBoot()
{
return this->secSinceBoot;
}
float AirTime::channelUtilizationPercent()
{
uint32_t sum = 0;
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
sum += this->channelUtilization[i];
// DEBUG_MSG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
}
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
}
AirTime::AirTime() : concurrency::OSThread("AirTime") {}
int32_t AirTime::runOnce()
{
secSinceBoot++;
uint8_t utilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
if (firstTime) {
// DEBUG_MSG("AirTime::runOnce()\n");
airtimeRotatePeriod();
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
this->channelUtilization[i] = 0;
}
firstTime = false;
lastUtilPeriod = utilPeriod;
} else {
// Reset the channelUtilization window when we roll over
if (lastUtilPeriod != utilPeriod) {
lastUtilPeriod = utilPeriod;
this->channelUtilization[utilPeriod] = 0;
}
DEBUG_MSG("Channel Utilization percent %3.1f\n", airTime->channelUtilizationPercent());
}
return (1000 * 1);
}