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 <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
const unsigned int RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||||
|
const unsigned int BER_COUNT = 7U * 1233U; // 7 * 180ms = 1260ms
|
||||||
|
|
||||||
// #define DUMP_P25
|
// #define DUMP_P25
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
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_maxRSSI(0U),
|
||||||
m_minRSSI(0U),
|
m_minRSSI(0U),
|
||||||
m_aveRSSI(0U),
|
m_aveRSSI(0U),
|
||||||
|
m_rssiCountTotal(0U),
|
||||||
|
m_rssiAccum(0U),
|
||||||
m_rssiCount(0U),
|
m_rssiCount(0U),
|
||||||
|
m_bitsCount(0U),
|
||||||
|
m_bitErrsAccum(0U),
|
||||||
m_enabled(true),
|
m_enabled(true),
|
||||||
m_fp(NULL)
|
m_fp(NULL)
|
||||||
{
|
{
|
||||||
@@ -128,8 +135,8 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
std::string source = m_lookup->find(srcId);
|
std::string source = m_lookup->find(srcId);
|
||||||
|
|
||||||
if (m_rssi != 0U) {
|
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);
|
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_rssiCount);
|
writeJSONRF("lost", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCountTotal);
|
||||||
} else {
|
} 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));
|
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));
|
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_maxRSSI = m_rssi;
|
||||||
|
|
||||||
m_aveRSSI += m_rssi;
|
m_aveRSSI += m_rssi;
|
||||||
m_rssiCount++;
|
m_rssiCountTotal++;
|
||||||
|
|
||||||
|
writeJSONRSSI();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duid == P25_DUID_LDU1) {
|
if (duid == P25_DUID_LDU1) {
|
||||||
@@ -266,8 +275,14 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
m_aveRSSI = m_rssi;
|
m_aveRSSI = m_rssi;
|
||||||
|
m_rssiCountTotal = 1U;
|
||||||
|
|
||||||
|
m_rssiAccum = m_rssi;
|
||||||
m_rssiCount = 1U;
|
m_rssiCount = 1U;
|
||||||
|
|
||||||
|
m_bitErrsAccum = 0U;
|
||||||
|
m_bitsCount = 0U;
|
||||||
|
|
||||||
createRFHeader();
|
createRFHeader();
|
||||||
writeNetwork(data + 2U, P25_DUID_HEADER, false);
|
writeNetwork(data + 2U, P25_DUID_HEADER, false);
|
||||||
} else if (m_rfState == RS_RF_AUDIO) {
|
} else if (m_rfState == RS_RF_AUDIO) {
|
||||||
@@ -298,6 +313,10 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
m_rfFrames++;
|
m_rfFrames++;
|
||||||
m_lastDUID = duid;
|
m_lastDUID = duid;
|
||||||
|
|
||||||
|
m_bitsCount += 1233U;
|
||||||
|
m_bitErrsAccum += errors;
|
||||||
|
writeJSONBER();
|
||||||
|
|
||||||
// Add busy bits
|
// Add busy bits
|
||||||
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
|
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_rfFrames++;
|
||||||
m_lastDUID = duid;
|
m_lastDUID = duid;
|
||||||
|
|
||||||
|
m_bitsCount += 1233U;
|
||||||
|
m_bitErrsAccum += errors;
|
||||||
|
writeJSONBER();
|
||||||
|
|
||||||
// Add busy bits
|
// Add busy bits
|
||||||
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
|
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;
|
m_lastDUID = duid;
|
||||||
|
|
||||||
if (m_rssi != 0U) {
|
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);
|
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_rssiCount);
|
writeJSONRF("end", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCountTotal);
|
||||||
} else {
|
} 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));
|
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));
|
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;
|
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)
|
void CP25Control::writeJSONRF(const char* action, unsigned int srcId, const std::string& srcInfo, bool grp, unsigned int dstId)
|
||||||
{
|
{
|
||||||
assert(action != NULL);
|
assert(action != NULL);
|
||||||
|
|||||||
@@ -93,7 +93,11 @@ private:
|
|||||||
unsigned char m_maxRSSI;
|
unsigned char m_maxRSSI;
|
||||||
unsigned char m_minRSSI;
|
unsigned char m_minRSSI;
|
||||||
unsigned int m_aveRSSI;
|
unsigned int m_aveRSSI;
|
||||||
|
unsigned int m_rssiCountTotal;
|
||||||
|
unsigned int m_rssiAccum;
|
||||||
unsigned int m_rssiCount;
|
unsigned int m_rssiCount;
|
||||||
|
unsigned int m_bitsCount;
|
||||||
|
unsigned int m_bitErrsAccum;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
FILE* m_fp;
|
FILE* m_fp;
|
||||||
|
|
||||||
@@ -121,6 +125,9 @@ private:
|
|||||||
bool writeFile(const unsigned char* data, unsigned char length);
|
bool writeFile(const unsigned char* data, unsigned char length);
|
||||||
void closeFile();
|
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, 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);
|
||||||
void writeJSONRF(const char* action, float duration, float ber, unsigned char minRSSI, unsigned char maxRSSI, unsigned int aveRSSI);
|
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;
|
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()
|
void CYSFControl::writeJSONRSSI()
|
||||||
{
|
{
|
||||||
m_rssiAccum += m_rssi;
|
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)
|
void CYSFControl::writeJSONRF(const char* action, float duration, float ber, unsigned char minRSSI, unsigned char maxRSSI, unsigned int aveRSSI)
|
||||||
{
|
{
|
||||||
assert(action != NULL);
|
assert(action != NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user