mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 23:45:49 +08:00
Add JSON RSSI and BER to P25.
This commit is contained in:
@@ -31,6 +31,9 @@
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
const unsigned int RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||
const unsigned int BER_COUNT = 7U * 1233U; // 7 * 180ms = 1260ms
|
||||
|
||||
// #define DUMP_P25
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
@@ -79,7 +82,11 @@ m_rssi(0U),
|
||||
m_maxRSSI(0U),
|
||||
m_minRSSI(0U),
|
||||
m_aveRSSI(0U),
|
||||
m_rssiCountTotal(0U),
|
||||
m_rssiAccum(0U),
|
||||
m_rssiCount(0U),
|
||||
m_bitsCount(0U),
|
||||
m_bitErrsAccum(0U),
|
||||
m_enabled(true),
|
||||
m_fp(NULL)
|
||||
{
|
||||
@@ -128,8 +135,8 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||
std::string source = m_lookup->find(srcId);
|
||||
|
||||
if (m_rssi != 0U) {
|
||||
LogMessage("P25, transmission lost from %s to %s%u, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
writeJSONRF("lost", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
LogMessage("P25, transmission lost from %s to %s%u, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCountTotal);
|
||||
writeJSONRF("lost", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCountTotal);
|
||||
} else {
|
||||
LogMessage("P25, transmission lost from %s to %s%u, %.1f seconds, BER: %.1f%%", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
writeJSONRF("lost", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
@@ -217,7 +224,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||
m_maxRSSI = m_rssi;
|
||||
|
||||
m_aveRSSI += m_rssi;
|
||||
m_rssiCount++;
|
||||
m_rssiCountTotal++;
|
||||
|
||||
writeJSONRSSI();
|
||||
}
|
||||
|
||||
if (duid == P25_DUID_LDU1) {
|
||||
@@ -266,8 +275,14 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||
m_minRSSI = m_rssi;
|
||||
m_maxRSSI = m_rssi;
|
||||
m_aveRSSI = m_rssi;
|
||||
m_rssiCountTotal = 1U;
|
||||
|
||||
m_rssiAccum = m_rssi;
|
||||
m_rssiCount = 1U;
|
||||
|
||||
m_bitErrsAccum = 0U;
|
||||
m_bitsCount = 0U;
|
||||
|
||||
createRFHeader();
|
||||
writeNetwork(data + 2U, P25_DUID_HEADER, false);
|
||||
} else if (m_rfState == RS_RF_AUDIO) {
|
||||
@@ -298,6 +313,10 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||
m_rfFrames++;
|
||||
m_lastDUID = duid;
|
||||
|
||||
m_bitsCount += 1233U;
|
||||
m_bitErrsAccum += errors;
|
||||
writeJSONBER();
|
||||
|
||||
// Add busy bits
|
||||
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
|
||||
|
||||
@@ -344,6 +363,10 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||
m_rfFrames++;
|
||||
m_lastDUID = duid;
|
||||
|
||||
m_bitsCount += 1233U;
|
||||
m_bitErrsAccum += errors;
|
||||
writeJSONBER();
|
||||
|
||||
// Add busy bits
|
||||
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
|
||||
|
||||
@@ -469,8 +492,8 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||
m_lastDUID = duid;
|
||||
|
||||
if (m_rssi != 0U) {
|
||||
LogMessage("P25, received RF end of voice transmission from %s to %s%u, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
writeJSONRF("end", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
LogMessage("P25, received RF end of voice transmission from %s to %s%u, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCountTotal);
|
||||
writeJSONRF("end", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCountTotal);
|
||||
} else {
|
||||
LogMessage("P25, received RF end of voice transmission from %s to %s%u, %.1f seconds, BER: %.1f%%", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
writeJSONRF("end", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
@@ -1213,6 +1236,43 @@ void CP25Control::enable(bool enabled)
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
void CP25Control::writeJSONRSSI()
|
||||
{
|
||||
m_rssiAccum += m_rssi;
|
||||
m_rssiCount++;
|
||||
|
||||
if (m_rssiCount >= RSSI_COUNT) {
|
||||
nlohmann::json json;
|
||||
|
||||
json["timestamp"] = CUtils::createTimestamp();
|
||||
json["mode"] = "P25";
|
||||
|
||||
json["value"] = -int(m_rssiAccum / m_rssiCount);
|
||||
|
||||
WriteJSON("RSSI", json);
|
||||
|
||||
m_rssiAccum = 0U;
|
||||
m_rssiCount = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void CP25Control::writeJSONBER()
|
||||
{
|
||||
if (m_bitsCount >= BER_COUNT) {
|
||||
nlohmann::json json;
|
||||
|
||||
json["timestamp"] = CUtils::createTimestamp();
|
||||
json["mode"] = "P25";
|
||||
|
||||
json["value"] = float(m_bitErrsAccum * 100U) / float(m_bitsCount);
|
||||
|
||||
WriteJSON("BER", json);
|
||||
|
||||
m_bitErrsAccum = 0U;
|
||||
m_bitsCount = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
void CP25Control::writeJSONRF(const char* action, unsigned int srcId, const std::string& srcInfo, bool grp, unsigned int dstId)
|
||||
{
|
||||
assert(action != NULL);
|
||||
|
||||
@@ -93,7 +93,11 @@ private:
|
||||
unsigned char m_maxRSSI;
|
||||
unsigned char m_minRSSI;
|
||||
unsigned int m_aveRSSI;
|
||||
unsigned int m_rssiCountTotal;
|
||||
unsigned int m_rssiAccum;
|
||||
unsigned int m_rssiCount;
|
||||
unsigned int m_bitsCount;
|
||||
unsigned int m_bitErrsAccum;
|
||||
bool m_enabled;
|
||||
FILE* m_fp;
|
||||
|
||||
@@ -121,6 +125,9 @@ private:
|
||||
bool writeFile(const unsigned char* data, unsigned char length);
|
||||
void closeFile();
|
||||
|
||||
void writeJSONRSSI();
|
||||
void writeJSONBER();
|
||||
|
||||
void writeJSONRF(const char* action, unsigned int srcId, const std::string& srcInfo, bool grp, unsigned int dstId);
|
||||
void writeJSONRF(const char* action, float duration, float ber);
|
||||
void writeJSONRF(const char* action, float duration, float ber, unsigned char minRSSI, unsigned char maxRSSI, unsigned int aveRSSI);
|
||||
|
||||
@@ -1286,35 +1286,6 @@ void CYSFControl::enable(bool enabled)
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
void CYSFControl::writeJSONRF(const char* action, const char* mode, const unsigned char* source, unsigned char dgid)
|
||||
{
|
||||
assert(action != NULL);
|
||||
assert(mode != NULL);
|
||||
assert(source != NULL);
|
||||
|
||||
nlohmann::json json;
|
||||
|
||||
writeJSONRF(json, action, source, dgid);
|
||||
|
||||
json["mode"] = mode;
|
||||
|
||||
WriteJSON("YSF", json);
|
||||
}
|
||||
|
||||
void CYSFControl::writeJSONRF(const char* action, float duration, float ber)
|
||||
{
|
||||
assert(action != NULL);
|
||||
|
||||
nlohmann::json json;
|
||||
|
||||
writeJSONRF(json, action);
|
||||
|
||||
json["duration"] = duration;
|
||||
json["ber"] = ber;
|
||||
|
||||
WriteJSON("YSF", json);
|
||||
}
|
||||
|
||||
void CYSFControl::writeJSONRSSI()
|
||||
{
|
||||
m_rssiAccum += m_rssi;
|
||||
@@ -1355,6 +1326,35 @@ void CYSFControl::writeJSONBER(unsigned int bits, unsigned int errs)
|
||||
}
|
||||
}
|
||||
|
||||
void CYSFControl::writeJSONRF(const char* action, const char* mode, const unsigned char* source, unsigned char dgid)
|
||||
{
|
||||
assert(action != NULL);
|
||||
assert(mode != NULL);
|
||||
assert(source != NULL);
|
||||
|
||||
nlohmann::json json;
|
||||
|
||||
writeJSONRF(json, action, source, dgid);
|
||||
|
||||
json["mode"] = mode;
|
||||
|
||||
WriteJSON("YSF", json);
|
||||
}
|
||||
|
||||
void CYSFControl::writeJSONRF(const char* action, float duration, float ber)
|
||||
{
|
||||
assert(action != NULL);
|
||||
|
||||
nlohmann::json json;
|
||||
|
||||
writeJSONRF(json, action);
|
||||
|
||||
json["duration"] = duration;
|
||||
json["ber"] = ber;
|
||||
|
||||
WriteJSON("YSF", json);
|
||||
}
|
||||
|
||||
void CYSFControl::writeJSONRF(const char* action, float duration, float ber, unsigned char minRSSI, unsigned char maxRSSI, unsigned int aveRSSI)
|
||||
{
|
||||
assert(action != NULL);
|
||||
|
||||
Reference in New Issue
Block a user