2020-12-25 16:10:38 -08:00
|
|
|
#include "airtime.h"
|
2021-12-07 13:04:50 -08:00
|
|
|
#include "NodeDB.h"
|
2021-12-28 23:34:49 -08:00
|
|
|
#include "configuration.h"
|
2020-12-24 22:12:59 -08:00
|
|
|
|
2021-12-07 13:04:50 -08:00
|
|
|
#define periodsToLog 24
|
2020-12-24 22:12:59 -08:00
|
|
|
|
2021-01-08 20:43:51 -08:00
|
|
|
AirTime *airTime;
|
2021-01-01 12:31:46 -08:00
|
|
|
|
2020-12-25 16:10:38 -08:00
|
|
|
// Don't read out of this directly. Use the helper functions.
|
|
|
|
|
struct airtimeStruct {
|
2021-01-14 18:40:18 -08:00
|
|
|
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.
|
2020-12-27 10:50:52 -08:00
|
|
|
uint8_t lastPeriodIndex;
|
2020-12-25 16:10:38 -08:00
|
|
|
} airtimes;
|
2020-12-24 22:12:59 -08:00
|
|
|
|
2021-01-01 12:31:46 -08:00
|
|
|
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
2020-12-24 22:12:59 -08:00
|
|
|
{
|
2020-12-25 16:10:38 -08:00
|
|
|
if (reportType == TX_LOG) {
|
2021-01-14 18:40:18 -08:00
|
|
|
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
|
|
|
|
|
airtimes.periodTX[0] = airtimes.periodTX[0] + airtime_ms;
|
2021-12-07 13:04:50 -08:00
|
|
|
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
|
2020-12-25 16:10:38 -08:00
|
|
|
} else if (reportType == RX_LOG) {
|
2021-01-14 18:40:18 -08:00
|
|
|
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
|
|
|
|
|
airtimes.periodRX[0] = airtimes.periodRX[0] + airtime_ms;
|
2021-12-07 13:04:50 -08:00
|
|
|
myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
|
2020-12-25 16:10:38 -08:00
|
|
|
} else if (reportType == RX_ALL_LOG) {
|
2021-01-14 18:40:18 -08:00
|
|
|
DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
|
|
|
|
|
airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + airtime_ms;
|
2020-12-25 16:10:38 -08:00
|
|
|
} else {
|
2021-01-01 21:20:34 -08:00
|
|
|
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n");
|
2020-12-25 16:10:38 -08:00
|
|
|
}
|
2021-12-28 23:34:49 -08:00
|
|
|
|
|
|
|
|
uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
|
|
|
|
|
this->channelUtilization[channelUtilPeriod] = channelUtilization[channelUtilPeriod] + airtime_ms;
|
2020-12-25 16:10:38 -08:00
|
|
|
}
|
2020-12-24 22:12:59 -08:00
|
|
|
|
2021-12-28 23:34:49 -08:00
|
|
|
uint8_t AirTime::currentPeriodIndex()
|
2020-12-25 16:10:38 -08:00
|
|
|
{
|
2021-12-28 23:34:49 -08:00
|
|
|
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % periodsToLog);
|
2020-12-25 16:10:38 -08:00
|
|
|
}
|
2020-12-24 22:12:59 -08:00
|
|
|
|
2021-12-28 23:34:49 -08:00
|
|
|
void AirTime::airtimeRotatePeriod()
|
2020-12-25 16:10:38 -08:00
|
|
|
{
|
2021-01-01 12:31:46 -08:00
|
|
|
|
|
|
|
|
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];
|
2021-12-07 13:04:50 -08:00
|
|
|
|
|
|
|
|
myNodeInfo.air_period_tx[i + 1] = myNodeInfo.air_period_tx[i];
|
|
|
|
|
myNodeInfo.air_period_rx[i + 1] = myNodeInfo.air_period_rx[i];
|
2020-12-26 22:39:43 -08:00
|
|
|
}
|
2021-01-01 12:31:46 -08:00
|
|
|
airtimes.periodTX[0] = 0;
|
|
|
|
|
airtimes.periodRX[0] = 0;
|
|
|
|
|
airtimes.periodRX_ALL[0] = 0;
|
|
|
|
|
|
2021-12-07 13:04:50 -08:00
|
|
|
myNodeInfo.air_period_tx[0] = 0;
|
|
|
|
|
myNodeInfo.air_period_rx[0] = 0;
|
|
|
|
|
|
2021-01-01 12:31:46 -08:00
|
|
|
airtimes.lastPeriodIndex = currentPeriodIndex();
|
2020-12-25 16:10:38 -08:00
|
|
|
}
|
2020-12-24 22:12:59 -08:00
|
|
|
}
|
|
|
|
|
|
2021-01-14 18:40:18 -08:00
|
|
|
uint32_t *airtimeReport(reportTypes reportType)
|
2020-12-24 22:12:59 -08:00
|
|
|
{
|
2020-12-25 16:10:38 -08:00
|
|
|
|
2020-12-26 22:39:43 -08:00
|
|
|
if (reportType == TX_LOG) {
|
2020-12-27 10:50:52 -08:00
|
|
|
return airtimes.periodTX;
|
2020-12-26 22:39:43 -08:00
|
|
|
} else if (reportType == RX_LOG) {
|
2020-12-27 10:50:52 -08:00
|
|
|
return airtimes.periodRX;
|
2020-12-26 22:39:43 -08:00
|
|
|
} else if (reportType == RX_ALL_LOG) {
|
2020-12-27 10:50:52 -08:00
|
|
|
return airtimes.periodRX_ALL;
|
2020-12-25 16:10:38 -08:00
|
|
|
}
|
2020-12-26 22:39:43 -08:00
|
|
|
return 0;
|
|
|
|
|
}
|
2020-12-25 16:10:38 -08:00
|
|
|
|
2021-12-28 23:34:49 -08:00
|
|
|
uint8_t AirTime::getPeriodsToLog()
|
2020-12-27 10:50:52 -08:00
|
|
|
{
|
|
|
|
|
return periodsToLog;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-28 23:34:49 -08:00
|
|
|
uint32_t AirTime::getSecondsPerPeriod()
|
2020-12-26 22:39:43 -08:00
|
|
|
{
|
2021-12-28 23:34:49 -08:00
|
|
|
return SECONDS_PER_PERIOD;
|
2020-12-27 10:50:52 -08:00
|
|
|
}
|
|
|
|
|
|
2021-12-28 23:34:49 -08:00
|
|
|
uint32_t AirTime::getSecondsSinceBoot()
|
2020-12-27 10:50:52 -08:00
|
|
|
{
|
2021-12-28 23:34:49 -08:00
|
|
|
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;
|
2020-12-27 10:50:52 -08:00
|
|
|
}
|
2021-01-01 12:31:46 -08:00
|
|
|
|
|
|
|
|
AirTime::AirTime() : concurrency::OSThread("AirTime") {}
|
|
|
|
|
|
|
|
|
|
int32_t AirTime::runOnce()
|
|
|
|
|
{
|
|
|
|
|
secSinceBoot++;
|
|
|
|
|
|
2021-12-28 23:34:49 -08:00
|
|
|
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());
|
|
|
|
|
}
|
2021-01-01 21:20:34 -08:00
|
|
|
|
|
|
|
|
return (1000 * 1);
|
2021-01-01 12:31:46 -08:00
|
|
|
}
|