mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-23 00:35:53 +08:00
Add RSSI reporting to FM and AX.25.
This commit is contained in:
@@ -30,11 +30,13 @@ const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04
|
|||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
CAX25Control::CAX25Control(CAX25Network* network, bool trace) :
|
CAX25Control::CAX25Control(CAX25Network* network, bool trace, CRSSIInterpolator* rssiMapper) :
|
||||||
m_network(network),
|
m_network(network),
|
||||||
m_trace(trace),
|
m_trace(trace),
|
||||||
|
m_rssiMapper(rssiMapper),
|
||||||
m_enabled(true)
|
m_enabled(true)
|
||||||
{
|
{
|
||||||
|
assert(rssiMapper != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAX25Control::~CAX25Control()
|
CAX25Control::~CAX25Control()
|
||||||
@@ -48,17 +50,33 @@ bool CAX25Control::writeModem(unsigned char *data, unsigned int len)
|
|||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_trace)
|
bool hasRSSI = data[0U] == TAG_RSSI;
|
||||||
decode(data, len);
|
|
||||||
|
|
||||||
decodeJSON("rf", data, len);
|
unsigned int offset = hasRSSI ? 3U : 1U;
|
||||||
|
|
||||||
|
int rssi = 0;
|
||||||
|
if (hasRSSI) {
|
||||||
|
uint16_t raw = 0U;
|
||||||
|
raw |= (data[1U] << 8) & 0xFF00U;
|
||||||
|
raw |= (data[2U] << 0) & 0x00FFU;
|
||||||
|
|
||||||
|
// Convert the raw RSSI to dBm
|
||||||
|
rssi = m_rssiMapper->interpolate(raw);
|
||||||
|
if (rssi != 0)
|
||||||
|
LogDebug("AX.25, raw RSSI: %u, reported RSSI: %d dBm", raw, rssi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_trace)
|
||||||
|
decode(data + offset, len - offset);
|
||||||
|
|
||||||
|
decodeJSON("rf", data + offset, len - offset, rssi);
|
||||||
|
|
||||||
CUtils::dump(1U, "AX.25 received packet", data, len);
|
CUtils::dump(1U, "AX.25 received packet", data, len);
|
||||||
|
|
||||||
if (m_network == NULL)
|
if (m_network == NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return m_network->write(data, len);
|
return m_network->write(data + offset, len - offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CAX25Control::readModem(unsigned char* data)
|
unsigned int CAX25Control::readModem(unsigned char* data)
|
||||||
@@ -185,7 +203,7 @@ void CAX25Control::decode(const unsigned char* data, unsigned int length)
|
|||||||
LogMessage("AX.25, %s %.*s", text.c_str(), length - n, data + n);
|
LogMessage("AX.25, %s %.*s", text.c_str(), length - n, data + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAX25Control::decodeJSON(const char* source, const unsigned char* data, unsigned int length)
|
void CAX25Control::decodeJSON(const char* source, const unsigned char* data, unsigned int length, int rssi)
|
||||||
{
|
{
|
||||||
assert(source != NULL);
|
assert(source != NULL);
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
@@ -205,6 +223,9 @@ void CAX25Control::decodeJSON(const char* source, const unsigned char* data, uns
|
|||||||
decodeAddressJSON(data + 0U, text, isDigi);
|
decodeAddressJSON(data + 0U, text, isDigi);
|
||||||
json["destination_cs"] = text;
|
json["destination_cs"] = text;
|
||||||
|
|
||||||
|
if (rssi != 0)
|
||||||
|
json["rssi"] = rssi;
|
||||||
|
|
||||||
unsigned int n = 14U;
|
unsigned int n = 14U;
|
||||||
|
|
||||||
if (more) {
|
if (more) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#if !defined(AX25Control_H)
|
#if !defined(AX25Control_H)
|
||||||
#define AX25Control_H
|
#define AX25Control_H
|
||||||
|
|
||||||
|
#include "RSSIInterpolator.h"
|
||||||
#include "AX25Network.h"
|
#include "AX25Network.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
|
|
||||||
class CAX25Control {
|
class CAX25Control {
|
||||||
public:
|
public:
|
||||||
CAX25Control(CAX25Network* network, bool trace);
|
CAX25Control(CAX25Network* network, bool trace, CRSSIInterpolator* rssiMapper);
|
||||||
~CAX25Control();
|
~CAX25Control();
|
||||||
|
|
||||||
bool writeModem(unsigned char* data, unsigned int len);
|
bool writeModem(unsigned char* data, unsigned int len);
|
||||||
@@ -40,10 +41,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
CAX25Network* m_network;
|
CAX25Network* m_network;
|
||||||
bool m_trace;
|
bool m_trace;
|
||||||
|
CRSSIInterpolator* m_rssiMapper;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
|
|
||||||
void decode(const unsigned char* data, unsigned int length);
|
void decode(const unsigned char* data, unsigned int length);
|
||||||
void decodeJSON(const char* source, const unsigned char* data, unsigned int length);
|
void decodeJSON(const char* source, const unsigned char* data, unsigned int length, int rssi = 0);
|
||||||
bool decodeAddress(const unsigned char* data, std::string& text, bool isDigi = false) const;
|
bool decodeAddress(const unsigned char* data, std::string& text, bool isDigi = false) const;
|
||||||
bool decodeAddressJSON(const unsigned char* data, std::string& text, bool& isDigi) const;
|
bool decodeAddressJSON(const unsigned char* data, std::string& text, bool& isDigi) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ const unsigned char TAG_HEADER = 0x00U;
|
|||||||
const unsigned char TAG_DATA = 0x01U;
|
const unsigned char TAG_DATA = 0x01U;
|
||||||
const unsigned char TAG_LOST = 0x02U;
|
const unsigned char TAG_LOST = 0x02U;
|
||||||
const unsigned char TAG_EOT = 0x03U;
|
const unsigned char TAG_EOT = 0x03U;
|
||||||
|
const unsigned char TAG_RSSI = 0x04U;
|
||||||
|
|
||||||
const unsigned int DSTAR_MODEM_DATA_LEN = 220U;
|
const unsigned int DSTAR_MODEM_DATA_LEN = 220U;
|
||||||
|
|
||||||
|
|||||||
@@ -43,12 +43,13 @@ const unsigned char FS_TIMEOUT_EXT = 9U;
|
|||||||
const unsigned char FS_TIMEOUT_WAIT_EXT = 10U;
|
const unsigned char FS_TIMEOUT_WAIT_EXT = 10U;
|
||||||
const unsigned char FS_HANG = 11U;
|
const unsigned char FS_HANG = 11U;
|
||||||
|
|
||||||
CFMControl::CFMControl(CFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn) :
|
CFMControl::CFMControl(CFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn, CRSSIInterpolator* rssiMapper) :
|
||||||
m_network(network),
|
m_network(network),
|
||||||
m_txAudioGain(txAudioGain),
|
m_txAudioGain(txAudioGain),
|
||||||
m_rxAudioGain(rxAudioGain),
|
m_rxAudioGain(rxAudioGain),
|
||||||
m_preEmphasisOn(preEmphasisOn),
|
m_preEmphasisOn(preEmphasisOn),
|
||||||
m_deEmphasisOn(deEmphasisOn),
|
m_deEmphasisOn(deEmphasisOn),
|
||||||
|
m_rssiMapper(rssiMapper),
|
||||||
m_enabled(false),
|
m_enabled(false),
|
||||||
m_incomingRFAudio(1600U, "Incoming RF FM Audio"),
|
m_incomingRFAudio(1600U, "Incoming RF FM Audio"),
|
||||||
m_preEmphasis(NULL),
|
m_preEmphasis(NULL),
|
||||||
@@ -59,6 +60,7 @@ m_filterStage3(NULL)
|
|||||||
{
|
{
|
||||||
assert(txAudioGain > 0.0F);
|
assert(txAudioGain > 0.0F);
|
||||||
assert(rxAudioGain > 0.0F);
|
assert(rxAudioGain > 0.0F);
|
||||||
|
assert(rssiMapper != NULL);
|
||||||
|
|
||||||
m_preEmphasis = new CIIRDirectForm1Filter(8.315375384336983F, -7.03334621603483F,0.0F,1.0F, 0.282029168302153F,0.0F, PREEMPHASIS_GAIN_DB);
|
m_preEmphasis = new CIIRDirectForm1Filter(8.315375384336983F, -7.03334621603483F,0.0F,1.0F, 0.282029168302153F,0.0F, PREEMPHASIS_GAIN_DB);
|
||||||
m_deEmphasis = new CIIRDirectForm1Filter(0.07708787090460224F, 0.07708787090460224F,0.0F, 1.0F, -0.8458242581907955F,0.0F, DEEMPHASIS_GAIN_DB);
|
m_deEmphasis = new CIIRDirectForm1Filter(0.07708787090460224F, 0.07708787090460224F,0.0F, 1.0F, -0.8458242581907955F,0.0F, DEEMPHASIS_GAIN_DB);
|
||||||
@@ -84,9 +86,6 @@ bool CFMControl::writeModem(const unsigned char* data, unsigned int length)
|
|||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
assert(length > 0U);
|
assert(length > 0U);
|
||||||
|
|
||||||
if (m_network == NULL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (data[0U] == TAG_HEADER) {
|
if (data[0U] == TAG_HEADER) {
|
||||||
switch (data[1U]) {
|
switch (data[1U]) {
|
||||||
case FS_LISTENING: writeJSON("listening"); break;
|
case FS_LISTENING: writeJSON("listening"); break;
|
||||||
@@ -107,6 +106,24 @@ bool CFMControl::writeModem(const unsigned char* data, unsigned int length)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data[0U] == TAG_RSSI) {
|
||||||
|
uint16_t raw = 0U;
|
||||||
|
raw |= (data[0U] << 8) & 0xFF00U;
|
||||||
|
raw |= (data[1U] << 0) & 0x00FFU;
|
||||||
|
|
||||||
|
// Convert the raw RSSI to dBm
|
||||||
|
int rssi = m_rssiMapper->interpolate(raw);
|
||||||
|
if (rssi != 0) {
|
||||||
|
LogDebug("FM, raw RSSI: %u, reported RSSI: %d dBm", raw, rssi);
|
||||||
|
writeJSONRSSI(rssi);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_network == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (data[0U] == TAG_EOT)
|
if (data[0U] == TAG_EOT)
|
||||||
return m_network->writeEnd();
|
return m_network->writeEnd();
|
||||||
|
|
||||||
@@ -115,19 +132,21 @@ bool CFMControl::writeModem(const unsigned char* data, unsigned int length)
|
|||||||
|
|
||||||
m_incomingRFAudio.addData(data + 1U, length - 1U);
|
m_incomingRFAudio.addData(data + 1U, length - 1U);
|
||||||
unsigned int bufferLength = m_incomingRFAudio.dataSize();
|
unsigned int bufferLength = m_incomingRFAudio.dataSize();
|
||||||
|
|
||||||
if (bufferLength > 240U) // 160 samples 12-bit
|
if (bufferLength > 240U) // 160 samples 12-bit
|
||||||
bufferLength = 240U; // 160 samples 12-bit
|
bufferLength = 240U; // 160 samples 12-bit
|
||||||
|
|
||||||
if (bufferLength >= 3U) {
|
if (bufferLength >= 3U) {
|
||||||
bufferLength = bufferLength - bufferLength % 3U; // Round down to nearest multiple of 3
|
bufferLength = bufferLength - bufferLength % 3U; // Round down to nearest multiple of 3
|
||||||
|
|
||||||
unsigned char bufferData[240U]; // 160 samples 12-bit
|
unsigned char bufferData[240U]; // 160 samples 12-bit
|
||||||
m_incomingRFAudio.getData(bufferData, bufferLength);
|
m_incomingRFAudio.getData(bufferData, bufferLength);
|
||||||
|
|
||||||
unsigned int pack = 0U;
|
unsigned int pack = 0U;
|
||||||
unsigned char* packPointer = (unsigned char*)&pack;
|
unsigned char* packPointer = (unsigned char*)&pack;
|
||||||
|
|
||||||
float out[160U]; // 160 samples 12-bit
|
float out[160U]; // 160 samples 12-bit
|
||||||
unsigned int nOut = 0U;
|
unsigned int nOut = 0U;
|
||||||
short unpackedSamples[2U];
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < bufferLength; i += 3U) {
|
for (unsigned int i = 0U; i < bufferLength; i += 3U) {
|
||||||
// Extract unsigned 12 bit unsigned sample pairs packed into 3 bytes to 16 bit signed
|
// Extract unsigned 12 bit unsigned sample pairs packed into 3 bytes to 16 bit signed
|
||||||
@@ -135,8 +154,9 @@ bool CFMControl::writeModem(const unsigned char* data, unsigned int length)
|
|||||||
packPointer[1U] = bufferData[i + 1U];
|
packPointer[1U] = bufferData[i + 1U];
|
||||||
packPointer[2U] = bufferData[i + 2U];
|
packPointer[2U] = bufferData[i + 2U];
|
||||||
|
|
||||||
unpackedSamples[1U] = short(int(pack & FM_MASK) - 2048);
|
short unpackedSamples[2U];
|
||||||
unpackedSamples[0U] = short(int(pack >> 12 & FM_MASK) - 2048); //
|
unpackedSamples[1U] = short(int((pack >> 0) & FM_MASK) - 2048);
|
||||||
|
unpackedSamples[0U] = short(int((pack >> 12) & FM_MASK) - 2048); //
|
||||||
|
|
||||||
// Process unpacked sample pair
|
// Process unpacked sample pair
|
||||||
for (unsigned char j = 0U; j < 2U; j++) {
|
for (unsigned char j = 0U; j < 2U; j++) {
|
||||||
@@ -188,7 +208,7 @@ unsigned int CFMControl::readModem(unsigned char* data, unsigned int space)
|
|||||||
unsigned int sample12bit = (unsigned int)((sampleFloat + 1.0F) * 2048.0F + 0.5F);
|
unsigned int sample12bit = (unsigned int)((sampleFloat + 1.0F) * 2048.0F + 0.5F);
|
||||||
|
|
||||||
// Pack 2 samples into 3 bytes
|
// Pack 2 samples into 3 bytes
|
||||||
if ((i & 1U) == 0) {
|
if ((i & 1U) == 0U) {
|
||||||
pack = 0U;
|
pack = 0U;
|
||||||
pack = sample12bit << 12;
|
pack = sample12bit << 12;
|
||||||
} else {
|
} else {
|
||||||
@@ -225,5 +245,15 @@ void CFMControl::writeJSON(const char* state)
|
|||||||
WriteJSON("FM", json);
|
WriteJSON("FM", json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CFMControl::writeJSONRSSI(int rssi)
|
||||||
|
{
|
||||||
|
nlohmann::json json;
|
||||||
|
|
||||||
|
json["timestamp"] = CUtils::createTimestamp();
|
||||||
|
json["mode"] = "FM";
|
||||||
|
json["value"] = rssi;
|
||||||
|
|
||||||
|
WriteJSON("RSSI", json);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "FMNetwork.h"
|
#include "FMNetwork.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
#include "IIRDirectForm1Filter.h"
|
#include "IIRDirectForm1Filter.h"
|
||||||
|
#include "RSSIInterpolator.h"
|
||||||
|
|
||||||
#if defined(USE_FM)
|
#if defined(USE_FM)
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
|
|
||||||
class CFMControl {
|
class CFMControl {
|
||||||
public:
|
public:
|
||||||
CFMControl(CFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn);
|
CFMControl(CFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn, CRSSIInterpolator* rssiMapper);
|
||||||
~CFMControl();
|
~CFMControl();
|
||||||
|
|
||||||
bool writeModem(const unsigned char* data, unsigned int length);
|
bool writeModem(const unsigned char* data, unsigned int length);
|
||||||
@@ -51,6 +52,7 @@ private:
|
|||||||
float m_rxAudioGain;
|
float m_rxAudioGain;
|
||||||
bool m_preEmphasisOn;
|
bool m_preEmphasisOn;
|
||||||
bool m_deEmphasisOn;
|
bool m_deEmphasisOn;
|
||||||
|
CRSSIInterpolator* m_rssiMapper;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
CRingBuffer<unsigned char> m_incomingRFAudio;
|
CRingBuffer<unsigned char> m_incomingRFAudio;
|
||||||
CIIRDirectForm1Filter* m_preEmphasis;
|
CIIRDirectForm1Filter* m_preEmphasis;
|
||||||
@@ -60,6 +62,7 @@ private:
|
|||||||
CIIRDirectForm1Filter* m_filterStage3;
|
CIIRDirectForm1Filter* m_filterStage3;
|
||||||
|
|
||||||
void writeJSON(const char* state);
|
void writeJSON(const char* state);
|
||||||
|
void writeJSONRSSI(int rssi);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -352,7 +352,6 @@ int CMMDVMHost::run()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
::LogInitialise(m_conf.getLogDisplayLevel(), m_conf.getLogMQTTLevel());
|
::LogInitialise(m_conf.getLogDisplayLevel(), m_conf.getLogMQTTLevel());
|
||||||
|
|
||||||
std::vector<std::pair<std::string, void (*)(const unsigned char*, unsigned int)>> subscriptions;
|
std::vector<std::pair<std::string, void (*)(const unsigned char*, unsigned int)>> subscriptions;
|
||||||
@@ -878,7 +877,7 @@ int CMMDVMHost::run()
|
|||||||
LogInfo(" P-Persist: %u", pPersist);
|
LogInfo(" P-Persist: %u", pPersist);
|
||||||
LogInfo(" Trace: %s", trace ? "yes" : "no");
|
LogInfo(" Trace: %s", trace ? "yes" : "no");
|
||||||
|
|
||||||
m_ax25 = new CAX25Control(m_ax25Network, trace);
|
m_ax25 = new CAX25Control(m_ax25Network, trace, rssi);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -890,7 +889,7 @@ int CMMDVMHost::run()
|
|||||||
float rxAudioGain = m_conf.getFMRXAudioGain();
|
float rxAudioGain = m_conf.getFMRXAudioGain();
|
||||||
m_fmRFModeHang = m_conf.getFMModeHang();
|
m_fmRFModeHang = m_conf.getFMModeHang();
|
||||||
|
|
||||||
m_fm = new CFMControl(m_fmNetwork, txAudioGain, rxAudioGain, preEmphasis, deEmphasis);
|
m_fm = new CFMControl(m_fmNetwork, txAudioGain, rxAudioGain, preEmphasis, deEmphasis, rssi);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1119,7 +1118,7 @@ int CMMDVMHost::run()
|
|||||||
if (m_mode == MODE_IDLE || m_mode == MODE_FM) {
|
if (m_mode == MODE_IDLE || m_mode == MODE_FM) {
|
||||||
m_ax25->writeModem(data, len);
|
m_ax25->writeModem(data, len);
|
||||||
} else if (m_mode != MODE_LOCKOUT) {
|
} else if (m_mode != MODE_LOCKOUT) {
|
||||||
LogWarning("NXDN modem data received when in mode %u", m_mode);
|
LogWarning("AX.25 modem data received when in mode %u", m_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
37
Modem.cpp
37
Modem.cpp
@@ -98,6 +98,7 @@ const unsigned char MMDVM_POCSAG_DATA = 0x50U;
|
|||||||
|
|
||||||
#if defined(USE_AX25)
|
#if defined(USE_AX25)
|
||||||
const unsigned char MMDVM_AX25_DATA = 0x55U;
|
const unsigned char MMDVM_AX25_DATA = 0x55U;
|
||||||
|
const unsigned char MMDVM_AX25_DATA_EX = 0x56U;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_FM)
|
#if defined(USE_FM)
|
||||||
@@ -108,6 +109,7 @@ const unsigned char MMDVM_FM_PARAMS4 = 0x63U;
|
|||||||
const unsigned char MMDVM_FM_DATA = 0x65U;
|
const unsigned char MMDVM_FM_DATA = 0x65U;
|
||||||
const unsigned char MMDVM_FM_STATUS = 0x66U;
|
const unsigned char MMDVM_FM_STATUS = 0x66U;
|
||||||
const unsigned char MMDVM_FM_EOT = 0x67U;
|
const unsigned char MMDVM_FM_EOT = 0x67U;
|
||||||
|
const unsigned char MMDVM_FM_RSSI = 0x68U;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const unsigned char MMDVM_ACK = 0x70U;
|
const unsigned char MMDVM_ACK = 0x70U;
|
||||||
@@ -929,6 +931,20 @@ void CModem::clock(unsigned int ms)
|
|||||||
m_rxFMData.addData(m_buffer + m_offset, m_length - m_offset);
|
m_rxFMData.addData(m_buffer + m_offset, m_length - m_offset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MMDVM_FM_RSSI: {
|
||||||
|
if(m_trace)
|
||||||
|
CUtils::dump(1U, "RX FM RSSI", m_buffer, m_length);
|
||||||
|
|
||||||
|
unsigned int data1 = m_length - m_offset + 1U;
|
||||||
|
m_rxFMData.addData((unsigned char*)&data1, sizeof(unsigned int));
|
||||||
|
|
||||||
|
unsigned char data2 = TAG_RSSI;
|
||||||
|
m_rxFMData.addData(&data2, 1U);
|
||||||
|
|
||||||
|
m_rxFMData.addData(m_buffer + m_offset, m_length - m_offset);
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_AX25)
|
#if defined(USE_AX25)
|
||||||
@@ -936,8 +952,25 @@ void CModem::clock(unsigned int ms)
|
|||||||
if (m_trace)
|
if (m_trace)
|
||||||
CUtils::dump(1U, "RX AX.25 Data", m_buffer, m_length);
|
CUtils::dump(1U, "RX AX.25 Data", m_buffer, m_length);
|
||||||
|
|
||||||
unsigned int data = m_length - m_offset;
|
unsigned int data1 = m_length - m_offset + 1U;
|
||||||
m_rxAX25Data.addData((unsigned char*)&data, sizeof(unsigned int));
|
m_rxAX25Data.addData((unsigned char*)&data1, sizeof(unsigned int));
|
||||||
|
|
||||||
|
unsigned char data2 = TAG_DATA;
|
||||||
|
m_rxFMData.addData(&data2, 1U);
|
||||||
|
|
||||||
|
m_rxAX25Data.addData(m_buffer + m_offset, m_length - m_offset);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MMDVM_AX25_DATA_EX: {
|
||||||
|
if (m_trace)
|
||||||
|
CUtils::dump(1U, "RX AX.25 Data Extended", m_buffer, m_length);
|
||||||
|
|
||||||
|
unsigned int data1 = m_length - m_offset + 1U;
|
||||||
|
m_rxAX25Data.addData((unsigned char*)&data1, sizeof(unsigned int));
|
||||||
|
|
||||||
|
unsigned char data2 = TAG_RSSI;
|
||||||
|
m_rxFMData.addData(&data2, 1U);
|
||||||
|
|
||||||
m_rxAX25Data.addData(m_buffer + m_offset, m_length - m_offset);
|
m_rxAX25Data.addData(m_buffer + m_offset, m_length - m_offset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,6 @@
|
|||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20230730";
|
const char* VERSION = "20230804";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -198,6 +198,8 @@
|
|||||||
},
|
},
|
||||||
"type": {"$ref": "#/$defs/ax25_type"},
|
"type": {"$ref": "#/$defs/ax25_type"},
|
||||||
"pid": {"$ref": "#/$defs/ax25_pid"},
|
"pid": {"$ref": "#/$defs/ax25_pid"},
|
||||||
|
"rssi": {"$ref": "#/$defs/rssi"},
|
||||||
|
"ber": {"$ref": "#/$defs/ber"},
|
||||||
"data": {"type": "string"},
|
"data": {"type": "string"},
|
||||||
"required": ["timestamp", "source", "destination", "source", "type"]
|
"required": ["timestamp", "source", "destination", "source", "type"]
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user