Add MMDVM support for FCS mode and some code cleanup

pull/3/head
Doug McLain 3 years ago
parent a3117dca78
commit f2073c919a

@ -26,7 +26,6 @@
#define MACHAK 0 #define MACHAK 0
#endif #endif
//AudioEngine::AudioEngine(QObject *parent) : QObject(parent)
AudioEngine::AudioEngine(QString in, QString out) : AudioEngine::AudioEngine(QString in, QString out) :
m_outputdevice(out), m_outputdevice(out),
m_inputdevice(in), m_inputdevice(in),
@ -44,12 +43,6 @@ AudioEngine::AudioEngine(QString in, QString out) :
AudioEngine::~AudioEngine() AudioEngine::~AudioEngine()
{ {
//m_indev->disconnect();
//m_in->stop();
//m_outdev->disconnect();
//m_out->stop();
//delete m_in;
//delete m_out;
} }
QStringList AudioEngine::discover_audio_devices(uint8_t d) QStringList AudioEngine::discover_audio_devices(uint8_t d)
@ -59,7 +52,6 @@ QStringList AudioEngine::discover_audio_devices(uint8_t d)
QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(m); QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(m);
for (QList<QAudioDeviceInfo>::ConstIterator it = devices.constBegin(); it != devices.constEnd(); ++it ) { for (QList<QAudioDeviceInfo>::ConstIterator it = devices.constBegin(); it != devices.constEnd(); ++it ) {
//fprintf(stderr, "Playback device name = %s\n", (*it).deviceName().toStdString().c_str());fflush(stderr);
list.append((*it).deviceName()); list.append((*it).deviceName());
} }
return list; return list;
@ -269,7 +261,6 @@ uint16_t AudioEngine::read(int16_t *pcm, int s)
return 1; return 1;
} }
else{ else{
//fprintf(stderr, "audio frame not avail size == %d\n", m_audioinq.size());
return 0; return 0;
} }
} }

@ -40,9 +40,6 @@ void DCSCodec::process_udp()
static int sd_seq = 0; static int sd_seq = 0;
static char user_data[21]; static char user_data[21];
buf.resize(200); buf.resize(200);
//qDebug() << "buf size before == " << buf.size();
//buf.resize(m_udp->pendingDatagramSize());
//qDebug() << "buf size after == " << buf.size();
int size = m_udp->readDatagram(buf.data(), buf.size(), &sender, &senderPort); int size = m_udp->readDatagram(buf.data(), buf.size(), &sender, &senderPort);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "RECV: "); fprintf(stderr, "RECV: ");
@ -94,7 +91,6 @@ void DCSCodec::process_udp()
m_ping_timer->start(2000); m_ping_timer->start(2000);
m_audio = new AudioEngine(m_audioin, m_audioout); m_audio = new AudioEngine(m_audioin, m_audioout);
m_audio->init(); m_audio->init();
//fprintf(stderr, "m_vocoder == %s m_hwtx:m_hwrx == %d:%d\n", m_vocoder.toStdString().c_str(), m_hwtx, m_hwrx);fflush(stderr);
} }
if(m_modeinfo.status != CONNECTED_RW) return; if(m_modeinfo.status != CONNECTED_RW) return;
@ -104,7 +100,6 @@ void DCSCodec::process_udp()
} }
if((size == 100) && (!memcmp(buf.data(), "0001", 4)) ){ if((size == 100) && (!memcmp(buf.data(), "0001", 4)) ){
m_rxwatchdog = 0; m_rxwatchdog = 0;
//qDebug() << "m_streamid == " << m_streamid << ":" << m_hwrx << ":" << m_tx;
uint16_t streamid = (buf.data()[43] << 8) | (buf.data()[44] & 0xff); uint16_t streamid = (buf.data()[43] << 8) | (buf.data()[44] & 0xff);
if(!m_tx && (m_modeinfo.streamid == 0)){ if(!m_tx && (m_modeinfo.streamid == 0)){
@ -248,12 +243,6 @@ void DCSCodec::hostname_lookup(QHostInfo i)
out[9] = m_module; out[9] = m_module;
out[10] = 11; out[10] = 11;
//out.append(m_modeinfo.callsign.toUtf8());
//out.append(8 - m_modeinfo.callsign.size(), ' ');
//out.append(m_module);
//out.append(m_module);
//out.append(11);
//out.append(508, 0);
m_address = i.addresses().first(); m_address = i.addresses().first();
m_udp = new QUdpSocket(this); m_udp = new QUdpSocket(this);
connect(m_udp, SIGNAL(readyRead()), this, SLOT(process_udp())); connect(m_udp, SIGNAL(readyRead()), this, SLOT(process_udp()));

@ -92,15 +92,9 @@ void DMRCodec::process_udp()
fflush(stderr); fflush(stderr);
#endif #endif
if((m_modeinfo.status != CONNECTED_RW) && (::memcmp(buf.data() + 3, "NAK", 3U) == 0)){ if((m_modeinfo.status != CONNECTED_RW) && (::memcmp(buf.data() + 3, "NAK", 3U) == 0)){
//m_udp->disconnect();
//m_udp->close();
//delete m_udp;
m_modeinfo.status = DISCONNECTED; m_modeinfo.status = DISCONNECTED;
} }
if((m_modeinfo.status != CONNECTED_RW) && (::memcmp(buf.data(), "MSTCL", 5U) == 0)){ if((m_modeinfo.status != CONNECTED_RW) && (::memcmp(buf.data(), "MSTCL", 5U) == 0)){
//m_udp->disconnect();
//m_udp->close();
//delete m_udp;
m_modeinfo.status = CLOSED; m_modeinfo.status = CLOSED;
} }
if((m_modeinfo.status != CONNECTED_RW) && (::memcmp(buf.data(), "RPTACK", 6U) == 0)){ if((m_modeinfo.status != CONNECTED_RW) && (::memcmp(buf.data(), "RPTACK", 6U) == 0)){
@ -168,7 +162,6 @@ void DMRCodec::process_udp()
out.append((m_essid >> 8) & 0xff); out.append((m_essid >> 8) & 0xff);
out.append((m_essid >> 0) & 0xff); out.append((m_essid >> 0) & 0xff);
out.append(m_options.toUtf8()); out.append(m_options.toUtf8());
//m_status = DMR_OPTS;
} }
break; break;
case DMR_OPTS: case DMR_OPTS:
@ -224,8 +217,6 @@ void DMRCodec::process_udp()
for(int i = 0; i < 33; ++i){ for(int i = 0; i < 33; ++i){
m_rxmodemq.append(buf.data()[20+i]); m_rxmodemq.append(buf.data()[20+i]);
}; };
//m_rxmodemq.append('\x00');
//m_rxmodemq.append(0x2f);
} }
} }
if((buf.size() == 55) && if((buf.size() == 55) &&
@ -417,7 +408,6 @@ void DMRCodec::process_modem_data(QByteArray d)
if ((p_frame[3U] & DMR_SYNC_DATA) == DMR_SYNC_DATA){ if ((p_frame[3U] & DMR_SYNC_DATA) == DMR_SYNC_DATA){
if((m_dataType == DT_VOICE_LC_HEADER) && (m_modeinfo.stream_state == STREAM_IDLE)){ if((m_dataType == DT_VOICE_LC_HEADER) && (m_modeinfo.stream_state == STREAM_IDLE)){
m_modeinfo.stream_state = TRANSMITTING_MODEM; m_modeinfo.stream_state = TRANSMITTING_MODEM;
//qDebug() << "ids == " << m_txsrcid << ":" << m_txdstid;
} }
else if(m_dataType == DT_TERMINATOR_WITH_LC){ else if(m_dataType == DT_TERMINATOR_WITH_LC){
m_modeinfo.stream_state = STREAM_IDLE; m_modeinfo.stream_state = STREAM_IDLE;

@ -50,8 +50,6 @@ DroidStar::DroidStar(QObject *parent) :
connect_status = Codec::DISCONNECTED; connect_status = Codec::DISCONNECTED;
m_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "dudetronics", "droidstar", this); m_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "dudetronics", "droidstar", this);
config_path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); config_path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
qDebug() << "Config path == " << config_path;
qDebug() << "Download path == " << QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_WIN) #if !defined(Q_OS_ANDROID) && !defined(Q_OS_WIN)
config_path += "/dudetronics"; config_path += "/dudetronics";
#endif #endif
@ -135,7 +133,6 @@ void DroidStar::discover_devices()
void DroidStar::download_file(QString f, bool u) void DroidStar::download_file(QString f, bool u)
{ {
qDebug() << "download_file() " << f << ":" << u;
HttpManager *http = new HttpManager(f, u); HttpManager *http = new HttpManager(f, u);
QThread *httpThread = new QThread; QThread *httpThread = new QThread;
http->moveToThread(httpThread); http->moveToThread(httpThread);
@ -152,13 +149,11 @@ void DroidStar::download_file(QString f, bool u)
void DroidStar::url_downloaded(QString url) void DroidStar::url_downloaded(QString url)
{ {
qDebug() << "DudeStar::url_downloaded() " << url;
emit update_log("Downloaded " + url); emit update_log("Downloaded " + url);
} }
void DroidStar::file_downloaded(QString filename) void DroidStar::file_downloaded(QString filename)
{ {
qDebug() << "DudeStar::file_downloaded() " << filename;
emit update_log("Updated " + filename); emit update_log("Updated " + filename);
{ {
if(filename == "dplus.txt" && m_protocol == "REF"){ if(filename == "dplus.txt" && m_protocol == "REF"){
@ -455,7 +450,7 @@ void DroidStar::process_connect()
connect(this, SIGNAL(tx_clicked(bool)), m_dmr, SLOT(toggle_tx(bool))); connect(this, SIGNAL(tx_clicked(bool)), m_dmr, SLOT(toggle_tx(bool)));
connect(this, SIGNAL(tx_pressed()), m_dmr, SLOT(start_tx())); connect(this, SIGNAL(tx_pressed()), m_dmr, SLOT(start_tx()));
connect(this, SIGNAL(tx_released()), m_dmr, SLOT(stop_tx())); connect(this, SIGNAL(tx_released()), m_dmr, SLOT(stop_tx()));
connect(this, SIGNAL(dmr_tgid_changed(unsigned int)), m_dmr, SLOT(dmr_tgid_changed(unsigned int))); connect(this, SIGNAL(dmr_tgid_changed(uint)), m_dmr, SLOT(dmr_tgid_changed(uint)));
connect(this, SIGNAL(dmrpc_state_changed(int)), m_dmr, SLOT(dmrpc_state_changed(int))); connect(this, SIGNAL(dmrpc_state_changed(int)), m_dmr, SLOT(dmrpc_state_changed(int)));
connect(this, SIGNAL(slot_changed(int)), m_dmr, SLOT(slot_changed(int))); connect(this, SIGNAL(slot_changed(int)), m_dmr, SLOT(slot_changed(int)));
connect(this, SIGNAL(cc_changed(int)), m_dmr, SLOT(cc_changed(int))); connect(this, SIGNAL(cc_changed(int)), m_dmr, SLOT(cc_changed(int)));
@ -1310,7 +1305,6 @@ void DroidStar::check_host_files()
if( (!check_file.exists() && !(check_file.isFile())) || m_update_host_files ){ if( (!check_file.exists() && !(check_file.isFile())) || m_update_host_files ){
download_file("/dplus.txt"); download_file("/dplus.txt");
} }
qDebug() << "dplus.txt time == " << check_file.birthTime();
check_file.setFile(config_path + "/dextra.txt"); check_file.setFile(config_path + "/dextra.txt");
if( (!check_file.exists() && !check_file.isFile() ) || m_update_host_files ){ if( (!check_file.exists() && !check_file.isFile() ) || m_update_host_files ){

@ -326,7 +326,6 @@ void XRFCodec::format_callsign(QString &s)
void XRFCodec::process_modem_data(QByteArray d) void XRFCodec::process_modem_data(QByteArray d)
{ {
QByteArray txdata;
char cs[9]; char cs[9];
uint8_t ambe[9]; uint8_t ambe[9];

@ -24,7 +24,7 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
//#define DEBUG #define DEBUG
const uint32_t IMBE_INTERLEAVE[] = { const uint32_t IMBE_INTERLEAVE[] = {
0, 7, 12, 19, 24, 31, 36, 43, 48, 55, 60, 67, 72, 79, 84, 91, 96, 103, 108, 115, 120, 127, 132, 139, 0, 7, 12, 19, 24, 31, 36, 43, 48, 55, 60, 67, 72, 79, 84, 91, 96, 103, 108, 115, 120, 127, 132, 139,
@ -212,6 +212,17 @@ void YSFCodec::process_udp()
memcpy(ysftag, buf.data() + 0x79, 8);ysftag[8] = '\0'; memcpy(ysftag, buf.data() + 0x79, 8);ysftag[8] = '\0';
m_modeinfo.gw = QString(ysftag); m_modeinfo.gw = QString(ysftag);
p_data = (uint8_t *)buf.data(); p_data = (uint8_t *)buf.data();
if(m_modem){
m_rxmodemq.append(MMDVM_FRAME_START);
m_rxmodemq.append(124);
m_rxmodemq.append(MMDVM_YSF_DATA);
m_rxmodemq.append('\x00');
for(int i = 0; i < 120; ++i){
m_rxmodemq.append(buf.data()[i]);
}
//m_rxmodemq.append(buf.mid(35));
}
} }
if(p_data != nullptr){ if(p_data != nullptr){
@ -612,30 +623,37 @@ void YSFCodec::interleave(uint8_t *ambe)
void YSFCodec::process_modem_data(QByteArray d) void YSFCodec::process_modem_data(QByteArray d)
{ {
QByteArray txdata; if(d.size() < 126){
uint8_t *p_frame = (uint8_t *)(d.data()); return;
}
if(m_fcs && d.size() >= 130){ char callsign[YSF_CALLSIGN_LENGTH+1];
::memset(p_frame + 120U, 0, 10U); ::memcpy(callsign, " ", YSF_CALLSIGN_LENGTH);
::memcpy(p_frame + 121U, m_fcsname.c_str(), 8); ::memcpy(callsign, m_modeinfo.callsign.toStdString().c_str(), ::strlen(m_modeinfo.callsign.toStdString().c_str()));
d.remove(0, 4);
if(m_fcs){
d.insert(120, 10, 0);
d.insert(121, m_fcsname.c_str(), 8);
d.resize(130);
} }
else{ else{
::memcpy(m_ysfFrame + 0U, "YSFD", 4U); d.insert(0U, "YSFD", 4U);
::memcpy(m_ysfFrame + 4U, m_modeinfo.callsign.toStdString().c_str(), YSF_CALLSIGN_LENGTH); d.insert(4U, callsign, YSF_CALLSIGN_LENGTH);
::memcpy(m_ysfFrame + 14U, m_modeinfo.callsign.toStdString().c_str(), YSF_CALLSIGN_LENGTH); d.insert(14U, callsign, YSF_CALLSIGN_LENGTH);
::memcpy(m_ysfFrame + 24U, "ALL ", YSF_CALLSIGN_LENGTH); d.insert(24U, "ALL ", YSF_CALLSIGN_LENGTH);
m_ysfFrame[34U] = (m_txcnt & 0x7f) << 1; d.insert(34U, (m_txcnt & 0x7f) << 1);
::memcpy(m_ysfFrame + 35U, p_frame + 4U, 120); d.resize(155);
} }
++m_txcnt; ++m_txcnt;
txdata.append((char *)m_ysfFrame, 155); m_udp->writeDatagram(d, m_address, m_modeinfo.port);
m_udp->writeDatagram(txdata, m_address, m_modeinfo.port);
qDebug() << "Sending modem to network....................................................."; qDebug() << "Sending modem to network.....................................................";
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "SEND:%d: ", txdata.size()); fprintf(stderr, "SEND:%d: ", d.size());
for(int i = 0; i < txdata.size(); ++i){ for(int i = 0; i < d.size(); ++i){
fprintf(stderr, "%02x ", (uint8_t)txdata.data()[i]); fprintf(stderr, "%02x ", (uint8_t)d.data()[i]);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fflush(stderr); fflush(stderr);
@ -776,20 +794,20 @@ void YSFCodec::encode_header(bool eot)
} }
::memcpy(p_frame, YSF_SYNC_BYTES, 5); ::memcpy(p_frame, YSF_SYNC_BYTES, 5);
fich.setFI(eot ? YSF_FI_TERMINATOR : YSF_FI_HEADER); m_fich.setFI(eot ? YSF_FI_TERMINATOR : YSF_FI_HEADER);
fich.setCS(2U); m_fich.setCS(2U);
fich.setCM(0U); m_fich.setCM(0U);
fich.setBN(0U); m_fich.setBN(0U);
fich.setBT(0U); m_fich.setBT(0U);
fich.setFN(0U); m_fich.setFN(0U);
fich.setFT(6U); m_fich.setFT(6U);
fich.setDev(0U); m_fich.setDev(0U);
fich.setMR(0U); m_fich.setMR(0U);
fich.setVoIP(false); m_fich.setVoIP(false);
fich.setDT(m_txfullrate ? YSF_DT_VOICE_FR_MODE : YSF_DT_VD_MODE2); m_fich.setDT(m_txfullrate ? YSF_DT_VOICE_FR_MODE : YSF_DT_VD_MODE2);
fich.setSQL(false); m_fich.setSQL(false);
fich.setSQ(0U); m_fich.setSQ(0U);
fich.encode(p_frame); m_fich.encode(p_frame);
uint8_t csd1[20U], csd2[20U]; uint8_t csd1[20U], csd2[20U];
memset(csd1, '*', YSF_CALLSIGN_LENGTH); memset(csd1, '*', YSF_CALLSIGN_LENGTH);
@ -825,20 +843,20 @@ void YSFCodec::encode_vw()
::memcpy(p_frame, YSF_SYNC_BYTES, 5); ::memcpy(p_frame, YSF_SYNC_BYTES, 5);
uint32_t fn = (m_txcnt - 1U) % 7U; uint32_t fn = (m_txcnt - 1U) % 7U;
fich.setFI(YSF_FI_COMMUNICATIONS); m_fich.setFI(YSF_FI_COMMUNICATIONS);
fich.setCS(2U); m_fich.setCS(2U);
fich.setCM(0U); m_fich.setCM(0U);
fich.setBN(0U); m_fich.setBN(0U);
fich.setBT(0U); m_fich.setBT(0U);
fich.setFN(fn); m_fich.setFN(fn);
fich.setFT(6U); m_fich.setFT(6U);
fich.setDev(0U); m_fich.setDev(0U);
fich.setMR(0U); m_fich.setMR(0U);
fich.setVoIP(false); m_fich.setVoIP(false);
fich.setDT(YSF_DT_VOICE_FR_MODE); m_fich.setDT(YSF_DT_VOICE_FR_MODE);
fich.setSQL(false); m_fich.setSQL(false);
fich.setSQ(0U); m_fich.setSQ(0U);
fich.encode(p_frame); m_fich.encode(p_frame);
m_modeinfo.gw = m_modeinfo.callsign; m_modeinfo.gw = m_modeinfo.callsign;
m_modeinfo.src = m_modeinfo.callsign; m_modeinfo.src = m_modeinfo.callsign;
@ -981,20 +999,20 @@ void YSFCodec::encode_dv2()
::memcpy(p_frame, YSF_SYNC_BYTES, 5); ::memcpy(p_frame, YSF_SYNC_BYTES, 5);
uint32_t fn = (m_txcnt - 1U) % 7U; uint32_t fn = (m_txcnt - 1U) % 7U;
fich.setFI(YSF_FI_COMMUNICATIONS); m_fich.setFI(YSF_FI_COMMUNICATIONS);
fich.setCS(2U); m_fich.setCS(2U);
fich.setCM(0U); m_fich.setCM(0U);
fich.setBN(0U); m_fich.setBN(0U);
fich.setBT(0U); m_fich.setBT(0U);
fich.setFN(fn); m_fich.setFN(fn);
fich.setFT(6U); m_fich.setFT(6U);
fich.setDev(0U); m_fich.setDev(0U);
fich.setMR(0U); m_fich.setMR(0U);
fich.setVoIP(false); m_fich.setVoIP(false);
fich.setDT(YSF_DT_VD_MODE2); m_fich.setDT(YSF_DT_VD_MODE2);
fich.setSQL(false); m_fich.setSQL(false);
fich.setSQ(0U); m_fich.setSQ(0U);
fich.encode(p_frame); m_fich.encode(p_frame);
m_modeinfo.gw = m_modeinfo.callsign; m_modeinfo.gw = m_modeinfo.callsign;
m_modeinfo.src = m_modeinfo.callsign; m_modeinfo.src = m_modeinfo.callsign;

@ -94,7 +94,7 @@ private:
uint8_t m_vch[13U]; uint8_t m_vch[13U];
uint8_t m_ambe[55]; uint8_t m_ambe[55];
//uint8_t m_imbe[55]; //uint8_t m_imbe[55];
CYSFFICH fich; CYSFFICH m_fich;
uint8_t ambe_fr[4][24]; uint8_t ambe_fr[4][24];
uint32_t ambe_a; uint32_t ambe_a;
uint32_t ambe_b; uint32_t ambe_b;

Loading…
Cancel
Save