diff --git a/Conf.cpp b/Conf.cpp index 5bdd518..3b1ef41 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -92,6 +92,7 @@ m_modemYSFTXLevel(50U), m_modemP25TXLevel(50U), m_modemOscOffset(0), m_modemRSSIMappingFile(), +m_modemSamplesDir(), m_modemDebug(false), m_umpEnabled(false), m_umpPort(), @@ -331,6 +332,8 @@ bool CConf::read() m_modemOscOffset = ::atoi(value); else if (::strcmp(key, "RSSIMappingFile") == 0) m_modemRSSIMappingFile = value; + else if (::strcmp(key, "SamplesDir") == 0) + m_modemSamplesDir = value; else if (::strcmp(key, "Debug") == 0) m_modemDebug = ::atoi(value) == 1; } else if (section == SECTION_UMP) { @@ -746,6 +749,11 @@ std::string CConf::getModemRSSIMappingFile () const return m_modemRSSIMappingFile; } +std::string CConf::getModemSamplesDir() const +{ + return m_modemSamplesDir; +} + bool CConf::getModemDebug() const { return m_modemDebug; diff --git a/Conf.h b/Conf.h index d158130..4983643 100644 --- a/Conf.h +++ b/Conf.h @@ -79,6 +79,7 @@ public: unsigned int getModemP25TXLevel() const; int getModemOscOffset() const; std::string getModemRSSIMappingFile() const; + std::string getModemSamplesDir() const; bool getModemDebug() const; // The UMP section @@ -230,6 +231,7 @@ private: unsigned int m_modemP25TXLevel; int m_modemOscOffset; std::string m_modemRSSIMappingFile; + std::string m_modemSamplesDir; bool m_modemDebug; bool m_umpEnabled; diff --git a/MMDVM.ini b/MMDVM.ini index 4d899a3..2d990a8 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -51,6 +51,7 @@ TXLevel=50 # P25TXLevel=50 OscOffset=0 RSSIMappingFile=RSSI.dat +SamplesDir= Debug=0 [UMP] diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index d568199..a648007 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -795,6 +795,7 @@ bool CMMDVMHost::createModem() unsigned int rxFrequency = m_conf.getRxFrequency(); unsigned int txFrequency = m_conf.getTxFrequency(); int oscOffset = m_conf.getModemOscOffset(); + std::string samplesDir = m_conf.getModemSamplesDir(); LogInfo("Modem Parameters"); LogInfo(" Port: %s", port.c_str()); @@ -811,10 +812,9 @@ bool CMMDVMHost::createModem() LogInfo(" P25 TX Level: %u%%", p25TXLevel); LogInfo(" RX Frequency: %uHz", rxFrequency); LogInfo(" TX Frequency: %uHz", txFrequency); - LogInfo(" Osc. Offset: %dppm", oscOffset); - m_modem = new CModem(port, m_duplex, rxInvert, txInvert, pttInvert, txDelay, dmrDelay, oscOffset, debug); + m_modem = new CModem(port, m_duplex, rxInvert, txInvert, pttInvert, txDelay, dmrDelay, oscOffset, samplesDir, debug); m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled); m_modem->setLevels(rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel); m_modem->setRFParams(rxFrequency, txFrequency); diff --git a/Modem.cpp b/Modem.cpp index d4429e0..7c3c631 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #if defined(_WIN32) || defined(_WIN64) #include @@ -71,7 +72,8 @@ const unsigned char MMDVM_NAK = 0x7FU; const unsigned char MMDVM_SERIAL = 0x80U; -const unsigned char MMDVM_SAMPLES = 0xF0U; +const unsigned char MMDVM_SAMPLES = 0xEFU; +const unsigned char MMDVM_SYNC_SAMPLES = 0xF0U; const unsigned char MMDVM_DEBUG1 = 0xF1U; const unsigned char MMDVM_DEBUG2 = 0xF2U; @@ -81,10 +83,10 @@ const unsigned char MMDVM_DEBUG5 = 0xF5U; const unsigned int MAX_RESPONSES = 30U; -const unsigned int BUFFER_LENGTH = 500U; +const unsigned int BUFFER_LENGTH = 2000U; -CModem::CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, int oscOffset, bool debug) : +CModem::CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, int oscOffset, const std::string& samplesDir, bool debug) : m_port(port), m_colorCode(0U), m_duplex(duplex), @@ -100,6 +102,7 @@ m_dmrTXLevel(0U), m_ysfTXLevel(0U), m_p25TXLevel(0U), m_oscOffset(oscOffset), +m_samplesDir(samplesDir), m_debug(debug), m_rxFrequency(0U), m_txFrequency(0U), @@ -474,7 +477,11 @@ void CModem::clock(unsigned int ms) break; case MMDVM_SAMPLES: - printSamples(); + dumpSamples(); + break; + + case MMDVM_SYNC_SAMPLES: + printSyncSamples(); break; default: @@ -1128,6 +1135,22 @@ RESP_TYPE_MMDVM CModem::getResponse() } if (m_offset >= 3U) { + // Use later two byte length field + if (m_length == 0U) { + int ret = m_serial.read(m_buffer + 3U, 2U); + if (ret < 0) { + LogError("Error when reading from the modem"); + m_offset = 0U; + return RTM_ERROR; + } + + if (ret == 0) + return RTM_TIMEOUT; + + m_length = (m_buffer[3U] << 8) | m_buffer[4U]; + m_offset = 5U; + } + while (m_offset < m_length) { int ret = m_serial.read(m_buffer + m_offset, m_length - m_offset); if (ret < 0) { @@ -1277,7 +1300,7 @@ void CModem::printDebug() } } -void CModem::printSamples() +void CModem::printSyncSamples() { const char* mode = NULL; switch (m_buffer[3U]) { @@ -1287,12 +1310,12 @@ void CModem::printSamples() case MODE_DMR: mode = "DMR"; break; - case MODE_YSF: - mode = "YSF"; - break; case MODE_P25: mode = "P25"; break; + case MODE_YSF: + mode = "YSF"; + break; default: mode = "???"; break; @@ -1301,7 +1324,7 @@ void CModem::printSamples() char samples[250U]; samples[0U] = '\0'; - unsigned char n = (m_buffer[1U] - 4U) / 2U; + unsigned char n = (m_length - 4U) / 2U; for (unsigned char i = 0U; i < n; i++) { unsigned char index = i * 2U + 4U; @@ -1311,5 +1334,52 @@ void CModem::printSamples() ::sprintf(samples + ::strlen(samples), " %d", val - 2048); } - LogMessage("Debug: Samples dump: %s:%s", mode, samples); + LogMessage("Debug: Sync Samples dump: %s:%s", mode, samples); +} + +void CModem::dumpSamples() +{ + if (m_samplesDir.empty()) + m_samplesDir = "."; + + time_t now; + ::time(&now); + + struct tm* tm = ::localtime(&now); + + char* mode = NULL; + switch (m_buffer[5U]) { + case MODE_DSTAR: + mode = "DStar"; + break; + case MODE_DMR: + mode = "DMR"; + break; + case MODE_P25: + mode = "P25"; + break; + case MODE_YSF: + mode = "YSF"; + break; + default: + LogWarning("Unknown protocol passed to samples dump - %u", m_buffer[5U]); + return; + } + + char filename[150U]; +#if defined(_WIN32) || defined(_WIN64) + ::sprintf(filename, "%s\\Samples-%s-%04d%02d%02d.dat", m_samplesDir.c_str(), mode, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); +#else + ::sprintf(filename, "%s/Samples-%s-%04d%02d%02d.dat", m_samplesDir.c_str(), mode, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); +#endif + + FILE* fp = ::fopen(filename, "a+b"); + if (fp == NULL) { + LogWarning("Unable to open samples file for writing - %s", filename); + return; + } + + ::fwrite(m_buffer + 6U, 1U, m_length, fp); + + ::fclose(fp); } diff --git a/Modem.h b/Modem.h index a4d2afd..dfb602d 100644 --- a/Modem.h +++ b/Modem.h @@ -34,7 +34,7 @@ enum RESP_TYPE_MMDVM { class CModem { public: - CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, int oscOffset, bool debug = false); + CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, int oscOffset, const std::string& samplesDir, bool debug = false); ~CModem(); void setRFParams(unsigned int rxFrequency, unsigned int txFrequency); @@ -102,6 +102,7 @@ private: unsigned int m_ysfTXLevel; unsigned int m_p25TXLevel; int m_oscOffset; + std::string m_samplesDir; bool m_debug; unsigned int m_rxFrequency; unsigned int m_txFrequency; @@ -143,7 +144,8 @@ private: bool setFrequency(); void printDebug(); - void printSamples(); + void printSyncSamples(); + void dumpSamples(); RESP_TYPE_MMDVM getResponse(); };