diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index 628c50c..d4d5e29 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -180,6 +180,7 @@
+
@@ -234,6 +235,7 @@
+
diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters
index df153d8..cc105c8 100644
--- a/Common/Common.vcxproj.filters
+++ b/Common/Common.vcxproj.filters
@@ -155,6 +155,9 @@
Source Files
+
+ Source Files
+
@@ -322,5 +325,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/Common/IcomController.cpp b/Common/IcomController.cpp
new file mode 100644
index 0000000..956069b
--- /dev/null
+++ b/Common/IcomController.cpp
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 2011-2015,2018 by Jonathan Naylor G4KLX
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "CCITTChecksumReverse.h"
+#include "IcomController.h"
+#include "CCITTChecksum.h"
+#include "DStarDefines.h"
+#include "Timer.h"
+#include "Utils.h"
+
+#if defined(__WINDOWS__)
+#include
+#else
+#include
+#endif
+
+const unsigned char ICOM_FRAME_START = 0xFFU;
+
+const unsigned int MAX_RESPONSES = 30U;
+
+const unsigned int BUFFER_LENGTH = 200U;
+
+CIcomController::CIcomController(const wxString& port) :
+CModem(),
+m_port(port),
+m_serial(port, SERIAL_38400, true),
+m_buffer(NULL),
+m_txData(1000U),
+m_txCounter(0U),
+m_pktCounter(0U),
+m_rx(false),
+m_txSpace(0U),
+m_txEnabled(false),
+m_checksum(false)
+{
+ wxASSERT(!port.IsEmpty());
+
+ m_buffer = new unsigned char[BUFFER_LENGTH];
+}
+
+CIcomController::~CIcomController()
+{
+ delete[] m_buffer;
+}
+
+bool CIcomController::start()
+{
+ bool ret = m_serial.open();
+ if (!ret)
+ return false;
+
+ Create();
+ SetPriority(100U);
+ Run();
+
+ return true;
+}
+
+void* CIcomController::Entry()
+{
+ wxLogMessage(wxT("Starting Icom Controller thread"));
+
+ // Clock every 5ms-ish
+ CTimer pollTimer(200U, 0U, 100U);
+ pollTimer.start();
+
+ while (!m_stopped) {
+ // Poll the modem status every 100ms
+ if (pollTimer.hasExpired()) {
+ m_serial.write((unsigned char*)"\xFF\xFF\xFF", 3U);
+ pollTimer.start();
+ }
+
+ unsigned int length;
+ RESP_TYPE_ICOM type = getResponse(m_buffer, length);
+
+ switch (type) {
+ case RTI_TIMEOUT:
+ break;
+
+ case RTI_ERROR: {
+ wxLogMessage(wxT("Stopping Icom Controller thread"));
+ return NULL;
+
+ case RTI_HEADER: {
+ CUtils::dump(wxT("RT_HEADER"), m_buffer, length);
+
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char data[2U];
+ data[0U] = DSMTT_HEADER;
+ data[1U] = RADIO_HEADER_LENGTH_BYTES;
+ m_rxData.addData(data, 2U);
+
+ m_rxData.addData(m_buffer + 3U, RADIO_HEADER_LENGTH_BYTES);
+
+ m_rx = true;
+ }
+ break;
+
+ case RTI_DATA: {
+ CUtils::dump(wxT("RT_DATA"), m_buffer, length);
+
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char data[2U];
+ data[0U] = DSMTT_DATA;
+ data[1U] = DV_FRAME_LENGTH_BYTES;
+ m_rxData.addData(data, 2U);
+
+ m_rxData.addData(m_buffer + 5U, DV_FRAME_LENGTH_BYTES);
+
+ m_rx = true;
+ }
+ break;
+
+ default:
+ wxLogMessage(wxT("Unknown message, type: %02X"), m_buffer[3U]);
+ CUtils::dump(wxT("Buffer dump"), m_buffer, length);
+ break;
+ }
+
+#ifdef notdef
+ if (space > 0U) {
+ if (writeType == DSMTT_NONE && m_txData.hasData()) {
+ wxMutexLocker locker(m_mutex);
+
+ m_txData.getData(&writeType, 1U);
+ m_txData.getData(&writeLength, 1U);
+ m_txData.getData(writeBuffer, writeLength);
+ }
+
+ // Only send the start when the TX is off
+ if (!m_tx && writeType == DSMTT_START) {
+ // CUtils::dump(wxT("Write Header"), writeBuffer, writeLength);
+
+ int ret = m_serial.write(writeBuffer, writeLength);
+ if (ret != int(writeLength))
+ wxLogWarning(wxT("Error when writing the header to the Icom"));
+
+ writeType = DSMTT_NONE;
+ space--;
+ }
+
+ if (space > 4U && writeType == DSMTT_HEADER) {
+ // CUtils::dump(wxT("Write Header"), writeBuffer, writeLength);
+
+ int ret = m_serial.write(writeBuffer, writeLength);
+ if (ret != int(writeLength))
+ wxLogWarning(wxT("Error when writing the header to the Icom"));
+
+ writeType = DSMTT_NONE;
+ space -= 4U;
+ }
+
+ if (writeType == DSMTT_DATA || writeType == DSMTT_EOT) {
+ // CUtils::dump(wxT("Write Data"), writeBuffer, writeLength);
+
+ int ret = m_serial.write(writeBuffer, writeLength);
+ if (ret != int(writeLength))
+ wxLogWarning(wxT("Error when writing data to the Icom"));
+
+ writeType = DSMTT_NONE;
+ space--;
+ }
+#endif
+ }
+
+ Sleep(5UL);
+
+ pollTimer.clock();
+ }
+
+ m_serial.close();
+
+ wxLogMessage(wxT("Stopping Icom Controller thread"));
+
+ return NULL;
+}
+
+#ifdef notdef
+void* CIcomController::Entry()
+{
+ wxLogMessage(wxT("Starting Icom Controller thread"));
+
+ // Clock every 5ms-ish
+ CTimer pollTimer(200U, 0U, 100U);
+ pollTimer.start();
+
+ unsigned char writeType = DSMTT_NONE;
+ unsigned char writeLength = 0U;
+ unsigned char* writeBuffer = new unsigned char[BUFFER_LENGTH];
+
+ unsigned int space = 0U;
+
+ while (!m_stopped) {
+ // Poll the modem status every 100ms
+ if (pollTimer.hasExpired()) {
+ bool ret = readStatus();
+ if (!ret) {
+ ret = findModem();
+ if (!ret) {
+ wxLogMessage(wxT("Stopping Icom Controller thread"));
+ return NULL;
+ }
+ }
+
+ pollTimer.start();
+ }
+
+ unsigned int length;
+ RESP_TYPE_MEGA type = getResponse(m_buffer, length);
+
+ switch (type) {
+ case RTM_TIMEOUT:
+ break;
+
+ case RTM_ERROR: {
+ bool ret = findModem();
+ if (!ret) {
+ wxLogMessage(wxT("Stopping Icom Controller thread"));
+ return NULL;
+ }
+ }
+ break;
+
+ case RTM_RXPREAMBLE:
+ // wxLogMessage(wxT("RT_PREAMBLE"));
+ break;
+
+ case RTM_START:
+ // wxLogMessage(wxT("RT_START"));
+ break;
+
+ case RTM_HEADER:
+ CUtils::dump(wxT("RT_HEADER"), m_buffer, length);
+ if (length == 7U) {
+ if (m_buffer[4U] == DVRPTR_NAK)
+ wxLogWarning(wxT("Received a header NAK from the Icom"));
+ } else {
+ bool correct = (m_buffer[5U] & 0x80U) == 0x00U;
+ if (correct) {
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char data[2U];
+ data[0U] = DSMTT_HEADER;
+ data[1U] = RADIO_HEADER_LENGTH_BYTES;
+ m_rxData.addData(data, 2U);
+
+ m_rxData.addData(m_buffer + 8U, RADIO_HEADER_LENGTH_BYTES);
+
+ m_rx = true;
+ }
+ }
+ break;
+
+ case RTM_RXSYNC:
+ // wxLogMessage(wxT("RT_RXSYNC"));
+ break;
+
+ case RTM_DATA:
+ CUtils::dump(wxT("RT_DATA"), m_buffer, length);
+ if (length == 7U) {
+ if (m_buffer[4U] == DVRPTR_NAK)
+ wxLogWarning(wxT("Received a data NAK from the Icom"));
+ } else {
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char data[2U];
+ data[0U] = DSMTT_DATA;
+ data[1U] = DV_FRAME_LENGTH_BYTES;
+ m_rxData.addData(data, 2U);
+
+ m_rxData.addData(m_buffer + 8U, DV_FRAME_LENGTH_BYTES);
+
+ m_rx = true;
+ }
+ break;
+
+ case RTM_EOT: {
+ wxLogMessage(wxT("RT_EOT"));
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char data[2U];
+ data[0U] = DSMTT_EOT;
+ data[1U] = 0U;
+ m_rxData.addData(data, 2U);
+
+ m_rx = false;
+ }
+ break;
+
+ case RTM_RXLOST: {
+ wxLogMessage(wxT("RT_LOST"));
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char data[2U];
+ data[0U] = DSMTT_LOST;
+ data[1U] = 0U;
+ m_rxData.addData(data, 2U);
+
+ m_rx = false;
+ }
+ break;
+
+ case RTM_GET_STATUS: {
+ m_txEnabled = (m_buffer[4U] & 0x02U) == 0x02U;
+ m_checksum = (m_buffer[4U] & 0x08U) == 0x08U;
+ m_tx = (m_buffer[5U] & 0x02U) == 0x02U;
+ m_txSpace = m_buffer[8U];
+ space = m_txSpace - m_buffer[9U];
+ // CUtils::dump(wxT("GET_STATUS"), m_buffer, length);
+ // wxLogMessage(wxT("PTT=%d tx=%u space=%u cksum=%d, tx enabled=%d"), int(m_tx), m_txSpace, space, int(m_checksum), int(m_txEnabled));
+ }
+ break;
+
+ // These should not be received in this loop, but don't complain if we do
+ case RTM_GET_VERSION:
+ case RTM_GET_SERIAL:
+ case RTM_GET_CONFIG:
+ break;
+
+ default:
+ wxLogMessage(wxT("Unknown message, type: %02X"), m_buffer[3U]);
+ CUtils::dump(wxT("Buffer dump"), m_buffer, length);
+ break;
+ }
+
+ if (space > 0U) {
+ if (writeType == DSMTT_NONE && m_txData.hasData()) {
+ wxMutexLocker locker(m_mutex);
+
+ m_txData.getData(&writeType, 1U);
+ m_txData.getData(&writeLength, 1U);
+ m_txData.getData(writeBuffer, writeLength);
+ }
+
+ // Only send the start when the TX is off
+ if (!m_tx && writeType == DSMTT_START) {
+ // CUtils::dump(wxT("Write Header"), writeBuffer, writeLength);
+
+ int ret = m_serial.write(writeBuffer, writeLength);
+ if (ret != int(writeLength))
+ wxLogWarning(wxT("Error when writing the header to the Icom"));
+
+ writeType = DSMTT_NONE;
+ space--;
+ }
+
+ if (space > 4U && writeType == DSMTT_HEADER) {
+ // CUtils::dump(wxT("Write Header"), writeBuffer, writeLength);
+
+ int ret = m_serial.write(writeBuffer, writeLength);
+ if (ret != int(writeLength))
+ wxLogWarning(wxT("Error when writing the header to the Icom"));
+
+ writeType = DSMTT_NONE;
+ space -= 4U;
+ }
+
+ if (writeType == DSMTT_DATA || writeType == DSMTT_EOT) {
+ // CUtils::dump(wxT("Write Data"), writeBuffer, writeLength);
+
+ int ret = m_serial.write(writeBuffer, writeLength);
+ if (ret != int(writeLength))
+ wxLogWarning(wxT("Error when writing data to the Icom"));
+
+ writeType = DSMTT_NONE;
+ space--;
+ }
+ }
+
+ Sleep(5UL);
+
+ pollTimer.clock();
+ }
+
+ wxLogMessage(wxT("Stopping Icom Controller thread"));
+
+ setEnabled(false);
+
+ delete[] writeBuffer;
+
+ m_serial.close();
+
+ return NULL;
+}
+#endif
+
+bool CIcomController::writeHeader(const CHeaderData& header)
+{
+#ifdef notdef
+ if (!m_txEnabled)
+ return false;
+
+ bool ret = m_txData.hasSpace(64U);
+ if (!ret) {
+ wxLogWarning(wxT("No space to write the header"));
+ return false;
+ }
+
+ m_txCounter++;
+ if (m_txCounter == 0U)
+ m_txCounter = 1U;
+
+ unsigned char buffer1[10U];
+
+ buffer1[0U] = DVRPTR_FRAME_START;
+
+ buffer1[1U] = 0x03U;
+ buffer1[2U] = 0x00U;
+
+ buffer1[3U] = DVRPTR_START;
+
+ buffer1[4U] = m_txCounter;
+ buffer1[5U] = 0x00U;
+
+ if (m_checksum) {
+ CCCITTChecksum cksum;
+ cksum.update(buffer1 + 0U, 6U);
+ cksum.result(buffer1 + 6U);
+ } else {
+ buffer1[6U] = 0x00U;
+ buffer1[7U] = 0x0BU;
+ }
+
+ unsigned char buffer2[60U];
+
+ buffer2[0U] = DVRPTR_FRAME_START;
+
+ buffer2[1U] = 0x2FU;
+ buffer2[2U] = 0x00U;
+
+ buffer2[3U] = DVRPTR_HEADER;
+
+ buffer2[4U] = m_txCounter;
+ buffer2[5U] = 0x00U;
+
+ buffer2[6U] = 0x00U;
+ buffer2[7U] = 0x00U;
+
+ ::memset(buffer2 + 8U, ' ', RADIO_HEADER_LENGTH_BYTES);
+
+ buffer2[8U] = header.getFlag1();
+ buffer2[9U] = header.getFlag2();
+ buffer2[10U] = header.getFlag3();
+
+ wxString rpt2 = header.getRptCall2();
+ for (unsigned int i = 0U; i < rpt2.Len() && i < LONG_CALLSIGN_LENGTH; i++)
+ buffer2[i + 11U] = rpt2.GetChar(i);
+
+ wxString rpt1 = header.getRptCall1();
+ for (unsigned int i = 0U; i < rpt1.Len() && i < LONG_CALLSIGN_LENGTH; i++)
+ buffer2[i + 19U] = rpt1.GetChar(i);
+
+ wxString your = header.getYourCall();
+ for (unsigned int i = 0U; i < your.Len() && i < LONG_CALLSIGN_LENGTH; i++)
+ buffer2[i + 27U] = your.GetChar(i);
+
+ wxString my1 = header.getMyCall1();
+ for (unsigned int i = 0U; i < my1.Len() && i < LONG_CALLSIGN_LENGTH; i++)
+ buffer2[i + 35U] = my1.GetChar(i);
+
+ wxString my2 = header.getMyCall2();
+ for (unsigned int i = 0U; i < my2.Len() && i < SHORT_CALLSIGN_LENGTH; i++)
+ buffer2[i + 43U] = my2.GetChar(i);
+
+ CCCITTChecksumReverse cksum1;
+ cksum1.update(buffer2 + 8U, RADIO_HEADER_LENGTH_BYTES - 2U);
+ cksum1.result(buffer2 + 47U);
+
+ buffer2[49U] = 0x00U;
+
+ if (m_checksum) {
+ CCCITTChecksum cksum;
+ cksum.update(buffer2 + 0U, 50U);
+ cksum.result(buffer2 + 50U);
+ } else {
+ buffer2[50U] = 0x00U;
+ buffer2[51U] = 0x0BU;
+ }
+
+ m_pktCounter = 0U;
+
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char type1 = DSMTT_START;
+ m_txData.addData(&type1, 1U);
+
+ unsigned char len1 = 8U;
+ m_txData.addData(&len1, 1U);
+
+ m_txData.addData(buffer1, 8U);
+
+ unsigned char type2 = DSMTT_HEADER;
+ m_txData.addData(&type2, 1U);
+
+ unsigned char len2 = 52U;
+ m_txData.addData(&len2, 1U);
+
+ m_txData.addData(buffer2, 52U);
+#endif
+ return true;
+}
+
+bool CIcomController::writeData(const unsigned char* data, unsigned int, bool end)
+{
+#ifdef notdef
+ if (!m_txEnabled)
+ return false;
+
+ bool ret = m_txData.hasSpace(26U);
+ if (!ret) {
+ wxLogWarning(wxT("No space to write data"));
+ return false;
+ }
+
+ unsigned char buffer[30U];
+
+ if (end) {
+ buffer[0U] = DVRPTR_FRAME_START;
+
+ buffer[1U] = 0x03U;
+ buffer[2U] = 0x00U;
+
+ buffer[3U] = DVRPTR_EOT;
+
+ buffer[4U] = m_txCounter;
+ buffer[5U] = 0xFFU;
+
+ if (m_checksum) {
+ CCCITTChecksum cksum;
+ cksum.update(buffer + 0U, 6U);
+ cksum.result(buffer + 6U);
+ } else {
+ buffer[6U] = 0x00U;
+ buffer[7U] = 0x0BU;
+ }
+
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char type = DSMTT_EOT;
+ m_txData.addData(&type, 1U);
+
+ unsigned char len = 8U;
+ m_txData.addData(&len, 1U);
+
+ m_txData.addData(buffer, 8U);
+
+ return true;
+ }
+
+ buffer[0U] = DVRPTR_FRAME_START;
+
+ buffer[1U] = 0x13U;
+ buffer[2U] = 0x00U;
+
+ buffer[3U] = DVRPTR_DATA;
+
+ buffer[4U] = m_txCounter;
+ buffer[5U] = m_pktCounter;
+
+ m_pktCounter++;
+ if (m_pktCounter >= m_txSpace)
+ m_pktCounter = 0U;
+
+ buffer[6U] = 0x00U;
+ buffer[7U] = 0x00U;
+
+ ::memcpy(buffer + 8U, data, DV_FRAME_LENGTH_BYTES);
+
+ buffer[20U] = 0x00U;
+ buffer[21U] = 0x00U;
+
+ if (m_checksum) {
+ CCCITTChecksum cksum;
+ cksum.update(buffer + 0U, 22U);
+ cksum.result(buffer + 22U);
+ } else {
+ buffer[22U] = 0x00U;
+ buffer[23U] = 0x0BU;
+ }
+
+ wxMutexLocker locker(m_mutex);
+
+ unsigned char type = DSMTT_DATA;
+ m_txData.addData(&type, 1U);
+
+ unsigned char len = 24U;
+ m_txData.addData(&len, 1U);
+
+ m_txData.addData(buffer, 24U);
+#endif
+ return true;
+}
+
+unsigned int CIcomController::getSpace()
+{
+ // return m_txData.freeSpace() / 26U;
+ return true;
+}
+
+bool CIcomController::isTXReady()
+{
+ return true;
+
+#ifdef notdef
+ if (m_tx)
+ return false;
+
+ return m_txData.isEmpty();
+#endif
+}
+
+wxString CIcomController::getPath() const
+{
+ return wxEmptyString;
+}
+
+RESP_TYPE_ICOM CIcomController::getResponse(unsigned char *buffer, unsigned int& length)
+{
+ // Get the start of the frame or nothing at all
+ int ret = m_serial.read(buffer, 1U);
+ if (ret < 0) {
+ wxLogError(wxT("Error when reading from the Icom radio"));
+ return RTI_ERROR;
+ }
+
+ if (ret == 0)
+ return RTI_TIMEOUT;
+
+ if (buffer[0U] != ICOM_FRAME_START)
+ return RTI_TIMEOUT;
+
+ do {
+ ret = m_serial.read(buffer + 1U, 1U);
+ if (ret < 0) {
+ wxLogError(wxT("Error when reading from the Icom radio"));
+ return RTI_ERROR;
+ }
+ if (ret == 0)
+ Sleep(5UL);
+ } while (ret == 0);
+
+ if (buffer[1U] == ICOM_FRAME_START)
+ return RTI_TIMEOUT;
+
+ length = buffer[1U] + 1U;
+
+ if (length >= 100U) {
+ wxLogError(wxT("Invalid data received from the Icom radio"));
+ return RTI_ERROR;
+ }
+
+ unsigned int offset = 2U;
+
+ while (offset < length) {
+ ret = m_serial.read(buffer + offset, length - offset);
+ if (ret < 0) {
+ wxLogError(wxT("Error when reading from the Icom radio"));
+ return RTI_ERROR;
+ }
+
+ if (ret > 0)
+ offset += ret;
+
+ if (ret == 0)
+ Sleep(5UL);
+ }
+
+ // CUtils::dump(wxT("Received"), buffer, length);
+
+ switch (length) {
+ case 45U:
+ return RTI_HEADER;
+ case 17U:
+ return RTI_DATA;
+ default:
+ return RTI_UNKNOWN;
+ }
+}
diff --git a/Common/IcomController.h b/Common/IcomController.h
new file mode 100644
index 0000000..8d43629
--- /dev/null
+++ b/Common/IcomController.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011-2015,2018 by Jonathan Naylor G4KLX
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef IcomController_H
+#define IcomController_H
+
+#include "SerialDataController.h"
+#include "RingBuffer.h"
+#include "Modem.h"
+#include "Utils.h"
+
+#include
+
+enum RESP_TYPE_ICOM {
+ RTI_TIMEOUT,
+ RTI_ERROR,
+ RTI_UNKNOWN,
+ RTI_HEADER,
+ RTI_DATA,
+ RTI_EOT
+};
+
+class CIcomController : public CModem {
+public:
+ CIcomController(const wxString& port);
+ virtual ~CIcomController();
+
+ virtual void* Entry();
+
+ virtual bool start();
+
+ virtual unsigned int getSpace();
+ virtual bool isTXReady();
+
+ virtual bool writeHeader(const CHeaderData& header);
+ virtual bool writeData(const unsigned char* data, unsigned int length, bool end);
+
+ virtual wxString getPath() const;
+
+private:
+ wxString m_port;
+ CSerialDataController m_serial;
+ unsigned char* m_buffer;
+ CRingBuffer m_txData;
+ unsigned char m_txCounter;
+ unsigned char m_pktCounter;
+ bool m_rx;
+ unsigned int m_txSpace;
+ bool m_txEnabled;
+ bool m_checksum;
+
+ RESP_TYPE_ICOM getResponse(unsigned char* buffer, unsigned int& length);
+};
+
+#endif
+
diff --git a/Common/Makefile b/Common/Makefile
index 104702c..d240a81 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -2,7 +2,7 @@ OBJECTS = AMBEFEC.o AnnouncementUnit.o ArduinoController.o BeaconUnit.o Callsign
DStarGMSKDemodulator.o DStarGMSKModulator.o DStarRepeaterConfig.o DStarScrambler.o DummyController.o DVAPController.o \
DVMegaController.o DVRPTRV1Controller.o DVRPTRV2Controller.o DVRPTRV3Controller.o DVTOOLFileReader.o DVTOOLFileWriter.o \
ExternalController.o FIRFilter.o GatewayProtocolHandler.o GMSKController.o GMSKModem.o GMSKModemLibUsb.o Golay.o \
- HardwareController.o HeaderData.o K8055Controller.o LogEvent.o Logger.o MMDVMController.o Modem.o OutputQueue.o \
+ HardwareController.o HeaderData.o IcomController.o K8055Controller.o LogEvent.o Logger.o MMDVMController.o Modem.o OutputQueue.o \
RepeaterProtocolHandler.o SerialDataController.o SerialLineController.o SerialPortSelector.o SlowDataDecoder.o SlowDataEncoder.o \
SoundCardController.o SoundCardReaderWriter.o SplitController.o TCPReaderWriter.o Timer.o UDPReaderWriter.o \
URIUSBController.o Utils.o
diff --git a/DStarRepeater/DStarRepeater.vcxproj b/DStarRepeater/DStarRepeater.vcxproj
index 9045988..48c4e35 100644
--- a/DStarRepeater/DStarRepeater.vcxproj
+++ b/DStarRepeater/DStarRepeater.vcxproj
@@ -172,7 +172,7 @@
-
+
@@ -184,7 +184,7 @@
-
+
diff --git a/DStarRepeater/DStarRepeater.vcxproj.filters b/DStarRepeater/DStarRepeater.vcxproj.filters
index 078751f..09f9945 100644
--- a/DStarRepeater/DStarRepeater.vcxproj.filters
+++ b/DStarRepeater/DStarRepeater.vcxproj.filters
@@ -17,9 +17,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -38,6 +35,9 @@
Source Files
+
+ Source Files
+
@@ -49,9 +49,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -70,5 +67,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/DStarRepeater/DStarRepeaterApp.cpp b/DStarRepeater/DStarRepeaterApp.cpp
index 1d811d3..6c8d15c 100644
--- a/DStarRepeater/DStarRepeaterApp.cpp
+++ b/DStarRepeater/DStarRepeaterApp.cpp
@@ -22,13 +22,13 @@
#include
#include
+#include "DStarRepeaterLogRedirect.h"
#include "DStarRepeaterTXRXThread.h"
#include "RepeaterProtocolHandler.h"
#include "DStarRepeaterTRXThread.h"
#include "DStarRepeaterTXThread.h"
#include "DStarRepeaterRXThread.h"
#include "SerialLineController.h"
-#include "DStarRepeaterLogger.h"
#include "DStarRepeaterThread.h"
#include "SoundCardController.h"
#include "DVRPTRV1Controller.h"
@@ -42,6 +42,7 @@
#include "K8055Controller.h"
#include "DummyController.h"
#include "SplitController.h"
+#include "IcomController.h"
#if defined(GPIO)
#include "GPIOController.h"
#include "UDRCController.h"
@@ -127,7 +128,7 @@ bool CDStarRepeaterApp::OnInit()
new wxLogNull;
}
- m_logChain = new wxLogChain(new CDStarRepeaterLogger);
+ m_logChain = new wxLogChain(new CDStarRepeaterLogRedirect);
wxString appName;
if (!m_name.IsEmpty())
@@ -511,6 +512,11 @@ void CDStarRepeaterApp::createThread()
wxLogInfo("\tRX %u name: %s", i + 1U, name.c_str());
}
modem = new CSplitController(localAddress, localPort, transmitterNames, receiverNames, timeout);
+ } else if (modemType.IsSameAs("Icom Access Point/Terminal Mode")) {
+ wxString port;
+ m_config->getIcom(port);
+ wxLogInfo("Icom, port: %s", port.c_str());
+ modem = new CIcomController(port);
} else {
wxLogError("Unknown modem type: %s", modemType.c_str());
}
diff --git a/DStarRepeater/DStarRepeaterLogger.cpp b/DStarRepeater/DStarRepeaterLogRedirect.cpp
similarity index 72%
rename from DStarRepeater/DStarRepeaterLogger.cpp
rename to DStarRepeater/DStarRepeaterLogRedirect.cpp
index 5536e13..5b13f24 100644
--- a/DStarRepeater/DStarRepeaterLogger.cpp
+++ b/DStarRepeater/DStarRepeaterLogRedirect.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002,2003,2009-2012 by Jonathan Naylor G4KLX
+ * Copyright (C) 2002,2003,2009-2013,2018 by Jonathan Naylor G4KLX
*
* 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
@@ -16,22 +16,20 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "DStarRepeaterLogger.h"
+#include "DStarRepeaterLogRedirect.h"
#include "DStarRepeaterApp.h"
-CDStarRepeaterLogger::CDStarRepeaterLogger() :
+CDStarRepeaterLogRedirect::CDStarRepeaterLogRedirect() :
wxLog()
{
}
-CDStarRepeaterLogger::~CDStarRepeaterLogger()
+CDStarRepeaterLogRedirect::~CDStarRepeaterLogRedirect()
{
}
-void CDStarRepeaterLogger::DoLog(wxLogLevel level, const wxChar* msg, time_t timestamp)
+void CDStarRepeaterLogRedirect::DoLogRecord(wxLogLevel level, const wxString& msg, const wxLogRecordInfo& info)
{
- wxASSERT(msg != NULL);
-
wxString letter;
switch (level) {
@@ -46,20 +44,13 @@ void CDStarRepeaterLogger::DoLog(wxLogLevel level, const wxChar* msg, time_t tim
default: letter = wxT("U"); break;
}
- struct tm* tm = ::gmtime(×tamp);
+ struct tm* tm = ::gmtime(&info.timestamp);
wxString message;
- message.Printf(wxT("%s: %04d-%02d-%02d %02d:%02d:%02d: %s\n"), letter.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, msg);
+ message.Printf(wxT("%s: %04d-%02d-%02d %02d:%02d:%02d: %s\n"), letter.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, msg.c_str());
- DoLogString(message.c_str(), timestamp);
+ ::wxGetApp().showLog(message);
if (level == wxLOG_FatalError)
::abort();
}
-
-void CDStarRepeaterLogger::DoLogString(const wxChar* msg, time_t timestamp)
-{
- wxASSERT(msg != NULL);
-
- ::wxGetApp().showLog(msg);
-}
diff --git a/DStarRepeater/DStarRepeaterLogger.h b/DStarRepeater/DStarRepeaterLogRedirect.h
similarity index 67%
rename from DStarRepeater/DStarRepeaterLogger.h
rename to DStarRepeater/DStarRepeaterLogRedirect.h
index c9ec940..fa12afd 100644
--- a/DStarRepeater/DStarRepeaterLogger.h
+++ b/DStarRepeater/DStarRepeaterLogRedirect.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002,2003,2009-2011 by Jonathan Naylor G4KLX
+ * Copyright (C) 2002,2003,2009-2011,2018 by Jonathan Naylor G4KLX
*
* 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
@@ -16,18 +16,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef DStarRepeaterLogger_H
-#define DStarRepeaterLogger_H
+#ifndef DStarRepeaterLogRedirect_H
+#define DStarRepeaterLogRedirect_H
#include
+#include
-class CDStarRepeaterLogger : public wxLog {
+class CDStarRepeaterLogRedirect : public wxLog {
public:
- CDStarRepeaterLogger();
- virtual ~CDStarRepeaterLogger();
+ CDStarRepeaterLogRedirect();
+ virtual ~CDStarRepeaterLogRedirect();
- virtual void DoLog(wxLogLevel level, const wxChar* msg, time_t timestamp);
- virtual void DoLogString(const wxChar* msg, time_t timestamp);
+ virtual void DoLogRecord(wxLogLevel level, const wxString& msg, const wxLogRecordInfo& info);
private:
};
diff --git a/DStarRepeater/Makefile b/DStarRepeater/Makefile
index f7eb6d4..bfc7826 100644
--- a/DStarRepeater/Makefile
+++ b/DStarRepeater/Makefile
@@ -1,4 +1,4 @@
-OBJECTS = DStarRepeaterApp.o DStarRepeaterLogger.o DStarRepeaterRXThread.o DStarRepeaterStatusData.o \
+OBJECTS = DStarRepeaterApp.o DStarRepeaterLogRedirect.o DStarRepeaterRXThread.o DStarRepeaterStatusData.o \
DStarRepeaterThread.o DStarRepeaterTRXThread.o DStarRepeaterTXRXThread.o DStarRepeaterTXThread.o
all: dstarrepeaterd