mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-23 00:35:53 +08:00
Add FM to JSON/MQTT.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2020,2021,2023 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FMControl.h"
|
#include "FMControl.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -31,6 +32,19 @@ const float PREEMPHASIS_GAIN_DB = 0.0F; // Audio gain adjustment
|
|||||||
const float FILTER_GAIN_DB = 2.0F; // Audio gain adjustment
|
const float FILTER_GAIN_DB = 2.0F; // Audio gain adjustment
|
||||||
const unsigned int FM_MASK = 0x00000FFFU;
|
const unsigned int FM_MASK = 0x00000FFFU;
|
||||||
|
|
||||||
|
const unsigned char FS_LISTENING = 0U;
|
||||||
|
const unsigned char FS_KERCHUNK_RF = 1U;
|
||||||
|
const unsigned char FS_RELAYING_RF = 2U;
|
||||||
|
const unsigned char FS_RELAYING_WAIT_RF = 3U;
|
||||||
|
const unsigned char FS_TIMEOUT_RF = 4U;
|
||||||
|
const unsigned char FS_TIMEOUT_WAIT_RF = 5U;
|
||||||
|
const unsigned char FS_KERCHUNK_EXT = 6U;
|
||||||
|
const unsigned char FS_RELAYING_EXT = 7U;
|
||||||
|
const unsigned char FS_RELAYING_WAIT_EXT = 8U;
|
||||||
|
const unsigned char FS_TIMEOUT_EXT = 9U;
|
||||||
|
const unsigned char FS_TIMEOUT_WAIT_EXT = 10U;
|
||||||
|
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) :
|
||||||
m_network(network),
|
m_network(network),
|
||||||
m_txAudioGain(txAudioGain),
|
m_txAudioGain(txAudioGain),
|
||||||
@@ -75,8 +89,25 @@ bool CFMControl::writeModem(const unsigned char* data, unsigned int length)
|
|||||||
if (m_network == NULL)
|
if (m_network == NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (data[0U] == TAG_HEADER)
|
if (data[0U] == TAG_HEADER) {
|
||||||
|
switch (data[1U]) {
|
||||||
|
case FS_LISTENING: writeJSON("listening"); break;
|
||||||
|
case FS_KERCHUNK_RF: writeJSON("kerchunk_rf"); break;
|
||||||
|
case FS_RELAYING_RF: writeJSON("relaying_rf"); break;
|
||||||
|
case FS_RELAYING_WAIT_RF: writeJSON("relaying_wait_rf"); break;
|
||||||
|
case FS_TIMEOUT_RF: writeJSON("timeout_rf"); break;
|
||||||
|
case FS_TIMEOUT_WAIT_RF: writeJSON("timeout_wait_rf"); break;
|
||||||
|
case FS_KERCHUNK_EXT: writeJSON("kerchunk_ext"); break;
|
||||||
|
case FS_RELAYING_EXT: writeJSON("relaying_ext"); break;
|
||||||
|
case FS_RELAYING_WAIT_EXT: writeJSON("relaying_wait_ext"); break;
|
||||||
|
case FS_TIMEOUT_EXT: writeJSON("timeout_ext"); break;
|
||||||
|
case FS_TIMEOUT_WAIT_EXT: writeJSON("timeout_wait_ext"); break;
|
||||||
|
case FS_HANG: writeJSON("hang"); break;
|
||||||
|
default: writeJSON("unknown"); break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (data[0U] == TAG_EOT)
|
if (data[0U] == TAG_EOT)
|
||||||
return m_network->writeEnd();
|
return m_network->writeEnd();
|
||||||
@@ -190,3 +221,16 @@ void CFMControl::enable(bool enabled)
|
|||||||
{
|
{
|
||||||
// May not be needed
|
// May not be needed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CFMControl::writeJSON(const char* state)
|
||||||
|
{
|
||||||
|
assert(state != NULL);
|
||||||
|
|
||||||
|
nlohmann::json json;
|
||||||
|
|
||||||
|
json["timestamp"] = CUtils::createTimestamp();
|
||||||
|
json["state"] = state;
|
||||||
|
|
||||||
|
WriteJSON("FM", json);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2020,2021,2023 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
#include "IIRDirectForm1Filter.h"
|
#include "IIRDirectForm1Filter.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
// Uncomment this to dump audio to a raw audio file
|
// Uncomment this to dump audio to a raw audio file
|
||||||
// The file will be written in same folder as executable
|
// The file will be written in same folder as executable
|
||||||
// Toplay the file : ffplay -autoexit -f u16be -ar 8000 audiodump.bin
|
// Toplay the file : ffplay -autoexit -f u16be -ar 8000 audiodump.bin
|
||||||
@@ -54,6 +56,9 @@ private:
|
|||||||
CIIRDirectForm1Filter* m_filterStage1;
|
CIIRDirectForm1Filter* m_filterStage1;
|
||||||
CIIRDirectForm1Filter* m_filterStage2;
|
CIIRDirectForm1Filter* m_filterStage2;
|
||||||
CIIRDirectForm1Filter* m_filterStage3;
|
CIIRDirectForm1Filter* m_filterStage3;
|
||||||
|
|
||||||
|
void writeJSON(const char* state);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
12
Modem.cpp
12
Modem.cpp
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2018,2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2011-2018,2020,2021,2023 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -89,7 +89,7 @@ const unsigned char MMDVM_FM_PARAMS2 = 0x61U;
|
|||||||
const unsigned char MMDVM_FM_PARAMS3 = 0x62U;
|
const unsigned char MMDVM_FM_PARAMS3 = 0x62U;
|
||||||
const unsigned char MMDVM_FM_PARAMS4 = 0x63U;
|
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_CONTROL = 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_ACK = 0x70U;
|
const unsigned char MMDVM_ACK = 0x70U;
|
||||||
@@ -730,9 +730,9 @@ void CModem::clock(unsigned int ms)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MMDVM_FM_CONTROL: {
|
case MMDVM_FM_STATUS: {
|
||||||
if (m_trace)
|
if (m_trace)
|
||||||
CUtils::dump(1U, "RX FM Control", m_buffer, m_length);
|
CUtils::dump(1U, "RX FM Status", m_buffer, m_length);
|
||||||
|
|
||||||
unsigned int data1 = m_length - m_offset + 1U;
|
unsigned int data1 = m_length - m_offset + 1U;
|
||||||
m_rxFMData.addData((unsigned char*)&data1, sizeof(unsigned int));
|
m_rxFMData.addData((unsigned char*)&data1, sizeof(unsigned int));
|
||||||
@@ -1093,8 +1093,8 @@ void CModem::clock(unsigned int ms)
|
|||||||
m_txFMData.getData(m_buffer, len);
|
m_txFMData.getData(m_buffer, len);
|
||||||
|
|
||||||
if (m_trace) {
|
if (m_trace) {
|
||||||
if (m_buffer[2U] == MMDVM_FM_CONTROL)
|
if (m_buffer[2U] == MMDVM_FM_STATUS)
|
||||||
CUtils::dump(1U, "TX FM Control", m_buffer, len);
|
CUtils::dump(1U, "TX FM Status", m_buffer, len);
|
||||||
else
|
else
|
||||||
CUtils::dump(1U, "TX FM Data", m_buffer, len);
|
CUtils::dump(1U, "TX FM Data", m_buffer, len);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"ax25_type": {"type": "string", "enum": ["sabm", "disc", "ui", "ua", "rr", "rnr", "rej", "frmr", "i"]},
|
"ax25_type": {"type": "string", "enum": ["sabm", "disc", "ui", "ua", "rr", "rnr", "rej", "frmr", "i"]},
|
||||||
"dmr_slot": {"type": "integer", "enum": [1, 2]},
|
"dmr_slot": {"type": "integer", "enum": [1, 2]},
|
||||||
"source": {"type": "string", "enum": ["rf", "network"]},
|
"source": {"type": "string", "enum": ["rf", "network"]},
|
||||||
"fm_state": {"type": "string", "enum": ["waiting_rf", "waiting_network"]},
|
"fm_state": {"type": "string", "enum": ["listening", "kerchunk_rf", "relaying_rf", "relaying_wait_rf", "timeout_rf", "timeout_wait_rf", "kerchunk_ext", "relaying_ext", "relaying_wait_ext", "timeout_ext", "timeout_wait_ext", "hang", "unknown"]},
|
||||||
"m17_traffic_type": {"type": "string", "enum": ["audio", "audio_data", "data"]},
|
"m17_traffic_type": {"type": "string", "enum": ["audio", "audio_data", "data"]},
|
||||||
"ax25_pid": {"type": "string"},
|
"ax25_pid": {"type": "string"},
|
||||||
"pocsag_source": {"type": "string", "enum": ["local", "network"]},
|
"pocsag_source": {"type": "string", "enum": ["local", "network"]},
|
||||||
|
|||||||
Reference in New Issue
Block a user