DSMT_TYPE CModem::read() { m_readLength = 0U; if (m_rxData.isEmpty()) return DSMTT_NONE; wxMutexLocker locker(m_mutex); unsigned char hdr[2U]; m_rxData.getData(hdr, 2U); m_readType = DSMT_TYPE(hdr[0U]); m_readLength = hdr[1U]; m_rxData.getData(m_readBuffer, m_readLength); return m_readType; }
void* CGMSKController::Entry() { wxLogMessage(wxT("Starting GMSK Modem Controller thread")); CTimer hdrTimer(100U, 0U, 100U); hdrTimer.start(); CTimer dataTimer(100U, 0U, 100U); bool rx = false; DSMT_TYPE writeType = DSMTT_HEADER; unsigned char writeLength = 0U; unsigned char* writeBuffer = new unsigned char[BUFFER_LENGTH]; unsigned char readLength = 0U; unsigned char* readBuffer = new unsigned char[DV_FRAME_LENGTH_BYTES]; while (!m_stopped) { // Only receive when not transmitting or when in duplex mode if (!m_tx || m_duplex) { if (rx) { unsigned char buffer[GMSK_MODEM_DATA_LENGTH]; bool end; int ret = m_modem->readData(buffer, GMSK_MODEM_DATA_LENGTH, end); if (ret >= 0) { // CUtils::dump(wxT("Read Data"), buffer, ret); if (end) { wxMutexLocker locker(m_mutex); unsigned char data[2U]; data[0U] = DSMTT_EOT; data[1U] = 0U; m_rxData.addData(data, 2U); hdrTimer.start(); readLength = 0U; rx = false; } else { for (int i = 0; i < ret; i++) { readBuffer[readLength] = buffer[i]; readLength++; if (readLength >= DV_FRAME_LENGTH_BYTES) { 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(readBuffer, DV_FRAME_LENGTH_BYTES); readLength = 0U; } } } } } else { // Check for a header every 100ms or so if (hdrTimer.isRunning() && hdrTimer.hasExpired()) { unsigned char buffer[90U]; bool ret = m_modem->readHeader(buffer, 90U); if (ret) { // CUtils::dump(wxT("Read Header"), buffer, RADIO_HEADER_LENGTH_BYTES); wxMutexLocker locker(m_mutex); unsigned char data[2U]; data[0U] = DSMTT_HEADER; data[1U] = RADIO_HEADER_LENGTH_BYTES - 2U; m_rxData.addData(data, 2U); m_rxData.addData(buffer, RADIO_HEADER_LENGTH_BYTES - 2U); hdrTimer.stop(); readLength = 0U; rx = true; } else { hdrTimer.reset(); } } } } // Only transmit when not receiving or when in duplex mode if (!rx || m_duplex) { if (writeLength == 0U && m_txData.hasData()) { wxMutexLocker locker(m_mutex); unsigned char type; m_txData.getData(&type, 1U); writeType = DSMT_TYPE(type); m_txData.getData(&writeLength, 1U); m_txData.getData(writeBuffer, writeLength); } if (writeLength > 0U) { if (writeType == DSMTT_HEADER) { TRISTATE tx = m_modem->getPTT(); // Check that the modem isn't still transmitting before sending the new header if (tx == STATE_FALSE) { // CUtils::dump(wxT("Write Header"), writeBuffer, writeLength); m_modem->writeHeader(writeBuffer, writeLength); m_modem->setPTT(true); dataTimer.start(); writeLength = 0U; m_tx = true; } } else { // Don't start sending data until the header has been gone for 100ms or so if (!dataTimer.isRunning() || dataTimer.hasExpired()) { dataTimer.stop(); TRISTATE ret = m_modem->hasSpace(); // Check that there is space in the modem buffer if (ret == STATE_TRUE) { // CUtils::dump(wxT("Write Data"), writeBuffer, writeLength); int ret = m_modem->writeData(writeBuffer, writeLength); if (ret > 0) { writeLength -= ret; if (writeType == DSMTT_EOT) { m_modem->setPTT(false); m_tx = false; } } } } } } } Sleep(10UL); dataTimer.clock(); hdrTimer.clock(); } wxLogMessage(wxT("Stopping GMSK Modem Controller thread")); m_modem->close(); delete[] writeBuffer; delete[] readBuffer; return NULL; }