diff --git a/Common/IcomController.cpp b/Common/IcomController.cpp index 79c5234..0efe123 100644 --- a/Common/IcomController.cpp +++ b/Common/IcomController.cpp @@ -16,9 +16,7 @@ * 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" @@ -29,8 +27,6 @@ #include #endif -const unsigned char ICOM_FRAME_START = 0xFFU; - const unsigned int MAX_RESPONSES = 30U; const unsigned int BUFFER_LENGTH = 200U; @@ -43,10 +39,7 @@ m_buffer(NULL), m_txData(1000U), m_txCounter(0U), m_pktCounter(0U), -m_rx(false), -m_txSpace(0U), -m_txEnabled(false), -m_checksum(false) +m_txSpace(true) { wxASSERT(!port.IsEmpty()); @@ -93,12 +86,12 @@ void* CIcomController::Entry() case RTI_TIMEOUT: break; - case RTI_ERROR: { + case RTI_ERROR: wxLogMessage(wxT("Stopping Icom Controller thread")); return NULL; case RTI_HEADER: { - // CUtils::dump(wxT("RT_HEADER"), m_buffer, length); + // CUtils::dump(wxT("RTI_HEADER"), m_buffer, length); wxMutexLocker locker(m_mutex); unsigned char data[2U]; @@ -106,14 +99,14 @@ void* CIcomController::Entry() data[1U] = RADIO_HEADER_LENGTH_BYTES; m_rxData.addData(data, 2U); - m_rxData.addData(m_buffer + 3U, RADIO_HEADER_LENGTH_BYTES); + m_rxData.addData(m_buffer + 2U, RADIO_HEADER_LENGTH_BYTES); - m_rx = true; + m_txSpace = true; } break; case RTI_DATA: { - // CUtils::dump(wxT("RT_DATA"), m_buffer, length); + // CUtils::dump(wxT("RTI_DATA"), m_buffer, length); wxMutexLocker locker(m_mutex); unsigned char data[2U]; @@ -121,14 +114,14 @@ void* CIcomController::Entry() data[1U] = DV_FRAME_LENGTH_BYTES; m_rxData.addData(data, 2U); - m_rxData.addData(m_buffer + 5U, DV_FRAME_LENGTH_BYTES); + m_rxData.addData(m_buffer + 4U, DV_FRAME_LENGTH_BYTES); - m_rx = true; + m_txSpace = true; } break; case RTI_EOT: { - // wxLogMessage(wxT("RT_EOT")); + // wxLogMessage(wxT("RTI_EOT")); wxMutexLocker locker(m_mutex); unsigned char data[2U]; @@ -136,60 +129,39 @@ void* CIcomController::Entry() data[1U] = 0U; m_rxData.addData(data, 2U); - m_rx = false; + m_txSpace = true; } break; - default: - wxLogMessage(wxT("Unknown message, type: %02X"), m_buffer[3U]); - CUtils::dump(wxT("Buffer dump"), m_buffer, length); + case RTI_HEADER_ACK: + // wxLogMessage(wxT("RTI_HEADER_ACK")); + m_txSpace = true; 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--; - } + case RTI_DATA_ACK: + // wxLogMessage(wxT("RTI_DATA_ACK")); + m_txSpace = true; + break; - if (space > 4U && writeType == DSMTT_HEADER) { - // CUtils::dump(wxT("Write Header"), writeBuffer, writeLength); + default: + wxLogMessage(wxT("Unknown message, type: %02X"), m_buffer[1U]); + CUtils::dump(wxT("Buffer dump"), m_buffer, length + 1U); + break; + } - int ret = m_serial.write(writeBuffer, writeLength); - if (ret != int(writeLength)) - wxLogWarning(wxT("Error when writing the header to the Icom")); + if (m_txSpace && !m_txData.isEmpty()) { + m_txData.getData(m_buffer, 1U); - writeType = DSMTT_NONE; - space -= 4U; - } + unsigned int len = m_buffer[0U]; + m_txData.getData(m_buffer + 1U, len); - if (writeType == DSMTT_DATA || writeType == DSMTT_EOT) { - // CUtils::dump(wxT("Write Data"), writeBuffer, writeLength); + // CUtils::dump(wxT("Sending"), m_buffer, len + 1U); - int ret = m_serial.write(writeBuffer, writeLength); - if (ret != int(writeLength)) - wxLogWarning(wxT("Error when writing data to the Icom")); + int ret = m_serial.write(m_buffer, len + 1U); + if (ret != int(len + 1U)) + wxLogWarning(wxT("Error when writing the header to the Icom")); - writeType = DSMTT_NONE; - space--; - } -#endif + m_txSpace = false; } Sleep(5UL); @@ -204,438 +176,124 @@ void* CIcomController::Entry() 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); + bool ret = m_txData.hasSpace(43U); 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 buffer[50U]; - unsigned char buffer2[60U]; + buffer[0U] = 0x29U; - buffer2[0U] = DVRPTR_FRAME_START; + buffer[1U] = 0x20U; - buffer2[1U] = 0x2FU; - buffer2[2U] = 0x00U; + ::memset(buffer + 2U, ' ', RADIO_HEADER_LENGTH_BYTES); - 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(); + buffer[2U] = header.getFlag1(); + buffer[3U] = header.getFlag2(); + buffer[4U] = 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); + buffer[i + 5U] = 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); + buffer[i + 13U] = 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); + buffer[i + 21U] = 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); + buffer[i + 29U] = 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); + buffer[i + 37U] = 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; - } + buffer[41U] = 0xFFU; + m_txCounter = 0U; m_pktCounter = 0U; wxMutexLocker locker(m_mutex); - unsigned char type1 = DSMTT_START; - m_txData.addData(&type1, 1U); + m_txData.addData(buffer, 42U); - unsigned char len1 = 8U; - m_txData.addData(&len1, 1U); + m_txSpace = false; - 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); + bool ret = m_txData.hasSpace(18U); if (!ret) { wxLogWarning(wxT("No space to write data")); return false; } - unsigned char buffer[30U]; + unsigned char buffer[20U]; if (end) { - buffer[0U] = DVRPTR_FRAME_START; + buffer[0U] = 0x10U; - buffer[1U] = 0x03U; - buffer[2U] = 0x00U; + buffer[1U] = 0x22U; - buffer[3U] = DVRPTR_EOT; + buffer[2U] = m_txCounter; + buffer[3U] = m_pktCounter | 0x40U; - buffer[4U] = m_txCounter; - buffer[5U] = 0xFFU; + ::memcpy(buffer + 4U, END_PATTERN_BYTES, DV_FRAME_LENGTH_BYTES); - if (m_checksum) { - CCCITTChecksum cksum; - cksum.update(buffer + 0U, 6U); - cksum.result(buffer + 6U); - } else { - buffer[6U] = 0x00U; - buffer[7U] = 0x0BU; - } + buffer[16U] = 0xFFU; 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, 17U); - m_txData.addData(buffer, 8U); + m_txSpace = true; return true; } - buffer[0U] = DVRPTR_FRAME_START; + buffer[0U] = 0x10U; - buffer[1U] = 0x13U; - buffer[2U] = 0x00U; + buffer[1U] = 0x22U; - buffer[3U] = DVRPTR_DATA; - - buffer[4U] = m_txCounter; - buffer[5U] = m_pktCounter; + buffer[2U] = m_txCounter; + buffer[3U] = m_pktCounter; + m_txCounter++; m_pktCounter++; - if (m_pktCounter >= m_txSpace) + if (::memcmp(buffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES) == 0 || m_pktCounter == 21U) m_pktCounter = 0U; - buffer[6U] = 0x00U; - buffer[7U] = 0x00U; + ::memcpy(buffer + 4U, data, DV_FRAME_LENGTH_BYTES); - ::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; - } + buffer[16U] = 0xFFU; wxMutexLocker locker(m_mutex); - unsigned char type = DSMTT_DATA; - m_txData.addData(&type, 1U); + m_txData.addData(buffer, 17U); - unsigned char len = 24U; - m_txData.addData(&len, 1U); + m_txSpace = false; - m_txData.addData(buffer, 24U); -#endif return true; } unsigned int CIcomController::getSpace() { - // return m_txData.freeSpace() / 26U; - return true; + return m_txData.freeSpace() / 18U; } bool CIcomController::isTXReady() { - return true; - -#ifdef notdef - if (m_tx) - return false; - return m_txData.isEmpty(); -#endif } wxString CIcomController::getPath() const @@ -655,30 +313,17 @@ RESP_TYPE_ICOM CIcomController::getResponse(unsigned char *buffer, unsigned int& 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) + if (buffer[0U] == 0xFFU) return RTI_TIMEOUT; - length = buffer[1U] + 1U; + length = buffer[0U]; if (length >= 100U) { wxLogError(wxT("Invalid data received from the Icom radio")); return RTI_ERROR; } - unsigned int offset = 2U; + unsigned int offset = 1U; while (offset < length) { ret = m_serial.read(buffer + offset, length - offset); @@ -694,16 +339,22 @@ RESP_TYPE_ICOM CIcomController::getResponse(unsigned char *buffer, unsigned int& Sleep(5UL); } - // CUtils::dump(wxT("Received"), buffer, length); + // CUtils::dump(wxT("Received"), buffer, length + 1U); - switch (length) { - case 45U: + switch (buffer[1U]) { + case 0x03U: + return RTI_TIMEOUT; + case 0x10U: return RTI_HEADER; - case 17U: - if ((buffer[4U] & 0x40U) == 0x40U) + case 0x12U: + if ((buffer[3U] & 0x40U) == 0x40U) return RTI_EOT; else return RTI_DATA; + case 0x21U: + return RTI_HEADER_ACK; + case 0x23U: + return RTI_DATA_ACK; default: return RTI_UNKNOWN; } diff --git a/Common/IcomController.h b/Common/IcomController.h index 8d43629..eb0f797 100644 --- a/Common/IcomController.h +++ b/Common/IcomController.h @@ -32,7 +32,9 @@ enum RESP_TYPE_ICOM { RTI_UNKNOWN, RTI_HEADER, RTI_DATA, - RTI_EOT + RTI_EOT, + RTI_HEADER_ACK, + RTI_DATA_ACK }; class CIcomController : public CModem { @@ -59,10 +61,7 @@ private: CRingBuffer m_txData; unsigned char m_txCounter; unsigned char m_pktCounter; - bool m_rx; - unsigned int m_txSpace; - bool m_txEnabled; - bool m_checksum; + bool m_txSpace; RESP_TYPE_ICOM getResponse(unsigned char* buffer, unsigned int& length); };