blob: 71c1de89bd15a12e4e5e7d2b6c34e9a6f08641c1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* This file contains code to collect and print receive statistics to the
* console.
*/
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include "console/console.h"
#include "loraping.h"
#define LORAPING_NUM_RXINFOS 10
struct loraping_rxinfo {
int8_t rssi;
int8_t snr;
uint8_t rxed:1;
};
static struct loraping_rxinfo loraping_rxinfos[LORAPING_NUM_RXINFOS];
static int loraping_rxinfo_idx;
static int loraping_rxinfo_rollover;
static void
loraping_rxinfo_avg(struct loraping_rxinfo *out_info, int *out_pkt_loss)
{
long long rssi_sum;
long long snr_sum;
int num_rxed;
int count;
int i;
if (!loraping_rxinfo_rollover) {
count = loraping_rxinfo_idx;
} else {
count = LORAPING_NUM_RXINFOS;
}
assert(count > 0);
rssi_sum = 0;
snr_sum = 0;
num_rxed = 0;
for (i = 0; i < count; i++) {
if (loraping_rxinfos[i].rxed) {
num_rxed++;
rssi_sum += loraping_rxinfos[i].rssi;
snr_sum += loraping_rxinfos[i].snr;
}
}
memset(out_info, 0, sizeof *out_info);
if (num_rxed > 0) {
out_info->rssi = rssi_sum / num_rxed;
out_info->snr = snr_sum / num_rxed;
}
*out_pkt_loss = (count - num_rxed) * 10000 / count;
}
static void
loraping_rxinfo_inc_idx(void)
{
loraping_rxinfo_idx++;
if (loraping_rxinfo_idx >= LORAPING_NUM_RXINFOS) {
loraping_rxinfo_idx = 0;
loraping_rxinfo_rollover = 1;
}
}
void
loraping_rxinfo_print(void)
{
const struct loraping_rxinfo *last;
struct loraping_rxinfo avg;
int last_idx;
int pkt_loss;
int width;
last_idx = loraping_rxinfo_idx - 1;
if (last_idx < 0) {
last_idx += LORAPING_NUM_RXINFOS;
}
last = loraping_rxinfos + last_idx;
loraping_rxinfo_avg(&avg, &pkt_loss);
if (last->rxed) {
width = console_printf("[LAST] rssi=%-4d snr=%-4d",
last->rssi, last->snr);
} else {
width = console_printf("[LAST] TIMEOUT");
}
for (; width < 48; width++) {
console_printf(" ");
}
console_printf("[AVG-%d] rssi=%-4d snr=%-4d pkt_loss=%d.%02d%%\n",
LORAPING_NUM_RXINFOS, avg.rssi, avg.snr,
pkt_loss / 100, pkt_loss % 100);
}
void
loraping_rxinfo_timeout(void)
{
loraping_rxinfos[loraping_rxinfo_idx].rxed = 0;
loraping_rxinfo_inc_idx();
}
void
loraping_rxinfo_rxed(int8_t rssi, int8_t snr)
{
loraping_rxinfos[loraping_rxinfo_idx].rssi = rssi;
loraping_rxinfos[loraping_rxinfo_idx].snr = snr;
loraping_rxinfos[loraping_rxinfo_idx].rxed = 1;
loraping_rxinfo_inc_idx();
}