Rename Codec class to Mode and rename all dervied modes, rewrite use of the Mode class

pull/4/head
Doug McLain 2 years ago
parent 2e9cbd306c
commit 371dd2025b

@ -1,209 +0,0 @@
/*
* Copyright (C) 2015,2016,2017 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; version 2 of the License.
*
* 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.
*/
#include "DMRData.h"
#include "DMRDefines.h"
#include <cstdio>
#include <cstring>
#include <cassert>
CDMRData::CDMRData(const CDMRData& data) :
m_slotNo(data.m_slotNo),
m_data(NULL),
m_srcId(data.m_srcId),
m_dstId(data.m_dstId),
m_flco(data.m_flco),
m_dataType(data.m_dataType),
m_seqNo(data.m_seqNo),
m_missing(data.m_missing),
m_n(data.m_n),
m_ber(data.m_ber),
m_rssi(data.m_rssi),
m_streamId(data.m_streamId)
{
m_data = new unsigned char[2U * DMR_FRAME_LENGTH_BYTES];
::memcpy(m_data, data.m_data, 2U * DMR_FRAME_LENGTH_BYTES);
}
CDMRData::CDMRData() :
m_slotNo(1U),
m_data(NULL),
m_srcId(0U),
m_dstId(0U),
m_flco(FLCO_GROUP),
m_dataType(0U),
m_seqNo(0U),
m_missing(false),
m_n(0U),
m_ber(0U),
m_rssi(0U),
m_streamId(0U)
{
m_data = new unsigned char[2U * DMR_FRAME_LENGTH_BYTES];
}
CDMRData::~CDMRData()
{
delete[] m_data;
}
CDMRData& CDMRData::operator=(const CDMRData& data)
{
if (this != &data) {
::memcpy(m_data, data.m_data, DMR_FRAME_LENGTH_BYTES);
m_slotNo = data.m_slotNo;
m_srcId = data.m_srcId;
m_dstId = data.m_dstId;
m_flco = data.m_flco;
m_dataType = data.m_dataType;
m_seqNo = data.m_seqNo;
m_missing = data.m_missing;
m_n = data.m_n;
m_ber = data.m_ber;
m_rssi = data.m_rssi;
m_streamId = data.m_streamId;
}
return *this;
}
unsigned int CDMRData::getSlotNo() const
{
return m_slotNo;
}
void CDMRData::setSlotNo(unsigned int slotNo)
{
assert(slotNo == 1U || slotNo == 2U);
m_slotNo = slotNo;
}
unsigned char CDMRData::getDataType() const
{
return m_dataType;
}
void CDMRData::setDataType(unsigned char dataType)
{
m_dataType = dataType;
}
unsigned int CDMRData::getSrcId() const
{
return m_srcId;
}
void CDMRData::setSrcId(unsigned int id)
{
m_srcId = id;
}
unsigned int CDMRData::getDstId() const
{
return m_dstId;
}
void CDMRData::setDstId(unsigned int id)
{
m_dstId = id;
}
FLCO CDMRData::getFLCO() const
{
return m_flco;
}
void CDMRData::setFLCO(FLCO flco)
{
m_flco = flco;
}
unsigned char CDMRData::getSeqNo() const
{
return m_seqNo;
}
void CDMRData::setSeqNo(unsigned char seqNo)
{
m_seqNo = seqNo;
}
bool CDMRData::isMissing() const
{
return m_missing;
}
void CDMRData::setMissing(bool missing)
{
m_missing = missing;
}
unsigned char CDMRData::getN() const
{
return m_n;
}
void CDMRData::setN(unsigned char n)
{
m_n = n;
}
unsigned char CDMRData::getBER() const
{
return m_ber;
}
void CDMRData::setBER(unsigned char ber)
{
m_ber = ber;
}
unsigned char CDMRData::getRSSI() const
{
return m_rssi;
}
void CDMRData::setRSSI(unsigned char rssi)
{
m_rssi = rssi;
}
unsigned int CDMRData::getData(unsigned char* buffer) const
{
assert(buffer != NULL);
::memcpy(buffer, m_data, DMR_FRAME_LENGTH_BYTES);
return DMR_FRAME_LENGTH_BYTES;
}
void CDMRData::setData(const unsigned char* buffer)
{
assert(buffer != NULL);
::memcpy(m_data, buffer, DMR_FRAME_LENGTH_BYTES);
}
unsigned int CDMRData::getStreamId() const
{
return m_streamId;
}
void CDMRData::setStreamId(unsigned int id)
{
m_streamId = id;
}

@ -1,78 +0,0 @@
/*
* Copyright (C) 2015,2016,2017 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; version 2 of the License.
*
* 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.
*/
#ifndef DMRData_H
#define DMRData_H
#include "DMRDefines.h"
class CDMRData {
public:
CDMRData(const CDMRData& data);
CDMRData();
~CDMRData();
CDMRData& operator=(const CDMRData& data);
unsigned int getSlotNo() const;
void setSlotNo(unsigned int slotNo);
unsigned int getSrcId() const;
void setSrcId(unsigned int id);
unsigned int getDstId() const;
void setDstId(unsigned int id);
FLCO getFLCO() const;
void setFLCO(FLCO flco);
unsigned char getN() const;
void setN(unsigned char n);
unsigned char getSeqNo() const;
void setSeqNo(unsigned char seqNo);
unsigned char getDataType() const;
void setDataType(unsigned char dataType);
bool isMissing() const;
void setMissing(bool missing);
unsigned char getBER() const;
void setBER(unsigned char ber);
unsigned char getRSSI() const;
void setRSSI(unsigned char rssi);
void setData(const unsigned char* buffer);
unsigned int getData(unsigned char* buffer) const;
void setStreamId(unsigned int id);
unsigned int getStreamId() const;
private:
unsigned int m_slotNo;
unsigned char* m_data;
unsigned int m_srcId;
unsigned int m_dstId;
FLCO m_flco;
unsigned char m_dataType;
unsigned char m_seqNo;
bool m_missing;
unsigned char m_n;
unsigned char m_ber;
unsigned char m_rssi;
unsigned int m_streamId;
};
#endif

@ -31,12 +31,11 @@ DEFINES += VERSION_NUMBER=\"\\\"$${VERSION_BUILD}\\\"\"
DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
DEFINES += VOCODER_PLUGIN DEFINES += VOCODER_PLUGIN
#DEFINES += USE_FLITE DEFINES += USE_FLITE
#DEFINES += USE_EXTERNAL_CODEC2 #DEFINES += USE_EXTERNAL_CODEC2
HEADERS += \ HEADERS += \
CRCenc.h \ CRCenc.h \
DMRData.h \
DMRDefines.h \ DMRDefines.h \
Golay24128.h \ Golay24128.h \
M17Convolution.h \ M17Convolution.h \
@ -49,28 +48,27 @@ HEADERS += \
cbptc19696.h \ cbptc19696.h \
cgolay2087.h \ cgolay2087.h \
chamming.h \ chamming.h \
codec.h \
crs129.h \ crs129.h \
dcscodec.h \ dcs.h \
dmrcodec.h \ dmr.h \
droidstar.h \ droidstar.h \
httpmanager.h \ httpmanager.h \
iaxcodec.h \ iax.h \
iaxdefines.h \ iaxdefines.h \
m17codec.h \ m17.h \
nxdncodec.h \ mode.h \
p25codec.h \ nxdn.h \
refcodec.h \ p25.h \
ref.h \
vocoder_plugin.h \ vocoder_plugin.h \
xrfcodec.h \ xrf.h \
ysfcodec.h ysf.h
android:HEADERS += androidserialport.h android:HEADERS += androidserialport.h
macx:HEADERS += micpermission.h macx:HEADERS += micpermission.h
!ios:HEADERS += serialambe.h serialmodem.h !ios:HEADERS += serialambe.h serialmodem.h
SOURCES += \ SOURCES += \
CRCenc.cpp \ CRCenc.cpp \
DMRData.cpp \
Golay24128.cpp \ Golay24128.cpp \
M17Convolution.cpp \ M17Convolution.cpp \
SHA256.cpp \ SHA256.cpp \
@ -80,20 +78,20 @@ SOURCES += \
cbptc19696.cpp \ cbptc19696.cpp \
cgolay2087.cpp \ cgolay2087.cpp \
chamming.cpp \ chamming.cpp \
codec.cpp \
crs129.cpp \ crs129.cpp \
dcscodec.cpp \ dcs.cpp \
dmrcodec.cpp \ dmr.cpp \
droidstar.cpp \ droidstar.cpp \
httpmanager.cpp \ httpmanager.cpp \
iaxcodec.cpp \ iax.cpp \
m17codec.cpp \ m17.cpp \
main.cpp \ main.cpp \
nxdncodec.cpp \ mode.cpp \
p25codec.cpp \ nxdn.cpp \
refcodec.cpp \ p25.cpp \
xrfcodec.cpp \ ref.cpp \
ysfcodec.cpp xrf.cpp \
ysf.cpp
android:SOURCES += androidserialport.cpp android:SOURCES += androidserialport.cpp
!ios:SOURCES += serialambe.cpp serialmodem.cpp !ios:SOURCES += serialambe.cpp serialmodem.cpp
!contains(DEFINES, USE_EXTERNAL_CODEC2){ !contains(DEFINES, USE_EXTERNAL_CODEC2){

@ -16,22 +16,22 @@
*/ */
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include "dcscodec.h" #include "dcs.h"
#include "CRCenc.h" #include "CRCenc.h"
#include "MMDVMDefines.h" #include "MMDVMDefines.h"
//#define DEBUG //#define DEBUG
DCSCodec::DCSCodec(QString callsign, QString hostname, char module, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout) : DCS::DCS()
Codec(callsign, module, hostname, host, port, ipv6, vocoder, modem, audioin, audioout, 5)
{ {
m_attenuation = 5;
} }
DCSCodec::~DCSCodec() DCS::~DCS()
{ {
} }
void DCSCodec::process_udp() void DCS::process_udp()
{ {
QByteArray buf; QByteArray buf;
QHostAddress sender; QHostAddress sender;
@ -126,7 +126,7 @@ void DCSCodec::process_udp()
m_modeinfo.dst = QString(temp); m_modeinfo.dst = QString(temp);
memcpy(temp, buf.data() + 31, 8); temp[8] = '\0'; memcpy(temp, buf.data() + 31, 8); temp[8] = '\0';
m_modeinfo.src = QString(temp); m_modeinfo.src = QString(temp);
QString h = m_hostname + " " + m_module; QString h = m_refname + " " + m_module;
if(m_modem){ if(m_modem){
uint8_t out[44]; uint8_t out[44];
@ -236,7 +236,7 @@ void DCSCodec::process_udp()
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void DCSCodec::hostname_lookup(QHostInfo i) void DCS::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
@ -262,7 +262,7 @@ void DCSCodec::hostname_lookup(QHostInfo i)
} }
} }
void DCSCodec::send_ping() void DCS::send_ping()
{ {
static QByteArray out; static QByteArray out;
out.clear(); out.clear();
@ -270,7 +270,7 @@ void DCSCodec::send_ping()
out.append(7 - m_modeinfo.callsign.size(), ' '); out.append(7 - m_modeinfo.callsign.size(), ' ');
out.append(m_module); out.append(m_module);
out.append('\x00'); out.append('\x00');
out.append(m_hostname.toUtf8()); out.append(m_refname.toUtf8());
out.append('\x00'); out.append('\x00');
out.append(m_module); out.append(m_module);
m_udp->writeDatagram(out, m_address, m_modeinfo.port); m_udp->writeDatagram(out, m_address, m_modeinfo.port);
@ -284,7 +284,7 @@ void DCSCodec::send_ping()
#endif #endif
} }
void DCSCodec::send_disconnect() void DCS::send_disconnect()
{ {
QByteArray out; QByteArray out;
out.append(m_modeinfo.callsign.toUtf8()); out.append(m_modeinfo.callsign.toUtf8());
@ -303,7 +303,7 @@ void DCSCodec::send_disconnect()
#endif #endif
} }
void DCSCodec::format_callsign(QString &s) void DCS::format_callsign(QString &s)
{ {
QStringList l = s.simplified().split(' '); QStringList l = s.simplified().split(' ');
@ -321,7 +321,7 @@ void DCSCodec::format_callsign(QString &s)
} }
} }
void DCSCodec::process_modem_data(QByteArray d) void DCS::process_modem_data(QByteArray d)
{ {
QByteArray txdata; QByteArray txdata;
char cs[9]; char cs[9];
@ -348,21 +348,21 @@ void DCSCodec::process_modem_data(QByteArray d)
send_frame(ambe); send_frame(ambe);
} }
void DCSCodec::toggle_tx(bool tx) void DCS::toggle_tx(bool tx)
{ {
tx ? start_tx() : stop_tx(); tx ? start_tx() : stop_tx();
} }
void DCSCodec::start_tx() void DCS::start_tx()
{ {
format_callsign(m_txmycall); format_callsign(m_txmycall);
format_callsign(m_txurcall); format_callsign(m_txurcall);
format_callsign(m_txrptr1); format_callsign(m_txrptr1);
format_callsign(m_txrptr2); format_callsign(m_txrptr2);
Codec::start_tx(); Mode::start_tx();
} }
void DCSCodec::transmit() void DCS::transmit()
{ {
unsigned char ambe[9]; unsigned char ambe[9];
uint8_t ambe_frame[72]; uint8_t ambe_frame[72];
@ -413,7 +413,7 @@ void DCSCodec::transmit()
} }
} }
void DCSCodec::send_frame(uint8_t *ambe) void DCS::send_frame(uint8_t *ambe)
{ {
QByteArray txdata; QByteArray txdata;
static uint16_t txstreamid = 0; static uint16_t txstreamid = 0;
@ -533,7 +533,7 @@ void DCSCodec::send_frame(uint8_t *ambe)
#endif #endif
} }
void DCSCodec::get_ambe() void DCS::get_ambe()
{ {
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
uint8_t ambe[9]; uint8_t ambe[9];
@ -546,7 +546,7 @@ void DCSCodec::get_ambe()
#endif #endif
} }
void DCSCodec::process_rx_data() void DCS::process_rx_data()
{ {
int16_t pcm[160]; int16_t pcm[160];
uint8_t ambe[9]; uint8_t ambe[9];
@ -605,6 +605,7 @@ void DCSCodec::process_rx_data()
m_modeinfo.streamid = 0; m_modeinfo.streamid = 0;
m_rxcodecq.clear(); m_rxcodecq.clear();
qDebug() << "DCS playback stopped"; qDebug() << "DCS playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
return; return;
} }
} }

@ -15,17 +15,17 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef DCSCODEC_H #ifndef DCS_H
#define DCSCODEC_H #define DCS_H
#include "codec.h" #include "mode.h"
class DCSCodec : public Codec class DCS : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
DCSCodec(QString callsign, QString hostname, char module, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout); DCS();
~DCSCodec(); ~DCS();
unsigned char * get_frame(unsigned char *ambe); unsigned char * get_frame(unsigned char *ambe);
private: private:
QString m_txusrtxt; QString m_txusrtxt;
@ -47,4 +47,4 @@ private slots:
void send_frame(uint8_t *); void send_frame(uint8_t *);
}; };
#endif // DCSCODEC_H #endif // DCS_H

@ -17,14 +17,14 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include "dmrcodec.h" #include "dmr.h"
#include "cgolay2087.h" #include "cgolay2087.h"
#include "crs129.h" #include "crs129.h"
#include "SHA256.h" #include "SHA256.h"
#include "CRCenc.h" #include "CRCenc.h"
#include "MMDVMDefines.h" #include "MMDVMDefines.h"
//#define DEBUG #define DEBUG
const uint32_t ENCODING_TABLE_1676[] = const uint32_t ENCODING_TABLE_1676[] =
{0x0000U, 0x0273U, 0x04E5U, 0x0696U, 0x09C9U, 0x0BBAU, 0x0D2CU, 0x0F5FU, 0x11E2U, 0x1391U, 0x1507U, 0x1774U, {0x0000U, 0x0273U, 0x04E5U, 0x0696U, 0x09C9U, 0x0BBAU, 0x0D2CU, 0x0F5FU, 0x11E2U, 0x1391U, 0x1507U, 0x1774U,
@ -39,39 +39,41 @@ const uint32_t ENCODING_TABLE_1676[] =
0xD97AU, 0xDB09U, 0xDD9FU, 0xDFECU, 0xE0E6U, 0xE295U, 0xE403U, 0xE670U, 0xE92FU, 0xEB5CU, 0xEDCAU, 0xEFB9U, 0xD97AU, 0xDB09U, 0xDD9FU, 0xDFECU, 0xE0E6U, 0xE295U, 0xE403U, 0xE670U, 0xE92FU, 0xEB5CU, 0xEDCAU, 0xEFB9U,
0xF104U, 0xF377U, 0xF5E1U, 0xF792U, 0xF8CDU, 0xFABEU, 0xFC28U, 0xFE5BU}; 0xF104U, 0xF377U, 0xF5E1U, 0xF792U, 0xF8CDU, 0xFABEU, 0xFC28U, 0xFE5BU};
DMRCodec::DMRCodec(QString callsign, uint32_t dmrid, uint8_t essid, QString password, QString lat, QString lon, QString location, QString desc, QString freq, QString url, QString swid, QString pkid, QString options, uint32_t dstid, QString host, uint32_t port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout) : DMR::DMR() :
Codec(callsign, 0, NULL, host, port, ipv6, vocoder, modem, audioin, audioout, 5),
m_dmrid(dmrid),
m_password(password),
m_lat(lat),
m_lon(lon),
m_location(location),
m_desc(desc),
m_freq(freq),
m_url(url),
m_swid(swid),
m_pkid(pkid),
m_txdstid(dstid),
m_txslot(2), m_txslot(2),
m_txcc(1), m_txcc(1)
m_options(options)
{ {
m_dmrcnt = 0; m_dmrcnt = 0;
m_flco = FLCO_GROUP; m_flco = FLCO_GROUP;
m_attenuation = 5;
}
DMR::~DMR()
{
}
void DMR::set_dmr_params(uint8_t essid, QString password, QString lat, QString lon, QString location, QString desc, QString freq, QString url, QString swid, QString pkid, QString options)
{
if (essid){ if (essid){
m_essid = m_dmrid * 100 + (essid-1); m_essid = m_dmrid * 100 + (essid-1);
} }
else{ else{
m_essid = m_dmrid; m_essid = m_dmrid;
} }
}
DMRCodec::~DMRCodec() m_password = password;
{ m_lat = lat;
m_lon = lon;
m_location = location;
m_desc = desc;
m_freq = freq;
m_url = url;
m_swid = swid;
m_pkid = pkid;
m_options = options;
} }
void DMRCodec::process_udp() void DMR::process_udp()
{ {
QByteArray buf; QByteArray buf;
QByteArray in; QByteArray in;
@ -290,7 +292,7 @@ void DMRCodec::process_udp()
#endif #endif
} }
void DMRCodec::setup_connection() void DMR::setup_connection()
{ {
m_modeinfo.status = CONNECTED_RW; m_modeinfo.status = CONNECTED_RW;
//m_mbeenc->set_gain_adjust(2.5); //m_mbeenc->set_gain_adjust(2.5);
@ -331,7 +333,7 @@ void DMRCodec::setup_connection()
m_audio->init(); m_audio->init();
} }
void DMRCodec::hostname_lookup(QHostInfo i) void DMR::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
@ -358,7 +360,7 @@ void DMRCodec::hostname_lookup(QHostInfo i)
} }
} }
void DMRCodec::send_ping() void DMR::send_ping()
{ {
QByteArray out; QByteArray out;
char tag[] = { 'R','P','T','P','I','N','G' }; char tag[] = { 'R','P','T','P','I','N','G' };
@ -378,7 +380,7 @@ void DMRCodec::send_ping()
#endif #endif
} }
void DMRCodec::send_disconnect() void DMR::send_disconnect()
{ {
QByteArray out; QByteArray out;
out.append('R'); out.append('R');
@ -401,7 +403,7 @@ void DMRCodec::send_disconnect()
#endif #endif
} }
void DMRCodec::process_modem_data(QByteArray d) void DMR::process_modem_data(QByteArray d)
{ {
QByteArray txdata; QByteArray txdata;
uint8_t lcData[12U]; uint8_t lcData[12U];
@ -445,7 +447,7 @@ void DMRCodec::process_modem_data(QByteArray d)
#endif #endif
} }
void DMRCodec::transmit() void DMR::transmit()
{ {
uint8_t ambe[72]; uint8_t ambe[72];
int16_t pcm[160]; int16_t pcm[160];
@ -496,7 +498,7 @@ void DMRCodec::transmit()
} }
} }
void DMRCodec::send_frame() void DMR::send_frame()
{ {
QByteArray txdata; QByteArray txdata;
@ -565,14 +567,14 @@ void DMRCodec::send_frame()
#endif #endif
} }
unsigned char * DMRCodec::get_eot() unsigned char * DMR::get_eot()
{ {
encode_header(DT_TERMINATOR_WITH_LC); encode_header(DT_TERMINATOR_WITH_LC);
m_dmrcnt = 0; m_dmrcnt = 0;
return m_dmrFrame; return m_dmrFrame;
} }
void DMRCodec::build_frame() void DMR::build_frame()
{ {
//qDebug() << "DMR: slot:cc == " << m_txslot << ":" << m_txcc; //qDebug() << "DMR: slot:cc == " << m_txslot << ":" << m_txcc;
m_dmrFrame[0U] = 'D'; m_dmrFrame[0U] = 'D';
@ -614,14 +616,14 @@ void DMRCodec::build_frame()
m_modeinfo.frame_number = m_dmrcnt; m_modeinfo.frame_number = m_dmrcnt;
} }
void DMRCodec::encode_header(uint8_t t) void DMR::encode_header(uint8_t t)
{ {
addDMRDataSync(m_dmrFrame+20, 0); addDMRDataSync(m_dmrFrame+20, 0);
m_dataType = t; m_dataType = t;
full_lc_encode(m_dmrFrame+20, t); full_lc_encode(m_dmrFrame+20, t);
} }
void DMRCodec::encode_data() void DMR::encode_data()
{ {
unsigned int n_dmr = (m_dmrcnt - 1) % 6U; unsigned int n_dmr = (m_dmrcnt - 1) % 6U;
@ -637,7 +639,7 @@ void DMRCodec::encode_data()
} }
} }
void DMRCodec::encode16114(bool* d) void DMR::encode16114(bool* d)
{ {
d[11] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8]; d[11] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8];
d[12] = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[9]; d[12] = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[9];
@ -646,7 +648,7 @@ void DMRCodec::encode16114(bool* d)
d[15] = d[0] ^ d[2] ^ d[5] ^ d[6] ^ d[8] ^ d[9] ^ d[10]; d[15] = d[0] ^ d[2] ^ d[5] ^ d[6] ^ d[8] ^ d[9] ^ d[10];
} }
void DMRCodec::encode_qr1676(uint8_t* data) void DMR::encode_qr1676(uint8_t* data)
{ {
uint32_t value = (data[0U] >> 1) & 0x7FU; uint32_t value = (data[0U] >> 1) & 0x7FU;
uint32_t cksum = ENCODING_TABLE_1676[value]; uint32_t cksum = ENCODING_TABLE_1676[value];
@ -655,7 +657,7 @@ void DMRCodec::encode_qr1676(uint8_t* data)
data[1U] = cksum & 0xFFU; data[1U] = cksum & 0xFFU;
} }
void DMRCodec::get_emb_data(uint8_t* data, uint8_t lcss) void DMR::get_emb_data(uint8_t* data, uint8_t lcss)
{ {
uint8_t DMREMB[2U]; uint8_t DMREMB[2U];
DMREMB[0U] = (m_modeinfo.cc << 4) & 0xF0U; DMREMB[0U] = (m_modeinfo.cc << 4) & 0xF0U;
@ -671,7 +673,7 @@ void DMRCodec::get_emb_data(uint8_t* data, uint8_t lcss)
data[19U] = (data[19U] & 0x0FU) | ((DMREMB[1U] << 4U) & 0xF0U); data[19U] = (data[19U] & 0x0FU) | ((DMREMB[1U] << 4U) & 0xF0U);
} }
uint8_t DMRCodec::get_embedded_data(uint8_t* data, uint8_t n) uint8_t DMR::get_embedded_data(uint8_t* data, uint8_t n)
{ {
if (n >= 1U && n < 5U) { if (n >= 1U && n < 5U) {
n--; n--;
@ -712,7 +714,7 @@ uint8_t DMRCodec::get_embedded_data(uint8_t* data, uint8_t n)
} }
} }
void DMRCodec::encode_embedded_data() void DMR::encode_embedded_data()
{ {
uint32_t crc; uint32_t crc;
lc_get_data(m_data); lc_get_data(m_data);
@ -761,7 +763,7 @@ void DMRCodec::encode_embedded_data()
} }
} }
void DMRCodec::bitsToByteBE(const bool* bits, uint8_t& byte) void DMR::bitsToByteBE(const bool* bits, uint8_t& byte)
{ {
byte = bits[0U] ? 0x80U : 0x00U; byte = bits[0U] ? 0x80U : 0x00U;
byte |= bits[1U] ? 0x40U : 0x00U; byte |= bits[1U] ? 0x40U : 0x00U;
@ -773,7 +775,7 @@ void DMRCodec::bitsToByteBE(const bool* bits, uint8_t& byte)
byte |= bits[7U] ? 0x01U : 0x00U; byte |= bits[7U] ? 0x01U : 0x00U;
} }
void DMRCodec::byteToBitsBE(uint8_t byte, bool* bits) void DMR::byteToBitsBE(uint8_t byte, bool* bits)
{ {
bits[0U] = (byte & 0x80U) == 0x80U; bits[0U] = (byte & 0x80U) == 0x80U;
bits[1U] = (byte & 0x40U) == 0x40U; bits[1U] = (byte & 0x40U) == 0x40U;
@ -785,7 +787,7 @@ void DMRCodec::byteToBitsBE(uint8_t byte, bool* bits)
bits[7U] = (byte & 0x01U) == 0x01U; bits[7U] = (byte & 0x01U) == 0x01U;
} }
void DMRCodec::lc_get_data(bool* bits) void DMR::lc_get_data(bool* bits)
{ {
uint8_t bytes[9U]; uint8_t bytes[9U];
memset(bytes, 0, 9); memset(bytes, 0, 9);
@ -802,7 +804,7 @@ void DMRCodec::lc_get_data(bool* bits)
byteToBitsBE(bytes[8U], bits + 64U); byteToBitsBE(bytes[8U], bits + 64U);
} }
void DMRCodec::lc_get_data(uint8_t *bytes) void DMR::lc_get_data(uint8_t *bytes)
{ {
bool pf, r; bool pf, r;
uint8_t fid, options; uint8_t fid, options;
@ -832,7 +834,7 @@ void DMRCodec::lc_get_data(uint8_t *bytes)
bytes[8U] = m_dmrid >> 0; bytes[8U] = m_dmrid >> 0;
} }
void DMRCodec::full_lc_encode(uint8_t* data, uint8_t type) // for header void DMR::full_lc_encode(uint8_t* data, uint8_t type) // for header
{ {
uint8_t lcData[12U]; uint8_t lcData[12U];
uint8_t parity[4U]; uint8_t parity[4U];
@ -861,7 +863,7 @@ void DMRCodec::full_lc_encode(uint8_t* data, uint8_t type) // for header
m_bptc.encode(lcData, data); m_bptc.encode(lcData, data);
} }
void DMRCodec::get_slot_data(uint8_t* data) void DMR::get_slot_data(uint8_t* data)
{ {
uint8_t DMRSlotType[3U]; uint8_t DMRSlotType[3U];
DMRSlotType[0U] = (m_modeinfo.cc << 4) & 0xF0U; DMRSlotType[0U] = (m_modeinfo.cc << 4) & 0xF0U;
@ -878,7 +880,7 @@ void DMRCodec::get_slot_data(uint8_t* data)
} }
void DMRCodec::addDMRDataSync(uint8_t* data, bool duplex) void DMR::addDMRDataSync(uint8_t* data, bool duplex)
{ {
if (duplex) { if (duplex) {
for (uint32_t i = 0U; i < 7U; i++) for (uint32_t i = 0U; i < 7U; i++)
@ -889,7 +891,7 @@ void DMRCodec::addDMRDataSync(uint8_t* data, bool duplex)
} }
} }
void DMRCodec::addDMRAudioSync(uint8_t* data, bool duplex) void DMR::addDMRAudioSync(uint8_t* data, bool duplex)
{ {
if (duplex) { if (duplex) {
for (uint32_t i = 0U; i < 7U; i++) for (uint32_t i = 0U; i < 7U; i++)
@ -900,7 +902,7 @@ void DMRCodec::addDMRAudioSync(uint8_t* data, bool duplex)
} }
} }
void DMRCodec::get_ambe() void DMR::get_ambe()
{ {
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
uint8_t ambe[9]; uint8_t ambe[9];
@ -913,7 +915,7 @@ void DMRCodec::get_ambe()
#endif #endif
} }
void DMRCodec::process_rx_data() void DMR::process_rx_data()
{ {
int16_t pcm[160]; int16_t pcm[160];
uint8_t ambe[9]; uint8_t ambe[9];
@ -974,6 +976,7 @@ void DMRCodec::process_rx_data()
m_modeinfo.streamid = 0; m_modeinfo.streamid = 0;
m_rxcodecq.clear(); m_rxcodecq.clear();
qDebug() << "DMR playback stopped"; qDebug() << "DMR playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
return; return;
} }
} }

@ -15,21 +15,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef DMRCODEC_H #ifndef DMR_H
#define DMRCODEC_H #define DMR_H
#include "codec.h" #include "mode.h"
//#include <inttypes.h> #include "DMRDefines.h"
#include "DMRData.h"
#include "cbptc19696.h" #include "cbptc19696.h"
class DMRCodec : public Codec class DMR : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
DMRCodec(QString callsign, uint32_t dmrid, uint8_t essid, QString password, QString lat, QString lon, QString location, QString desc, QString freq, QString url, QString swid, QString pkid, QString options, uint32_t dstid, QString host, uint32_t port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout); DMR();
~DMRCodec(); ~DMR();
unsigned char * get_eot(); void set_dmr_params(uint8_t essid, QString password, QString lat, QString lon, QString location, QString desc, QString freq, QString url, QString swid, QString pkid, QString options);
uint8_t * get_eot();
private slots: private slots:
void process_udp(); void process_udp();
void process_rx_data(); void process_rx_data();
@ -39,13 +39,12 @@ private slots:
void send_disconnect(); void send_disconnect();
void transmit(); void transmit();
void hostname_lookup(QHostInfo i); void hostname_lookup(QHostInfo i);
void dmr_tgid_changed(unsigned int id) { m_txdstid = id; } void dmr_tgid_changed(int id) { m_txdstid = id; }
void dmrpc_state_changed(int p){m_flco = p ? FLCO_USER_USER : FLCO_GROUP; } void dmrpc_state_changed(int p){m_flco = p ? FLCO_USER_USER : FLCO_GROUP; }
void cc_changed(int cc) {m_txcc = cc + 1; } void cc_changed(int cc) {m_txcc = cc + 1; }
void slot_changed(int s) {m_txslot = s + 1; } void slot_changed(int s) {m_txslot = s + 1; }
void send_frame(); void send_frame();
private: private:
uint32_t m_dmrid;
uint32_t m_essid; uint32_t m_essid;
QString m_password; QString m_password;
QString m_lat; QString m_lat;
@ -92,4 +91,4 @@ private:
void setup_connection(); void setup_connection();
}; };
#endif // DMRCODEC_H #endif // DMR_H

File diff suppressed because it is too large Load Diff

@ -20,15 +20,7 @@
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include "refcodec.h" #include "mode.h"
#include "dcscodec.h"
#include "xrfcodec.h"
#include "ysfcodec.h"
#include "dmrcodec.h"
#include "p25codec.h"
#include "nxdncodec.h"
#include "m17codec.h"
#include "iaxcodec.h"
class DroidStar : public QObject class DroidStar : public QObject
{ {
@ -54,7 +46,7 @@ signals:
void tx_released(); void tx_released();
void tx_clicked(bool); void tx_clicked(bool);
void dmrpc_state_changed(int); void dmrpc_state_changed(int);
void dmr_tgid_changed(unsigned int); void dmr_tgid_changed(int);
void m17_rate_changed(int); void m17_rate_changed(int);
void m17_can_changed(int); void m17_can_changed(int);
void send_dtmf(QByteArray); void send_dtmf(QByteArray);
@ -70,7 +62,7 @@ signals:
void urcall_changed(QString); void urcall_changed(QString);
void usrtxt_changed(QString); void usrtxt_changed(QString);
public slots: public slots:
void set_callsign(const QString &callsign) { m_callsign = callsign.simplified(); save_settings(); } void set_callsign(const QString &callsign) { m_callsign = callsign.simplified(); save_settings(); }
void set_dmrtgid(const QString &dmrtgid) { m_dmr_destid = dmrtgid.simplified().toUInt(); save_settings(); } void set_dmrtgid(const QString &dmrtgid) { m_dmr_destid = dmrtgid.simplified().toUInt(); save_settings(); }
void set_slot(const int slot) {emit slot_changed(slot); } void set_slot(const int slot) {emit slot_changed(slot); }
void set_cc(const int cc) {emit cc_changed(cc); } void set_cc(const int cc) {emit cc_changed(cc); }
@ -271,7 +263,7 @@ private:
QString hosts_filename; QString hosts_filename;
QString m_callsign; QString m_callsign;
QString m_host; QString m_host;
QString m_hostname; QString m_refname;
QString m_protocol; QString m_protocol;
QString m_bm_password; QString m_bm_password;
QString m_tgif_password; QString m_tgif_password;
@ -328,15 +320,7 @@ private:
QMap<QString, QString> m_hostmap; QMap<QString, QString> m_hostmap;
QStringList m_customhosts; QStringList m_customhosts;
QThread *m_modethread; QThread *m_modethread;
REFCodec *m_ref; Mode *m_mode;
DCSCodec *m_dcs;
XRFCodec *m_xrf;
YSFCodec *m_ysf;
DMRCodec *m_dmr;
P25Codec *m_p25;
NXDNCodec *m_nxdn;
M17Codec *m_m17;
IAXCodec *m_iax;
QByteArray user_data; QByteArray user_data;
QString m_iaxuser; QString m_iaxuser;
QString m_iaxpassword; QString m_iaxpassword;
@ -401,15 +385,7 @@ private slots:
void process_m17_hosts(); void process_m17_hosts();
void process_dmr_ids(); void process_dmr_ids();
void process_nxdn_ids(); void process_nxdn_ids();
void update_dmr_data(Codec::MODEINFO); void update_data(Mode::MODEINFO);
void update_ref_data(Codec::MODEINFO);
void update_dcs_data(Codec::MODEINFO);
void update_xrf_data(Codec::MODEINFO);
void update_nxdn_data(Codec::MODEINFO);
void update_p25_data(Codec::MODEINFO);
void update_ysf_data(Codec::MODEINFO);
void update_m17_data(Codec::MODEINFO);
void update_iax_data();
void save_settings(); void save_settings();
void update_output_level(unsigned short l){ m_outlevel = l;} void update_output_level(unsigned short l){ m_outlevel = l;}
//void load_md380_fw(); //void load_md380_fw();

@ -15,14 +15,14 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "iaxcodec.h" #include "iax.h"
#include "iaxdefines.h" #include "iaxdefines.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <winsock2.h> #include <winsock2.h>
#else #else
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
//#define DEBUG #define DEBUG
#ifdef USE_FLITE #ifdef USE_FLITE
extern "C" { extern "C" {
@ -32,19 +32,11 @@ extern cst_voice * register_cmu_us_awb(const char *);
} }
#endif #endif
IAXCodec::IAXCodec(QString callsign, QString username, QString password, QString node, QString host, int port, QString audioin, QString audioout) : IAX::IAX() :
m_callsign(callsign),
m_username(username),
m_password(password),
m_node(node),
m_host(host),
m_port(port),
m_scallno(0), m_scallno(0),
m_dcallno(0), m_dcallno(0),
m_regscallno(0x7fff), m_regscallno(0x7fff),
m_regdcallno(0), m_regdcallno(0),
m_audioin(audioin),
m_audioout(audioout),
m_iseq(0), m_iseq(0),
m_oseq(0), m_oseq(0),
m_tx(false), m_tx(false),
@ -63,6 +55,20 @@ IAXCodec::IAXCodec(QString callsign, QString username, QString password, QString
voice_kal = register_cmu_us_kal16(nullptr); voice_kal = register_cmu_us_kal16(nullptr);
voice_awb = register_cmu_us_awb(nullptr); voice_awb = register_cmu_us_awb(nullptr);
#endif #endif
}
IAX::~IAX()
{
}
void IAX::set_iax_params(QString username, QString password, QString node, QString host, int port)
{
m_username = username;
m_password = password;
m_node = node;
m_host = host;
m_port = port;
QStringList l = m_node.split('@'); QStringList l = m_node.split('@');
if(l.size() == 2){ if(l.size() == 2){
m_node = l.at(0).simplified(); m_node = l.at(0).simplified();
@ -73,10 +79,6 @@ IAXCodec::IAXCodec(QString callsign, QString username, QString password, QString
} }
} }
IAXCodec::~IAXCodec()
{
}
int16_t ulaw_decode(int8_t number) int16_t ulaw_decode(int8_t number)
{ {
const uint16_t MULAW_BIAS = 33; const uint16_t MULAW_BIAS = 33;
@ -118,7 +120,7 @@ int8_t ulaw_encode(int16_t number)
return (~(sign | ((position - 5) << 4) | lsb)); return (~(sign | ((position - 5) << 4) | lsb));
} }
void IAXCodec::send_call() void IAX::send_call()
{ {
uint16_t scall = htons(++m_scallno | 0x8000); uint16_t scall = htons(++m_scallno | 0x8000);
m_oseq = m_iseq = 0; m_oseq = m_iseq = 0;
@ -167,7 +169,7 @@ void IAXCodec::send_call()
#endif #endif
} }
void IAXCodec::send_call_auth() void IAX::send_call_auth()
{ {
QByteArray out; QByteArray out;
m_md5seed.append(m_password.toUtf8()); m_md5seed.append(m_password.toUtf8());
@ -197,7 +199,7 @@ void IAXCodec::send_call_auth()
#endif #endif
} }
void IAXCodec::send_dtmf(QByteArray dtmf) void IAX::send_dtmf(QByteArray dtmf)
{ {
QByteArray out; QByteArray out;
uint16_t scall = htons(m_scallno | 0x8000); uint16_t scall = htons(m_scallno | 0x8000);
@ -225,7 +227,7 @@ void IAXCodec::send_dtmf(QByteArray dtmf)
} }
} }
void IAXCodec::send_radio_key(bool key) void IAX::send_radio_key(bool key)
{ {
QByteArray out; QByteArray out;
uint16_t scall = htons(m_scallno | 0x8000); uint16_t scall = htons(m_scallno | 0x8000);
@ -250,7 +252,7 @@ void IAXCodec::send_radio_key(bool key)
#endif #endif
} }
void IAXCodec::send_ping() void IAX::send_ping()
{ {
QByteArray out; QByteArray out;
uint16_t scall = htons(m_scallno | 0x8000); uint16_t scall = htons(m_scallno | 0x8000);
@ -275,7 +277,7 @@ void IAXCodec::send_ping()
#endif #endif
} }
void IAXCodec::send_pong() void IAX::send_pong()
{ {
QByteArray out; QByteArray out;
uint16_t scall = htons(m_scallno | 0x8000); uint16_t scall = htons(m_scallno | 0x8000);
@ -324,7 +326,7 @@ void IAXCodec::send_pong()
#endif #endif
} }
void IAXCodec::send_ack(uint16_t scall, uint16_t dcall, uint8_t oseq, uint8_t iseq) void IAX::send_ack(uint16_t scall, uint16_t dcall, uint8_t oseq, uint8_t iseq)
{ {
QByteArray out; QByteArray out;
scall = htons(scall | 0x8000); scall = htons(scall | 0x8000);
@ -349,7 +351,7 @@ void IAXCodec::send_ack(uint16_t scall, uint16_t dcall, uint8_t oseq, uint8_t is
#endif #endif
} }
void IAXCodec::send_lag_response() void IAX::send_lag_response()
{ {
QByteArray out; QByteArray out;
uint16_t scall = htons(m_scallno | 0x8000); uint16_t scall = htons(m_scallno | 0x8000);
@ -374,7 +376,7 @@ void IAXCodec::send_lag_response()
#endif #endif
} }
void IAXCodec::send_voice_frame(int16_t *f) void IAX::send_voice_frame(int16_t *f)
{ {
QByteArray out; QByteArray out;
uint16_t scall = htons(m_scallno | 0x8000); uint16_t scall = htons(m_scallno | 0x8000);
@ -404,7 +406,7 @@ void IAXCodec::send_voice_frame(int16_t *f)
#endif #endif
} }
void IAXCodec::send_registration(uint16_t dcall) void IAX::send_registration(uint16_t dcall)
{ {
//static qint64 time = QDateTime::currentMSecsSinceEpoch(); //static qint64 time = QDateTime::currentMSecsSinceEpoch();
uint32_t ts; uint32_t ts;
@ -459,7 +461,7 @@ void IAXCodec::send_registration(uint16_t dcall)
#endif #endif
} }
void IAXCodec::send_disconnect() void IAX::send_disconnect()
{ {
QByteArray out; QByteArray out;
uint16_t scall = htons(m_scallno | 0x8000); uint16_t scall = htons(m_scallno | 0x8000);
@ -487,7 +489,7 @@ void IAXCodec::send_disconnect()
#endif #endif
} }
void IAXCodec::hostname_lookup(QHostInfo i) void IAX::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
m_address = i.addresses().first(); m_address = i.addresses().first();
@ -501,14 +503,14 @@ void IAXCodec::hostname_lookup(QHostInfo i)
} }
} }
void IAXCodec::send_connect() void IAX::send_connect()
{ {
m_status = CONNECTING; m_modeinfo.status = CONNECTING;
qDebug() << "lookup IP = " << m_host << ":" << m_port; qDebug() << "lookup IP = " << m_host << ":" << m_port;
QHostInfo::lookupHost(m_host, this, SLOT(hostname_lookup(QHostInfo))); QHostInfo::lookupHost(m_host, this, SLOT(hostname_lookup(QHostInfo)));
} }
void IAXCodec::process_udp() void IAX::process_udp()
{ {
QByteArray buf; QByteArray buf;
QHostAddress sender; QHostAddress sender;
@ -545,7 +547,7 @@ void IAXCodec::process_udp()
uint16_t dcallno = (((buf.data()[0] & 0x7f) << 8) | ((uint8_t)buf.data()[1])); uint16_t dcallno = (((buf.data()[0] & 0x7f) << 8) | ((uint8_t)buf.data()[1]));
uint16_t scallno = (((buf.data()[2] & 0x7f) << 8) | ((uint8_t)buf.data()[3])); uint16_t scallno = (((buf.data()[2] & 0x7f) << 8) | ((uint8_t)buf.data()[3]));
send_ack(scallno, dcallno, 2, 2); send_ack(scallno, dcallno, 2, 2);
if(m_status == CONNECTING){ if(m_modeinfo.status == CONNECTING){
send_call(); send_call();
} }
} }
@ -553,7 +555,7 @@ void IAXCodec::process_udp()
(buf.data()[10] == AST_FRAME_IAX) && (buf.data()[10] == AST_FRAME_IAX) &&
(buf.data()[11] == IAX_COMMAND_REGREJ) ) (buf.data()[11] == IAX_COMMAND_REGREJ) )
{ {
m_status = DISCONNECTED; m_modeinfo.status = DISCONNECTED;
} }
else if( (buf.data()[0] & 0x80) && else if( (buf.data()[0] & 0x80) &&
(buf.data()[10] == AST_FRAME_IAX) && (buf.data()[10] == AST_FRAME_IAX) &&
@ -595,7 +597,7 @@ void IAXCodec::process_udp()
(buf.data()[10] == AST_FRAME_IAX) && (buf.data()[10] == AST_FRAME_IAX) &&
(buf.data()[11] == IAX_COMMAND_REJECT) ) (buf.data()[11] == IAX_COMMAND_REJECT) )
{ {
m_status = DISCONNECTED; m_modeinfo.status = DISCONNECTED;
} }
else if( (buf.data()[0] & 0x80) && else if( (buf.data()[0] & 0x80) &&
(buf.data()[10] == AST_FRAME_CONTROL) && (buf.data()[10] == AST_FRAME_CONTROL) &&
@ -614,8 +616,8 @@ void IAXCodec::process_udp()
(buf.data()[10] == AST_FRAME_CONTROL) && (buf.data()[10] == AST_FRAME_CONTROL) &&
(buf.data()[11] == AST_CONTROL_ANSWER) ) (buf.data()[11] == AST_CONTROL_ANSWER) )
{ {
if(m_status == CONNECTING){ if(m_modeinfo.status == CONNECTING){
m_status = CONNECTED_RW; m_modeinfo.status = CONNECTED_RW;
m_txtimer = new QTimer(); m_txtimer = new QTimer();
connect(m_txtimer, SIGNAL(timeout()), this, SLOT(transmit())); connect(m_txtimer, SIGNAL(timeout()), this, SLOT(transmit()));
m_rxtimer = new QTimer(); m_rxtimer = new QTimer();
@ -726,10 +728,10 @@ void IAXCodec::process_udp()
} }
} }
} }
emit update(); emit update(m_modeinfo);
} }
void IAXCodec::process_rx_data() void IAX::process_rx_data()
{ {
int16_t pcm[160]; int16_t pcm[160];
@ -743,13 +745,13 @@ void IAXCodec::process_rx_data()
else return; else return;
} }
void IAXCodec::toggle_tx(bool tx) void IAX::toggle_tx(bool tx)
{ {
qDebug() << "IAXCodec::toggle_tx(bool tx) == " << tx; qDebug() << "IAXCodec::toggle_tx(bool tx) == " << tx;
tx ? start_tx() : stop_tx(); tx ? start_tx() : stop_tx();
} }
void IAXCodec::start_tx() void IAX::start_tx()
{ {
//std::cerr << "Pressed TX buffersize == " << audioin->bufferSize() << std::endl; //std::cerr << "Pressed TX buffersize == " << audioin->bufferSize() << std::endl;
//QByteArray tx("*99", 3); //QByteArray tx("*99", 3);
@ -771,7 +773,7 @@ void IAXCodec::start_tx()
#endif #endif
} }
void IAXCodec::stop_tx() void IAX::stop_tx()
{ {
m_tx = false; m_tx = false;
send_radio_key(false); send_radio_key(false);
@ -779,7 +781,7 @@ void IAXCodec::stop_tx()
//send_dtmf(tx); //send_dtmf(tx);
} }
void IAXCodec::transmit() void IAX::transmit()
{ {
QByteArray out; QByteArray out;
int16_t pcm[160]; int16_t pcm[160];
@ -825,9 +827,9 @@ void IAXCodec::transmit()
#endif #endif
} }
void IAXCodec::deleteLater() void IAX::deleteLater()
{ {
if(m_status == CONNECTED_RW){ if(m_modeinfo.status == CONNECTED_RW){
m_udp->disconnect(); m_udp->disconnect();
m_txtimer->stop(); m_txtimer->stop();
m_rxtimer->stop(); m_rxtimer->stop();

@ -15,29 +15,22 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef IAXCODEC_H #ifndef IAX_H
#define IAXCODEC_H #define IAX_H
#include <QObject> #include "mode.h"
#include <QtNetwork>
#include "audioengine.h"
#ifdef USE_FLITE
#include <flite/flite.h>
#endif
class IAXCodec : public QObject class IAX : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
IAXCodec(QString callsign, QString username, QString password, QString node, QString host, int port, QString audioin, QString audioout); IAX();//QString callsign, QString username, QString password, QString node, QString host, int port, QString audioin, QString audioout);
~IAXCodec(); ~IAX();
uint8_t get_status(){ return m_status; } void set_iax_params(QString username, QString password, QString node, QString host, int port);
//uint8_t get_status(){ return m_status; }
QString get_host() { return m_host; } QString get_host() { return m_host; }
int get_port() { return m_port; } int get_port() { return m_port; }
int get_cnt() { return m_cnt; } int get_cnt() { return m_cnt; }
signals:
void update();
void update_output_level(unsigned short);
private slots: private slots:
void deleteLater(); void deleteLater();
void process_udp(); void process_udp();
@ -62,16 +55,6 @@ private slots:
void in_audio_vol_changed(qreal v){ m_audio->set_input_volume(v); } void in_audio_vol_changed(qreal v){ m_audio->set_input_volume(v); }
void out_audio_vol_changed(qreal v){ m_audio->set_output_volume(v); } void out_audio_vol_changed(qreal v){ m_audio->set_output_volume(v); }
private: private:
enum{
DISCONNECTED,
CLOSED,
CONNECTING,
DMR_AUTH,
DMR_CONF,
DMR_OPTS,
CONNECTED_RW,
CONNECTED_RO
} m_status;
QUdpSocket *m_udp = nullptr; QUdpSocket *m_udp = nullptr;
QHostAddress m_address; QHostAddress m_address;
QString m_callsign; QString m_callsign;
@ -119,4 +102,4 @@ private:
#endif #endif
}; };
#endif // IAXCODEC_H #endif // IAX_H

@ -19,14 +19,14 @@
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include "MMDVMDefines.h" #include "MMDVMDefines.h"
#include "m17codec.h" #include "m17.h"
#include "M17Defines.h" #include "M17Defines.h"
#include "M17Convolution.h" #include "M17Convolution.h"
#include "Golay24128.h" #include "Golay24128.h"
#define M17CHARACTERS " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/." #define M17CHARACTERS " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/."
//#define DEBUG #define DEBUG
const uint8_t SCRAMBLER[] = { const uint8_t SCRAMBLER[] = {
0x00U, 0x00U, 0xD6U, 0xB5U, 0xE2U, 0x30U, 0x82U, 0xFFU, 0x84U, 0x62U, 0xBAU, 0x4EU, 0x96U, 0x90U, 0xD8U, 0x98U, 0xDDU, 0x00U, 0x00U, 0xD6U, 0xB5U, 0xE2U, 0x30U, 0x82U, 0xFFU, 0x84U, 0x62U, 0xBAU, 0x4EU, 0x96U, 0x90U, 0xD8U, 0x98U, 0xDDU,
@ -83,17 +83,10 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) #define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) #define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
M17Codec::M17Codec(QString callsign, char module, QString hostname, QString host, int port, bool ipv6, QString modem, QString audioin, QString audioout) : M17::M17() :
Codec(callsign, module, hostname, host, port, ipv6, NULL, modem, audioin, audioout, 1),
m_c2(NULL), m_c2(NULL),
m_txrate(1) m_txrate(1)
{ {
m_modeinfo.callsign = callsign;
m_modeinfo.host = host;
m_modeinfo.port = port;
m_modeinfo.count = 0;
m_modeinfo.frame_number = 0;
m_modeinfo.streamid = 0;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
m_txtimerint = 30; // Qt timers on windows seem to be slower than desired value m_txtimerint = 30; // Qt timers on windows seem to be slower than desired value
@ -101,13 +94,14 @@ M17Codec::M17Codec(QString callsign, char module, QString hostname, QString host
m_txtimerint = 36; m_txtimerint = 36;
m_txcan = 0; m_txcan = 0;
#endif #endif
m_attenuation = 1;
} }
M17Codec::~M17Codec() M17::~M17()
{ {
} }
void M17Codec::encode_callsign(uint8_t *callsign) void M17::encode_callsign(uint8_t *callsign)
{ {
const std::string m17_alphabet(M17CHARACTERS); const std::string m17_alphabet(M17CHARACTERS);
char cs[10]; char cs[10];
@ -127,7 +121,7 @@ void M17Codec::encode_callsign(uint8_t *callsign)
} }
} }
void M17Codec::decode_callsign(uint8_t *callsign) void M17::decode_callsign(uint8_t *callsign)
{ {
const std::string m17_alphabet(M17CHARACTERS); const std::string m17_alphabet(M17CHARACTERS);
uint8_t code[6]; uint8_t code[6];
@ -149,7 +143,7 @@ void M17Codec::decode_callsign(uint8_t *callsign)
} }
} }
void M17Codec::set_mode(bool m) void M17::set_mode(bool m)
{ {
#ifdef USE_EXTERNAL_CODEC2 #ifdef USE_EXTERNAL_CODEC2
if(m_c2){ if(m_c2){
@ -168,7 +162,7 @@ void M17Codec::set_mode(bool m)
#endif #endif
} }
bool M17Codec::get_mode() bool M17::get_mode()
{ {
bool m = true; bool m = true;
#ifdef USE_EXTERNAL_CODEC2 #ifdef USE_EXTERNAL_CODEC2
@ -185,7 +179,7 @@ bool M17Codec::get_mode()
#endif #endif
return m; return m;
} }
void M17Codec::decode_c2(int16_t *audio, uint8_t *c) void M17::decode_c2(int16_t *audio, uint8_t *c)
{ {
#ifdef USE_EXTERNAL_CODEC2 #ifdef USE_EXTERNAL_CODEC2
if(m_c2){ if(m_c2){
@ -196,7 +190,7 @@ void M17Codec::decode_c2(int16_t *audio, uint8_t *c)
#endif #endif
} }
void M17Codec::encode_c2(int16_t *audio, uint8_t *c) void M17::encode_c2(int16_t *audio, uint8_t *c)
{ {
#ifdef USE_EXTERNAL_CODEC2 #ifdef USE_EXTERNAL_CODEC2
if(m_c2){ if(m_c2){
@ -207,7 +201,7 @@ void M17Codec::encode_c2(int16_t *audio, uint8_t *c)
#endif #endif
} }
void M17Codec::process_udp() void M17::process_udp()
{ {
QByteArray buf; QByteArray buf;
QHostAddress sender; QHostAddress sender;
@ -334,7 +328,7 @@ void M17Codec::process_udp()
//emit update(m_modeinfo); //emit update(m_modeinfo);
} }
void M17Codec::hostname_lookup(QHostInfo i) void M17::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
@ -343,7 +337,7 @@ void M17Codec::hostname_lookup(QHostInfo i)
memcpy(cs, m_modeinfo.callsign.toLocal8Bit(), m_modeinfo.callsign.size()); memcpy(cs, m_modeinfo.callsign.toLocal8Bit(), m_modeinfo.callsign.size());
cs[8] = 'D'; cs[8] = 'D';
cs[9] = 0x00; cs[9] = 0x00;
M17Codec::encode_callsign(cs); M17::encode_callsign(cs);
out.append('C'); out.append('C');
out.append('O'); out.append('O');
out.append('N'); out.append('N');
@ -365,7 +359,7 @@ void M17Codec::hostname_lookup(QHostInfo i)
} }
} }
void M17Codec::mmdvm_direct_connect() void M17::mmdvm_direct_connect()
{ {
if(m_modemport != ""){ if(m_modemport != ""){
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
@ -396,7 +390,7 @@ void M17Codec::mmdvm_direct_connect()
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void M17Codec::send_ping() void M17::send_ping()
{ {
QByteArray out; QByteArray out;
uint8_t cs[10]; uint8_t cs[10];
@ -421,7 +415,7 @@ void M17Codec::send_ping()
#endif #endif
} }
void M17Codec::send_disconnect() void M17::send_disconnect()
{ {
if(m_modeinfo.host == "MMDVM_DIRECT"){ if(m_modeinfo.host == "MMDVM_DIRECT"){
return; return;
@ -451,7 +445,7 @@ void M17Codec::send_disconnect()
#endif #endif
} }
void M17Codec::send_modem_data(QByteArray d) void M17::send_modem_data(QByteArray d)
{ {
CM17Convolution conv; CM17Convolution conv;
static uint8_t lsf[M17_LSF_LENGTH_BYTES]; static uint8_t lsf[M17_LSF_LENGTH_BYTES];
@ -520,7 +514,7 @@ void M17Codec::send_modem_data(QByteArray d)
lsfcnt = 0U; lsfcnt = 0U;
} }
void M17Codec::process_modem_data(QByteArray d) void M17::process_modem_data(QByteArray d)
{ {
QByteArray txframe; QByteArray txframe;
static uint16_t txstreamid = 0; static uint16_t txstreamid = 0;
@ -689,7 +683,7 @@ void M17Codec::process_modem_data(QByteArray d)
uint8_t dst[10]; uint8_t dst[10];
memset(dst, ' ', 9); memset(dst, ' ', 9);
memcpy(dst, m_hostname.toLocal8Bit(), m_hostname.size()); memcpy(dst, m_refname.toLocal8Bit(), m_refname.size());
dst[8] = m_module; dst[8] = m_module;
dst[9] = 0x00; dst[9] = 0x00;
encode_callsign(dst); encode_callsign(dst);
@ -723,19 +717,19 @@ void M17Codec::process_modem_data(QByteArray d)
} }
} }
void M17Codec::toggle_tx(bool tx) void M17::toggle_tx(bool tx)
{ {
qDebug() << "M17Codec::toggle_tx(bool tx) == " << tx; qDebug() << "M17Codec::toggle_tx(bool tx) == " << tx;
tx ? start_tx() : stop_tx(); tx ? start_tx() : stop_tx();
} }
void M17Codec::start_tx() void M17::start_tx()
{ {
set_mode(m_txrate); set_mode(m_txrate);
Codec::start_tx(); Mode::start_tx();
} }
void M17Codec::transmit() void M17::transmit()
{ {
QByteArray txframe; QByteArray txframe;
static uint16_t txstreamid = 0; static uint16_t txstreamid = 0;
@ -803,7 +797,7 @@ void M17Codec::transmit()
uint8_t dst[10]; uint8_t dst[10];
uint8_t lsf[30]; uint8_t lsf[30];
memset(dst, ' ', 9); memset(dst, ' ', 9);
memcpy(dst, m_hostname.toLocal8Bit(), m_hostname.size()); memcpy(dst, m_refname.toLocal8Bit(), m_refname.size());
dst[8] = m_module; dst[8] = m_module;
dst[9] = 0x00; dst[9] = 0x00;
encode_callsign(dst); encode_callsign(dst);
@ -846,7 +840,7 @@ void M17Codec::transmit()
++tx_cnt; ++tx_cnt;
m_modeinfo.src = m_modeinfo.callsign; m_modeinfo.src = m_modeinfo.callsign;
m_modeinfo.dst = m_hostname; m_modeinfo.dst = m_refname;
m_modeinfo.type = get_mode(); m_modeinfo.type = get_mode();
m_modeinfo.frame_number = tx_cnt; m_modeinfo.frame_number = tx_cnt;
m_modeinfo.streamid = txstreamid; m_modeinfo.streamid = txstreamid;
@ -867,7 +861,7 @@ void M17Codec::transmit()
uint8_t src[10]; uint8_t src[10];
uint8_t dst[10]; uint8_t dst[10];
memset(dst, ' ', 9); memset(dst, ' ', 9);
memcpy(dst, m_hostname.toLocal8Bit(), m_hostname.size()); memcpy(dst, m_refname.toLocal8Bit(), m_refname.size());
dst[8] = m_module; dst[8] = m_module;
dst[9] = 0x00; dst[9] = 0x00;
encode_callsign(dst); encode_callsign(dst);
@ -875,7 +869,7 @@ void M17Codec::transmit()
memcpy(src, m_modeinfo.callsign.toLocal8Bit(), m_modeinfo.callsign.size()); memcpy(src, m_modeinfo.callsign.toLocal8Bit(), m_modeinfo.callsign.size());
src[8] = 'D'; src[8] = 'D';
src[9] = 0x00; src[9] = 0x00;
M17Codec::encode_callsign(src); M17::encode_callsign(src);
tx_cnt |= 0x8000u; tx_cnt |= 0x8000u;
txframe.append('M'); txframe.append('M');
@ -912,7 +906,7 @@ void M17Codec::transmit()
m_audio->stop_capture(); m_audio->stop_capture();
} }
m_modeinfo.src = m_modeinfo.callsign; m_modeinfo.src = m_modeinfo.callsign;
m_modeinfo.dst = m_hostname; m_modeinfo.dst = m_refname;
m_modeinfo.type = get_mode(); m_modeinfo.type = get_mode();
m_modeinfo.frame_number = tx_cnt; m_modeinfo.frame_number = tx_cnt;
m_modeinfo.streamid = txstreamid; m_modeinfo.streamid = txstreamid;
@ -928,7 +922,7 @@ void M17Codec::transmit()
} }
} }
void M17Codec::process_rx_data() void M17::process_rx_data()
{ {
int16_t pcm[320]; int16_t pcm[320];
uint8_t codec2[8]; uint8_t codec2[8];
@ -974,18 +968,19 @@ void M17Codec::process_rx_data()
m_rxcodecq.clear(); m_rxcodecq.clear();
m_rxmodemq.clear(); m_rxmodemq.clear();
qDebug() << "M17 playback stopped"; qDebug() << "M17 playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
return; return;
} }
} }
void M17Codec::decorrelate(uint8_t *in, uint8_t *out) void M17::decorrelate(uint8_t *in, uint8_t *out)
{ {
for (uint32_t i = M17_SYNC_LENGTH_BYTES; i < M17_FRAME_LENGTH_BYTES; i++) { for (uint32_t i = M17_SYNC_LENGTH_BYTES; i < M17_FRAME_LENGTH_BYTES; i++) {
out[i] = in[i] ^ SCRAMBLER[i]; out[i] = in[i] ^ SCRAMBLER[i];
} }
} }
void M17Codec::interleave(uint8_t *in, uint8_t *out) void M17::interleave(uint8_t *in, uint8_t *out)
{ {
for (uint32_t i = 0U; i < (M17_FRAME_LENGTH_BITS - M17_SYNC_LENGTH_BITS); i++) { for (uint32_t i = 0U; i < (M17_FRAME_LENGTH_BITS - M17_SYNC_LENGTH_BITS); i++) {
uint32_t n1 = i + M17_SYNC_LENGTH_BITS; uint32_t n1 = i + M17_SYNC_LENGTH_BITS;
@ -995,7 +990,7 @@ void M17Codec::interleave(uint8_t *in, uint8_t *out)
} }
} }
void M17Codec::splitFragmentLICH(const uint8_t* data, uint32_t& frag1, uint32_t& frag2, uint32_t& frag3, uint32_t& frag4) void M17::splitFragmentLICH(const uint8_t* data, uint32_t& frag1, uint32_t& frag2, uint32_t& frag3, uint32_t& frag4)
{ {
assert(data != NULL); assert(data != NULL);
@ -1031,7 +1026,7 @@ void M17Codec::splitFragmentLICH(const uint8_t* data, uint32_t& frag1, uint32_t&
} }
} }
void M17Codec::combineFragmentLICH(uint32_t frag1, uint32_t frag2, uint32_t frag3, uint32_t frag4, uint8_t* data) void M17::combineFragmentLICH(uint32_t frag1, uint32_t frag2, uint32_t frag3, uint32_t frag4, uint8_t* data)
{ {
assert(data != NULL); assert(data != NULL);
@ -1061,7 +1056,7 @@ void M17Codec::combineFragmentLICH(uint32_t frag1, uint32_t frag2, uint32_t frag
} }
} }
void M17Codec::combineFragmentLICHFEC(uint32_t frag1, uint32_t frag2, uint32_t frag3, uint32_t frag4, uint8_t* data) void M17::combineFragmentLICHFEC(uint32_t frag1, uint32_t frag2, uint32_t frag3, uint32_t frag4, uint8_t* data)
{ {
assert(data != NULL); assert(data != NULL);
@ -1091,7 +1086,7 @@ void M17Codec::combineFragmentLICHFEC(uint32_t frag1, uint32_t frag2, uint32_t f
} }
} }
bool M17Codec::checkCRC16(const uint8_t* in, uint32_t nBytes) bool M17::checkCRC16(const uint8_t* in, uint32_t nBytes)
{ {
assert(in != NULL); assert(in != NULL);
assert(nBytes > 2U); assert(nBytes > 2U);
@ -1105,7 +1100,7 @@ bool M17Codec::checkCRC16(const uint8_t* in, uint32_t nBytes)
return temp[0U] == in[nBytes - 2U] && temp[1U] == in[nBytes - 1U]; return temp[0U] == in[nBytes - 2U] && temp[1U] == in[nBytes - 1U];
} }
void M17Codec::encodeCRC16(uint8_t* in, uint32_t nBytes) void M17::encodeCRC16(uint8_t* in, uint32_t nBytes)
{ {
assert(in != NULL); assert(in != NULL);
assert(nBytes > 2U); assert(nBytes > 2U);
@ -1116,7 +1111,7 @@ void M17Codec::encodeCRC16(uint8_t* in, uint32_t nBytes)
in[nBytes - 1U] = (crc >> 0) & 0xFFU; in[nBytes - 1U] = (crc >> 0) & 0xFFU;
} }
uint16_t M17Codec::createCRC16(const uint8_t* in, uint32_t nBytes) uint16_t M17::createCRC16(const uint8_t* in, uint32_t nBytes)
{ {
assert(in != NULL); assert(in != NULL);

@ -15,23 +15,23 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef M17CODEC_H #ifndef M17_H
#define M17CODEC_H #define M17_H
#include <string> #include <string>
#include "codec.h" #include "mode.h"
#ifdef USE_EXTERNAL_CODEC2 #ifdef USE_EXTERNAL_CODEC2
#include <codec2/codec2.h> #include <codec2/codec2.h>
#else #else
#include "codec2/codec2_api.h" #include "codec2/codec2_api.h"
#endif #endif
class M17Codec : public Codec class M17 : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
M17Codec(QString callsign, char module, QString hostname, QString host, int port, bool ipv6, QString modem, QString audioin, QString audioout); M17();
~M17Codec(); ~M17();
static void encode_callsign(uint8_t *); static void encode_callsign(uint8_t *);
static void decode_callsign(uint8_t *); static void decode_callsign(uint8_t *);
void decode_c2(int16_t *, uint8_t *); void decode_c2(int16_t *, uint8_t *);
@ -55,7 +55,7 @@ private slots:
void hostname_lookup(QHostInfo i); void hostname_lookup(QHostInfo i);
void mmdvm_direct_connect(); void mmdvm_direct_connect();
void rate_changed(int r) { m_txrate = r; } void rate_changed(int r) { m_txrate = r; }
void can_changed(int c) { m_txcan = c; } void can_changed(int c) { m_txcan = c; qDebug() << "CAN == " << c; }
void process_rx_data(); void process_rx_data();
void splitFragmentLICH(const uint8_t*, uint32_t&, uint32_t&, uint32_t&, uint32_t&); void splitFragmentLICH(const uint8_t*, uint32_t&, uint32_t&, uint32_t&, uint32_t&);
void combineFragmentLICH(uint32_t, uint32_t, uint32_t, uint32_t, uint8_t*); void combineFragmentLICH(uint32_t, uint32_t, uint32_t, uint32_t, uint8_t*);
@ -70,4 +70,4 @@ private:
uint8_t m_txcan; uint8_t m_txcan;
}; };
#endif // M17CODEC_H #endif // M17_H

@ -21,6 +21,7 @@
#import <AVFoundation/AVCaptureDevice.h> #import <AVFoundation/AVCaptureDevice.h>
int MicPermission::check_permission() int MicPermission::check_permission()
{ {
[UIApplication sharedApplication].idleTimerDisabled = YES;
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]; AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
if(status != AVAuthorizationStatusAuthorized){ if(status != AVAuthorizationStatusAuthorized){
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) { [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "codec.h" #include "mode.h"
#include <iostream> #include <iostream>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <windows.h> #include <windows.h>
@ -22,6 +22,16 @@
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include "m17.h"
#include "ysf.h"
#include "dmr.h"
#include "p25.h"
#include "nxdn.h"
#include "ref.h"
#include "xrf.h"
#include "dcs.h"
#include "iax.h"
#ifdef USE_FLITE #ifdef USE_FLITE
extern "C" { extern "C" {
extern cst_voice * register_cmu_us_slt(const char *); extern cst_voice * register_cmu_us_slt(const char *);
@ -30,32 +40,70 @@ extern cst_voice * register_cmu_us_awb(const char *);
} }
#endif #endif
Codec::Codec(QString callsign, char module, QString hostname, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout, uint8_t attenuation) : Mode* Mode::create_mode(QString m)
m_module(module),
m_hostname(hostname),
m_tx(false),
m_ttsid(0),
m_audioin(audioin),
m_audioout(audioout),
m_rxwatchdog(0),
m_attenuation(attenuation),
#ifdef Q_OS_WIN
m_rxtimerint(19),
#else
m_rxtimerint(20),
#endif
m_txtimerint(19),
m_vocoder(vocoder),
m_modemport(modem),
m_modem(nullptr),
m_ambedev(nullptr),
m_hwrx(false),
m_hwtx(false),
m_ipv6(ipv6)
{ {
Mode *mode = nullptr;
if(m == "M17"){
mode = new M17();
}
else if(m == "YSF" || m == "FCS"){
mode = new YSF();
}
else if(m == "DMR"){
mode = new DMR();
}
else if(m == "P25"){
mode = new P25();
}
else if(m == "NXDN"){
mode = new NXDN();
}
else if(m == "REF"){
mode = new REF();
}
else if(m == "XRF"){
mode = new XRF();
}
else if(m == "DCS"){
mode = new DCS();
}
else if(m == "IAX"){
mode = new IAX();
}
return mode;
}
Mode::Mode()
{
}
Mode::~Mode()
{
}
void Mode::init(QString callsign, uint32_t dmrid, char module, QString refname, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout)
{
m_dmrid = dmrid;
m_module = module;
m_refname = refname;
m_ipv6 = ipv6;
m_vocoder = vocoder;
m_modemport = modem;
m_audioin = audioin;
m_audioout = audioout;
m_modem = nullptr;
m_ambedev = nullptr;
m_hwrx = false;
m_hwtx = false;
m_tx = false;
m_ttsid = 0;
m_rxwatchdog = 0;
m_modeinfo.callsign = callsign; m_modeinfo.callsign = callsign;
m_modeinfo.gwid = 0; m_modeinfo.gwid = 0;
m_modeinfo.srcid = 0; m_modeinfo.srcid = dmrid;
m_modeinfo.dstid = 0; m_modeinfo.dstid = 0;
m_modeinfo.host = host; m_modeinfo.host = host;
m_modeinfo.port = port; m_modeinfo.port = port;
@ -66,19 +114,21 @@ Codec::Codec(QString callsign, char module, QString hostname, QString host, int
m_modeinfo.stream_state = STREAM_IDLE; m_modeinfo.stream_state = STREAM_IDLE;
m_modeinfo.sw_vocoder_loaded = false; m_modeinfo.sw_vocoder_loaded = false;
m_modeinfo.hw_vocoder_loaded = false; m_modeinfo.hw_vocoder_loaded = false;
#ifdef Q_OS_WIN
m_rxtimerint = 19;
#else
m_rxtimerint = 20;
#endif
#ifdef USE_FLITE #ifdef USE_FLITE
flite_init(); flite_init();
voice_slt = register_cmu_us_slt(nullptr); voice_slt = register_cmu_us_slt(nullptr);
voice_kal = register_cmu_us_kal16(nullptr); voice_kal = register_cmu_us_kal16(nullptr);
voice_awb = register_cmu_us_awb(nullptr); voice_awb = register_cmu_us_awb(nullptr);
#endif #endif
}
Codec::~Codec()
{
} }
void Codec::ambe_connect_status(bool s) void Mode::ambe_connect_status(bool s)
{ {
if(s){ if(s){
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
@ -94,7 +144,7 @@ void Codec::ambe_connect_status(bool s)
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void Codec::mmdvm_connect_status(bool s) void Mode::mmdvm_connect_status(bool s)
{ {
if(s){ if(s){
//m_modeinfo.mmdvmdesc = m_modem->get_mmdvm_description(); //m_modeinfo.mmdvmdesc = m_modem->get_mmdvm_description();
@ -108,23 +158,23 @@ void Codec::mmdvm_connect_status(bool s)
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void Codec::in_audio_vol_changed(qreal v) void Mode::in_audio_vol_changed(qreal v)
{ {
m_audio->set_input_volume(v / m_attenuation); m_audio->set_input_volume(v / m_attenuation);
} }
void Codec::out_audio_vol_changed(qreal v) void Mode::out_audio_vol_changed(qreal v)
{ {
m_audio->set_output_volume(v); m_audio->set_output_volume(v);
} }
void Codec::agc_state_changed(int s) void Mode::agc_state_changed(int s)
{ {
qDebug() << "Codec::agc_state_changed() called s == " << s; qDebug() << "Codec::agc_state_changed() called s == " << s;
m_audio->set_agc(s); m_audio->set_agc(s);
} }
void Codec::send_connect() void Mode::send_connect()
{ {
m_modeinfo.status = CONNECTING; m_modeinfo.status = CONNECTING;
@ -144,12 +194,12 @@ void Codec::send_connect()
} }
} }
void Codec::toggle_tx(bool tx) void Mode::toggle_tx(bool tx)
{ {
tx ? start_tx() : stop_tx(); tx ? start_tx() : stop_tx();
} }
void Codec::start_tx() void Mode::start_tx()
{ {
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
if(m_hwtx){ if(m_hwtx){
@ -185,12 +235,12 @@ void Codec::start_tx()
} }
} }
void Codec::stop_tx() void Mode::stop_tx()
{ {
m_tx = false; m_tx = false;
} }
bool Codec::load_vocoder_plugin() bool Mode::load_vocoder_plugin()
{ {
#ifdef VOCODER_PLUGIN #ifdef VOCODER_PLUGIN
QString config_path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); QString config_path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
@ -262,7 +312,7 @@ bool Codec::load_vocoder_plugin()
#endif #endif
} }
void Codec::deleteLater() void Mode::deleteLater()
{ {
if(m_modeinfo.status == CONNECTED_RW){ if(m_modeinfo.status == CONNECTED_RW){
//m_udp->disconnect(); //m_udp->disconnect();

@ -15,8 +15,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef CODEC_H #ifndef MODE_H
#define CODEC_H #define MODE_H
#include <QObject> #include <QObject>
#include <QtNetwork> #include <QtNetwork>
@ -35,13 +35,22 @@
#include "serialmodem.h" #include "serialmodem.h"
#endif #endif
class Codec : public QObject class Mode : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Codec(QString callsign, char module, QString hostname, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout, uint8_t attenuation); Mode();
~Codec(); ~Mode();
void set_modem_flags(bool rxInvert, bool txInvert, bool pttInvert, bool useCOSAsLockout, bool duplex) { m_rxInvert = rxInvert; m_txInvert = txInvert; m_pttInvert = pttInvert; m_useCOSAsLockout = useCOSAsLockout; m_duplex = duplex; } static Mode* create_mode(QString);
void init(QString callsign, uint32_t dmrid, char module, QString refname, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout);
void set_modem_flags(bool rxInvert, bool txInvert, bool pttInvert, bool useCOSAsLockout, bool duplex)
{
m_rxInvert = rxInvert;
m_txInvert = txInvert;
m_pttInvert = pttInvert;
m_useCOSAsLockout = useCOSAsLockout;
m_duplex = duplex;
}
void set_modem_params(uint32_t baud, uint32_t rxfreq, uint32_t txfreq, uint32_t txDelay, float rxLevel, float rfLevel, uint32_t ysfTXHang, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float pocsagTXLevel, float m17TXLevel) void set_modem_params(uint32_t baud, uint32_t rxfreq, uint32_t txfreq, uint32_t txDelay, float rxLevel, float rfLevel, uint32_t ysfTXHang, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float pocsagTXLevel, float m17TXLevel)
{ {
m_baud = baud; m_baud = baud;
@ -60,6 +69,8 @@ public:
m_pocsagTXLevel = pocsagTXLevel; m_pocsagTXLevel = pocsagTXLevel;
m_m17TXLevel = m17TXLevel; m_m17TXLevel = m17TXLevel;
} }
virtual void set_dmr_params(uint8_t, QString, QString, QString, QString, QString, QString, QString, QString, QString, QString) {}
virtual void set_iax_params(QString, QString, QString, QString, int) {}
bool get_hwrx() { return m_hwrx; } bool get_hwrx() { return m_hwrx; }
bool get_hwtx() { return m_hwtx; } bool get_hwtx() { return m_hwtx; }
void set_hostname(std::string); void set_hostname(std::string);
@ -118,12 +129,13 @@ public:
STREAM_UNKNOWN STREAM_UNKNOWN
}; };
signals: signals:
void update(Codec::MODEINFO); void update(Mode::MODEINFO);
void update_output_level(unsigned short); void update_output_level(unsigned short);
protected slots: protected slots:
virtual void send_disconnect(){} virtual void send_disconnect(){}
virtual void hostname_lookup(QHostInfo){} virtual void hostname_lookup(QHostInfo){}
virtual void mmdvm_direct_connect(){} virtual void mmdvm_direct_connect(){}
void ambe_connect_status(bool); void ambe_connect_status(bool);
void mmdvm_connect_status(bool); void mmdvm_connect_status(bool);
void send_connect(); void send_connect();
@ -148,7 +160,8 @@ protected:
QUdpSocket *m_udp = nullptr; QUdpSocket *m_udp = nullptr;
QHostAddress m_address; QHostAddress m_address;
char m_module; char m_module;
QString m_hostname; uint32_t m_dmrid;
QString m_refname;
bool m_tx; bool m_tx;
uint16_t m_txcnt; uint16_t m_txcnt;
uint16_t m_ttscnt; uint16_t m_ttscnt;
@ -235,4 +248,4 @@ protected:
int m_txDCOffset; int m_txDCOffset;
}; };
#endif // CODEC_H #endif // MODE_H

@ -15,7 +15,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "nxdncodec.h" #include "nxdn.h"
#include <cstring> #include <cstring>
//#define DEBUG //#define DEBUG
@ -39,20 +39,18 @@ const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) #define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) #define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
NXDNCodec::NXDNCodec(QString callsign, uint16_t nxdnid, uint32_t gwid, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout) : NXDN::NXDN()
Codec(callsign, 0, NULL, host, port, ipv6, vocoder, modem, audioin, audioout, 5),
m_nxdnid(nxdnid)
{ {
m_txcnt = 0; m_txcnt = 0;
m_txtimerint = 19; m_txtimerint = 19;
m_modeinfo.gwid = gwid; m_attenuation = 5;
} }
NXDNCodec::~NXDNCodec() NXDN::~NXDN()
{ {
} }
void NXDNCodec::process_udp() void NXDN::process_udp()
{ {
QByteArray buf; QByteArray buf;
QHostAddress sender; QHostAddress sender;
@ -190,7 +188,7 @@ void NXDNCodec::process_udp()
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void NXDNCodec::interleave(uint8_t *ambe) void NXDN::interleave(uint8_t *ambe)
{ {
char ambe_data[49]; char ambe_data[49];
char dvsi_data[7]; char dvsi_data[7];
@ -209,7 +207,7 @@ void NXDNCodec::interleave(uint8_t *ambe)
memcpy(ambe, dvsi_data, 7); memcpy(ambe, dvsi_data, 7);
} }
void NXDNCodec::hostname_lookup(QHostInfo i) void NXDN::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
@ -237,7 +235,7 @@ void NXDNCodec::hostname_lookup(QHostInfo i)
} }
} }
void NXDNCodec::send_ping() void NXDN::send_ping()
{ {
QByteArray out; QByteArray out;
out.append('N'); out.append('N');
@ -260,7 +258,7 @@ void NXDNCodec::send_ping()
#endif #endif
} }
void NXDNCodec::send_disconnect() void NXDN::send_disconnect()
{ {
QByteArray out; QByteArray out;
out.append('N'); out.append('N');
@ -283,7 +281,7 @@ void NXDNCodec::send_disconnect()
#endif #endif
} }
void NXDNCodec::transmit() void NXDN::transmit()
{ {
uint8_t ambe[7]; uint8_t ambe[7];
int16_t pcm[160]; int16_t pcm[160];
@ -338,7 +336,7 @@ void NXDNCodec::transmit()
} }
} }
void NXDNCodec::send_frame() void NXDN::send_frame()
{ {
QByteArray txdata; QByteArray txdata;
unsigned char *temp_nxdn; unsigned char *temp_nxdn;
@ -371,7 +369,7 @@ void NXDNCodec::send_frame()
emit update(m_modeinfo); emit update(m_modeinfo);
} }
uint8_t * NXDNCodec::get_frame() uint8_t * NXDN::get_frame()
{ {
memcpy(m_nxdnframe, "NXDND", 5); memcpy(m_nxdnframe, "NXDND", 5);
m_nxdnframe[5U] = (m_nxdnid >> 8) & 0xFFU; m_nxdnframe[5U] = (m_nxdnid >> 8) & 0xFFU;
@ -407,7 +405,7 @@ uint8_t * NXDNCodec::get_frame()
return m_nxdnframe; return m_nxdnframe;
} }
void NXDNCodec::encode_header() void NXDN::encode_header()
{ {
const uint8_t idle[3U] = {0x10, 0x00, 0x00}; const uint8_t idle[3U] = {0x10, 0x00, 0x00};
m_lich = 0; m_lich = 0;
@ -437,7 +435,7 @@ void NXDNCodec::encode_header()
memcpy(&m_nxdnframe[29U], m_layer3, 14U); memcpy(&m_nxdnframe[29U], m_layer3, 14U);
} }
void NXDNCodec::encode_data() void NXDN::encode_data()
{ {
uint8_t msg[3U]; uint8_t msg[3U];
m_lich = 0; m_lich = 0;
@ -502,7 +500,7 @@ void NXDNCodec::encode_data()
m_nxdnframe[41] |= (m_ambe[27] >> 2); m_nxdnframe[41] |= (m_ambe[27] >> 2);
} }
void NXDNCodec::deinterleave_ambe(uint8_t *d) void NXDN::deinterleave_ambe(uint8_t *d)
{ {
uint8_t dvsi_data[49]; uint8_t dvsi_data[49];
uint8_t ambe_data[7]; uint8_t ambe_data[7];
@ -524,36 +522,36 @@ void NXDNCodec::deinterleave_ambe(uint8_t *d)
memcpy(d, ambe_data, 7); memcpy(d, ambe_data, 7);
} }
unsigned char NXDNCodec::get_lich_fct(uint8_t lich) unsigned char NXDN::get_lich_fct(uint8_t lich)
{ {
return (lich >> 4) & 0x03U; return (lich >> 4) & 0x03U;
} }
void NXDNCodec::set_lich_rfct(uint8_t rfct) void NXDN::set_lich_rfct(uint8_t rfct)
{ {
m_lich &= 0x3FU; m_lich &= 0x3FU;
m_lich |= (rfct << 6) & 0xC0U; m_lich |= (rfct << 6) & 0xC0U;
} }
void NXDNCodec::set_lich_fct(uint8_t fct) void NXDN::set_lich_fct(uint8_t fct)
{ {
m_lich &= 0xCFU; m_lich &= 0xCFU;
m_lich |= (fct << 4) & 0x30U; m_lich |= (fct << 4) & 0x30U;
} }
void NXDNCodec::set_lich_option(uint8_t o) void NXDN::set_lich_option(uint8_t o)
{ {
m_lich &= 0xF3U; m_lich &= 0xF3U;
m_lich |= (o << 2) & 0x0CU; m_lich |= (o << 2) & 0x0CU;
} }
void NXDNCodec::set_lich_dir(uint8_t d) void NXDN::set_lich_dir(uint8_t d)
{ {
m_lich &= 0xFDU; m_lich &= 0xFDU;
m_lich |= (d << 1) & 0x02U; m_lich |= (d << 1) & 0x02U;
} }
uint8_t NXDNCodec::get_lich() uint8_t NXDN::get_lich()
{ {
bool parity; bool parity;
switch (m_lich & 0xF0U) { switch (m_lich & 0xF0U) {
@ -573,19 +571,19 @@ uint8_t NXDNCodec::get_lich()
} }
void NXDNCodec::set_sacch_ran(uint8_t ran) void NXDN::set_sacch_ran(uint8_t ran)
{ {
m_sacch[0] &= 0xC0U; m_sacch[0] &= 0xC0U;
m_sacch[0] |= ran; m_sacch[0] |= ran;
} }
void NXDNCodec::set_sacch_struct(uint8_t s) void NXDN::set_sacch_struct(uint8_t s)
{ {
m_sacch[0] &= 0x3FU; m_sacch[0] &= 0x3FU;
m_sacch[0] |= (s << 6) & 0xC0U;; m_sacch[0] |= (s << 6) & 0xC0U;;
} }
void NXDNCodec::set_sacch_data(const uint8_t *d) void NXDN::set_sacch_data(const uint8_t *d)
{ {
uint8_t offset = 8U; uint8_t offset = 8U;
for (uint8_t i = 0U; i < 18U; i++, offset++) { for (uint8_t i = 0U; i < 18U; i++, offset++) {
@ -594,42 +592,42 @@ void NXDNCodec::set_sacch_data(const uint8_t *d)
} }
} }
void NXDNCodec::get_sacch(uint8_t *d) void NXDN::get_sacch(uint8_t *d)
{ {
memcpy(d, m_sacch, 4U); memcpy(d, m_sacch, 4U);
encode_crc6(d, 26); encode_crc6(d, 26);
} }
void NXDNCodec::set_layer3_msgtype(uint8_t t) void NXDN::set_layer3_msgtype(uint8_t t)
{ {
m_layer3[0] &= 0xC0U; m_layer3[0] &= 0xC0U;
m_layer3[0] |= t & 0x3FU; m_layer3[0] |= t & 0x3FU;
} }
void NXDNCodec::set_layer3_srcid(uint16_t src) void NXDN::set_layer3_srcid(uint16_t src)
{ {
m_layer3[3U] = (src >> 8) & 0xFF; m_layer3[3U] = (src >> 8) & 0xFF;
m_layer3[4U] = (src >> 0) & 0xFF ; m_layer3[4U] = (src >> 0) & 0xFF ;
} }
void NXDNCodec::set_layer3_dstid(uint16_t dst) void NXDN::set_layer3_dstid(uint16_t dst)
{ {
m_layer3[5U] = (dst >> 8) & 0xFF; m_layer3[5U] = (dst >> 8) & 0xFF;
m_layer3[6U] = (dst >> 0) & 0xFF ; m_layer3[6U] = (dst >> 0) & 0xFF ;
} }
void NXDNCodec::set_layer3_grp(bool grp) void NXDN::set_layer3_grp(bool grp)
{ {
m_layer3[2U] |= grp ? 0x20U : 0x20U; m_layer3[2U] |= grp ? 0x20U : 0x20U;
} }
void NXDNCodec::set_layer3_blks(uint8_t b) void NXDN::set_layer3_blks(uint8_t b)
{ {
m_layer3[8U] &= 0xF0U; m_layer3[8U] &= 0xF0U;
m_layer3[8U] |= b & 0x0FU; m_layer3[8U] |= b & 0x0FU;
} }
void NXDNCodec::layer3_encode(uint8_t* d, uint8_t len, uint8_t offset) void NXDN::layer3_encode(uint8_t* d, uint8_t len, uint8_t offset)
{ {
for (uint32_t i = 0U; i < len; i++, offset++) { for (uint32_t i = 0U; i < len; i++, offset++) {
bool b = READ_BIT1(m_layer3, offset); bool b = READ_BIT1(m_layer3, offset);
@ -637,7 +635,7 @@ void NXDNCodec::layer3_encode(uint8_t* d, uint8_t len, uint8_t offset)
} }
} }
void NXDNCodec::encode_crc6(uint8_t *d, uint8_t len) void NXDN::encode_crc6(uint8_t *d, uint8_t len)
{ {
uint8_t crc = 0x3FU; uint8_t crc = 0x3FU;
@ -657,7 +655,7 @@ void NXDNCodec::encode_crc6(uint8_t *d, uint8_t len)
} }
} }
void NXDNCodec::get_ambe() void NXDN::get_ambe()
{ {
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
uint8_t ambe[7]; uint8_t ambe[7];
@ -670,7 +668,7 @@ void NXDNCodec::get_ambe()
#endif #endif
} }
void NXDNCodec::process_rx_data() void NXDN::process_rx_data()
{ {
int16_t pcm[160]; int16_t pcm[160];
uint8_t ambe[7]; uint8_t ambe[7];
@ -716,6 +714,7 @@ void NXDNCodec::process_rx_data()
m_modeinfo.streamid = 0; m_modeinfo.streamid = 0;
m_rxcodecq.clear(); m_rxcodecq.clear();
qDebug() << "YSF playback stopped"; qDebug() << "YSF playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
return; return;
} }
} }

@ -15,18 +15,18 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef NXDNCODEC_H #ifndef NXDN_H
#define NXDNCODEC_H #define NXDN_H
//#include <inttypes.h> //#include <inttypes.h>
#include "codec.h" #include "mode.h"
class NXDNCodec : public Codec class NXDN : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
NXDNCodec(QString callsign, uint16_t nxdnid, uint32_t gwid, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout); NXDN();
~NXDNCodec(); ~NXDN();
unsigned char * get_frame(); unsigned char * get_frame();
unsigned char * get_eot(){m_eot = true; return get_frame();} unsigned char * get_eot(){m_eot = true; return get_frame();}
void set_hwtx(bool hw){m_hwtx = hw;} void set_hwtx(bool hw){m_hwtx = hw;}
@ -73,4 +73,4 @@ private:
void interleave(uint8_t *ambe); void interleave(uint8_t *ambe);
}; };
#endif // NXDNCODEC_H #endif // NXDN_H

@ -17,7 +17,7 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include "p25codec.h" #include "p25.h"
//#define DEBUG //#define DEBUG
@ -45,20 +45,18 @@ const unsigned char REC80[] = {0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) #define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) #define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
P25Codec::P25Codec(QString callsign, int dmrid, int hostname, QString host, int port, bool ipv6, QString modem, QString audioin, QString audioout) : P25::P25()
Codec(callsign, 0, NULL, host, port, ipv6, NULL, modem, audioin, audioout, 2),
m_hostname(hostname),
m_dmrid(dmrid)
{ {
m_p25cnt = 0; m_p25cnt = 0;
m_txtimerint = 19; m_txtimerint = 19;
m_attenuation = 2;
} }
P25Codec::~P25Codec() P25::~P25()
{ {
} }
void P25Codec::process_udp() void P25::process_udp()
{ {
QByteArray buf; QByteArray buf;
QHostAddress sender; QHostAddress sender;
@ -78,6 +76,7 @@ void P25Codec::process_udp()
if(m_modeinfo.status == CONNECTING){ if(m_modeinfo.status == CONNECTING){
m_modeinfo.status = CONNECTED_RW; m_modeinfo.status = CONNECTED_RW;
m_modeinfo.status = CONNECTED_RW; m_modeinfo.status = CONNECTED_RW;
m_dstid = m_refname.toInt();
m_txtimer = new QTimer(); m_txtimer = new QTimer();
m_rxtimer = new QTimer(); m_rxtimer = new QTimer();
connect(m_rxtimer, SIGNAL(timeout()), this, SLOT(process_rx_data())); connect(m_rxtimer, SIGNAL(timeout()), this, SLOT(process_rx_data()));
@ -175,7 +174,7 @@ void P25Codec::process_udp()
} }
} }
void P25Codec::hostname_lookup(QHostInfo i) void P25::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
@ -197,7 +196,7 @@ void P25Codec::hostname_lookup(QHostInfo i)
} }
} }
void P25Codec::send_ping() void P25::send_ping()
{ {
QByteArray out; QByteArray out;
out.append(0xf0); out.append(0xf0);
@ -214,7 +213,7 @@ void P25Codec::send_ping()
#endif #endif
} }
void P25Codec::send_disconnect() void P25::send_disconnect()
{ {
QByteArray out; QByteArray out;
out.append(0xf1); out.append(0xf1);
@ -231,7 +230,7 @@ void P25Codec::send_disconnect()
#endif #endif
} }
void P25Codec::transmit() void P25::transmit()
{ {
QByteArray txdata; QByteArray txdata;
uint8_t imbe[11]; uint8_t imbe[11];
@ -286,9 +285,9 @@ void P25Codec::transmit()
case 0x03U: case 0x03U:
::memcpy(buffer, REC65, 17U); ::memcpy(buffer, REC65, 17U);
::memcpy(buffer + 5U, imbe, 11U); ::memcpy(buffer + 5U, imbe, 11U);
buffer[1U] = (m_hostname >> 16) & 0xFFU; buffer[1U] = (m_dstid >> 16) & 0xFFU;
buffer[2U] = (m_hostname >> 8) & 0xFFU; buffer[2U] = (m_dstid >> 8) & 0xFFU;
buffer[3U] = (m_hostname >> 0) & 0xFFU; buffer[3U] = (m_dstid >> 0) & 0xFFU;
txdata.append((char *)buffer, 17U); txdata.append((char *)buffer, 17U);
++p25step; ++p25step;
break; break;
@ -383,7 +382,7 @@ void P25Codec::transmit()
} }
m_modeinfo.stream_state = TRANSMITTING; m_modeinfo.stream_state = TRANSMITTING;
m_modeinfo.srcid = m_dmrid; m_modeinfo.srcid = m_dmrid;
m_modeinfo.dstid = m_hostname; m_modeinfo.dstid = m_dstid;
m_modeinfo.frame_number = p25step; m_modeinfo.frame_number = p25step;
m_udp->writeDatagram(txdata, m_address, m_modeinfo.port); m_udp->writeDatagram(txdata, m_address, m_modeinfo.port);
} }
@ -414,7 +413,7 @@ void P25Codec::transmit()
#endif #endif
} }
void P25Codec::process_rx_data() void P25::process_rx_data()
{ {
if(m_rxwatchdog++ > 50){ if(m_rxwatchdog++ > 50){
qDebug() << "P25 RX stream timeout "; qDebug() << "P25 RX stream timeout ";
@ -444,5 +443,6 @@ void P25Codec::process_rx_data()
m_modeinfo.streamid = 0; m_modeinfo.streamid = 0;
m_rxcodecq.clear(); m_rxcodecq.clear();
qDebug() << "P25 playback stopped"; qDebug() << "P25 playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
} }
} }

@ -15,22 +15,22 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef P25CODEC_H #ifndef P25_H
#define P25CODEC_H #define P25_H
#include "codec.h" #include "mode.h"
class P25Codec : public Codec class P25 : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
P25Codec(QString callsign, int dmrid, int hostname, QString host, int port, bool ipv6, QString modem, QString audioin, QString audioout); P25();
~P25Codec(); ~P25();
unsigned char * get_frame(unsigned char *ambe); uint8_t * get_frame(uint8_t *ambe);
private: private:
int m_p25cnt; int m_p25cnt;
unsigned char imbe[11U]; uint8_t imbe[11U];
int m_hostname; int m_dstid;
uint32_t m_dmrid; uint32_t m_dmrid;
uint32_t m_txdstid; uint32_t m_txdstid;
private slots: private slots:
@ -40,7 +40,7 @@ private slots:
void send_disconnect(); void send_disconnect();
void transmit(); void transmit();
void hostname_lookup(QHostInfo i); void hostname_lookup(QHostInfo i);
void dmr_tgid_changed(unsigned int id) { m_txdstid = id; } void dmr_tgid_changed(uint32_t id) { m_txdstid = id; }
}; };
#endif // P25CODEC_H #endif // P25_H

@ -17,26 +17,26 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include "refcodec.h" #include "ref.h"
#include "CRCenc.h" #include "CRCenc.h"
#define DEBUG //#define DEBUG
const unsigned char MMDVM_DSTAR_HEADER = 0x10U; const unsigned char MMDVM_DSTAR_HEADER = 0x10U;
const unsigned char MMDVM_DSTAR_DATA = 0x11U; const unsigned char MMDVM_DSTAR_DATA = 0x11U;
const unsigned char MMDVM_DSTAR_LOST = 0x12U; const unsigned char MMDVM_DSTAR_LOST = 0x12U;
const unsigned char MMDVM_DSTAR_EOT = 0x13U; const unsigned char MMDVM_DSTAR_EOT = 0x13U;
REFCodec::REFCodec(QString callsign, QString hostname, char module, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout) : REF::REF()
Codec(callsign, module, hostname, host, port, ipv6, vocoder, modem, audioin, audioout, 5)
{ {
m_attenuation = 5;
} }
REFCodec::~REFCodec() REF::~REF()
{ {
} }
void REFCodec::process_udp() void REF::process_udp()
{ {
QByteArray buf; QByteArray buf;
QByteArray out; QByteArray out;
@ -157,7 +157,7 @@ void REFCodec::process_udp()
QString urcall = QString(temp); QString urcall = QString(temp);
memcpy(temp, buf.data() + 44, 8); temp[8] = '\0'; memcpy(temp, buf.data() + 44, 8); temp[8] = '\0';
QString mycall = QString(temp); QString mycall = QString(temp);
QString h = m_hostname + " " + m_module; QString h = m_refname + " " + m_module;
if( (rptr2.simplified() == h.simplified()) || (rptr1.simplified() == h.simplified()) ){ if( (rptr2.simplified() == h.simplified()) || (rptr1.simplified() == h.simplified()) ){
m_rxwatchdog = 0; m_rxwatchdog = 0;
@ -296,7 +296,7 @@ void REFCodec::process_udp()
//emit update(m_modeinfo); //emit update(m_modeinfo);
} }
void REFCodec::hostname_lookup(QHostInfo i) void REF::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
@ -320,7 +320,7 @@ void REFCodec::hostname_lookup(QHostInfo i)
} }
} }
void REFCodec::send_ping() void REF::send_ping()
{ {
QByteArray out; QByteArray out;
out.append(0x03); out.append(0x03);
@ -337,7 +337,7 @@ void REFCodec::send_ping()
#endif #endif
} }
void REFCodec::send_disconnect() void REF::send_disconnect()
{ {
QByteArray out; QByteArray out;
out.append(0x05); out.append(0x05);
@ -356,7 +356,7 @@ void REFCodec::send_disconnect()
#endif #endif
} }
void REFCodec::format_callsign(QString &s) void REF::format_callsign(QString &s)
{ {
QStringList l = s.simplified().split(' '); QStringList l = s.simplified().split(' ');
@ -374,7 +374,7 @@ void REFCodec::format_callsign(QString &s)
} }
} }
void REFCodec::process_modem_data(QByteArray d) void REF::process_modem_data(QByteArray d)
{ {
QByteArray txdata; QByteArray txdata;
char cs[9]; char cs[9];
@ -401,21 +401,21 @@ void REFCodec::process_modem_data(QByteArray d)
send_frame(ambe); send_frame(ambe);
} }
void REFCodec::toggle_tx(bool tx) void REF::toggle_tx(bool tx)
{ {
tx ? start_tx() : stop_tx(); tx ? start_tx() : stop_tx();
} }
void REFCodec::start_tx() void REF::start_tx()
{ {
format_callsign(m_txmycall); format_callsign(m_txmycall);
format_callsign(m_txurcall); format_callsign(m_txurcall);
format_callsign(m_txrptr1); format_callsign(m_txrptr1);
format_callsign(m_txrptr2); format_callsign(m_txrptr2);
Codec::start_tx(); Mode::start_tx();
} }
void REFCodec::transmit() void REF::transmit()
{ {
unsigned char ambe[9]; unsigned char ambe[9];
uint8_t ambe_frame[72]; uint8_t ambe_frame[72];
@ -467,7 +467,7 @@ void REFCodec::transmit()
} }
} }
void REFCodec::send_frame(uint8_t *ambe) void REF::send_frame(uint8_t *ambe)
{ {
QByteArray txdata; QByteArray txdata;
static uint16_t txstreamid = 0; static uint16_t txstreamid = 0;
@ -637,7 +637,7 @@ void REFCodec::send_frame(uint8_t *ambe)
#endif #endif
} }
void REFCodec::get_ambe() void REF::get_ambe()
{ {
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
uint8_t ambe[9]; uint8_t ambe[9];
@ -650,7 +650,7 @@ void REFCodec::get_ambe()
#endif #endif
} }
void REFCodec::process_rx_data() void REF::process_rx_data()
{ {
int16_t pcm[160]; int16_t pcm[160];
uint8_t ambe[9]; uint8_t ambe[9];
@ -709,6 +709,7 @@ void REFCodec::process_rx_data()
m_modeinfo.streamid = 0; m_modeinfo.streamid = 0;
m_rxcodecq.clear(); m_rxcodecq.clear();
qDebug() << "REF playback stopped"; qDebug() << "REF playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
return; return;
} }
} }

@ -15,17 +15,17 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef REFCODEC_H #ifndef REF_H
#define REFCODEC_H #define REF_H
#include "codec.h" #include "mode.h"
class REFCodec : public Codec class REF : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
REFCodec(QString callsign, QString hostname, char module, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout); REF();
~REFCodec(); ~REF();
unsigned char * get_frame(unsigned char *ambe); unsigned char * get_frame(unsigned char *ambe);
private: private:
uint8_t packet_size; uint8_t packet_size;
@ -45,4 +45,4 @@ private slots:
void send_frame(uint8_t *); void send_frame(uint8_t *);
}; };
#endif // REFCODEC_H #endif // REF_H

@ -17,22 +17,22 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include "xrfcodec.h" #include "xrf.h"
#include "CRCenc.h" #include "CRCenc.h"
#include "MMDVMDefines.h" #include "MMDVMDefines.h"
//#define DEBUG //#define DEBUG
XRFCodec::XRFCodec(QString callsign, QString hostname, char module, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout) : XRF::XRF()
Codec(callsign, module, hostname, host, port, ipv6, vocoder, modem, audioin, audioout, 5)
{ {
m_attenuation = 5;
} }
XRFCodec::~XRFCodec() XRF::~XRF()
{ {
} }
void XRFCodec::process_udp() void XRF::process_udp()
{ {
QByteArray buf; QByteArray buf;
QHostAddress sender; QHostAddress sender;
@ -110,7 +110,7 @@ void XRFCodec::process_udp()
m_modeinfo.dst = QString(temp); m_modeinfo.dst = QString(temp);
memcpy(temp, buf.data() + 42, 8); temp[8] = '\0'; memcpy(temp, buf.data() + 42, 8); temp[8] = '\0';
m_modeinfo.src = QString(temp); m_modeinfo.src = QString(temp);
QString h = m_hostname + " " + m_module; QString h = m_refname + " " + m_module;
m_modeinfo.streamid = streamid; m_modeinfo.streamid = streamid;
m_modeinfo.stream_state = STREAM_NEW; m_modeinfo.stream_state = STREAM_NEW;
m_modeinfo.ts = QDateTime::currentMSecsSinceEpoch(); m_modeinfo.ts = QDateTime::currentMSecsSinceEpoch();
@ -250,7 +250,7 @@ void XRFCodec::process_udp()
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void XRFCodec::hostname_lookup(QHostInfo i) void XRF::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
@ -274,7 +274,7 @@ void XRFCodec::hostname_lookup(QHostInfo i)
} }
} }
void XRFCodec::send_ping() void XRF::send_ping()
{ {
QByteArray out; QByteArray out;
out.append(m_modeinfo.callsign.toUtf8()); out.append(m_modeinfo.callsign.toUtf8());
@ -291,7 +291,7 @@ void XRFCodec::send_ping()
#endif #endif
} }
void XRFCodec::send_disconnect() void XRF::send_disconnect()
{ {
QByteArray out; QByteArray out;
out.append(m_modeinfo.callsign.toUtf8()); out.append(m_modeinfo.callsign.toUtf8());
@ -310,7 +310,7 @@ void XRFCodec::send_disconnect()
#endif #endif
} }
void XRFCodec::format_callsign(QString &s) void XRF::format_callsign(QString &s)
{ {
QStringList l = s.simplified().split(' '); QStringList l = s.simplified().split(' ');
@ -328,7 +328,7 @@ void XRFCodec::format_callsign(QString &s)
} }
} }
void XRFCodec::process_modem_data(QByteArray d) void XRF::process_modem_data(QByteArray d)
{ {
char cs[9]; char cs[9];
uint8_t ambe[9]; uint8_t ambe[9];
@ -354,21 +354,21 @@ void XRFCodec::process_modem_data(QByteArray d)
send_frame(ambe); send_frame(ambe);
} }
void XRFCodec::toggle_tx(bool tx) void XRF::toggle_tx(bool tx)
{ {
tx ? start_tx() : stop_tx(); tx ? start_tx() : stop_tx();
} }
void XRFCodec::start_tx() void XRF::start_tx()
{ {
format_callsign(m_txmycall); format_callsign(m_txmycall);
format_callsign(m_txurcall); format_callsign(m_txurcall);
format_callsign(m_txrptr1); format_callsign(m_txrptr1);
format_callsign(m_txrptr2); format_callsign(m_txrptr2);
Codec::start_tx(); Mode::start_tx();
} }
void XRFCodec::transmit() void XRF::transmit()
{ {
unsigned char ambe[9]; unsigned char ambe[9];
uint8_t ambe_frame[72]; uint8_t ambe_frame[72];
@ -418,7 +418,7 @@ void XRFCodec::transmit()
} }
} }
void XRFCodec::send_frame(uint8_t *ambe) void XRF::send_frame(uint8_t *ambe)
{ {
QByteArray txdata; QByteArray txdata;
static uint16_t txstreamid = 0; static uint16_t txstreamid = 0;
@ -570,7 +570,7 @@ void XRFCodec::send_frame(uint8_t *ambe)
#endif #endif
} }
void XRFCodec::get_ambe() void XRF::get_ambe()
{ {
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
uint8_t ambe[9]; uint8_t ambe[9];
@ -583,7 +583,7 @@ void XRFCodec::get_ambe()
#endif #endif
} }
void XRFCodec::process_rx_data() void XRF::process_rx_data()
{ {
int16_t pcm[160]; int16_t pcm[160];
uint8_t ambe[9]; uint8_t ambe[9];
@ -642,6 +642,7 @@ void XRFCodec::process_rx_data()
m_modeinfo.streamid = 0; m_modeinfo.streamid = 0;
m_rxcodecq.clear(); m_rxcodecq.clear();
qDebug() << "XRF playback stopped"; qDebug() << "XRF playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
return; return;
} }
} }

@ -15,17 +15,17 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef XRFCODEC_H #ifndef XRF_H
#define XRFCODEC_H #define XRF_H
#include "codec.h" #include "mode.h"
class XRFCodec : public Codec class XRF : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
XRFCodec(QString callsign, QString hostname, char module, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout); XRF();
~XRFCodec(); ~XRF();
unsigned char * get_frame(unsigned char *ambe); unsigned char * get_frame(unsigned char *ambe);
private: private:
QString m_txusrtxt; QString m_txusrtxt;
@ -46,4 +46,4 @@ private slots:
void send_frame(uint8_t *); void send_frame(uint8_t *);
}; };
#endif // XRFCODEC_H #endif // XRF_H

@ -15,7 +15,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "ysfcodec.h" #include "ysf.h"
#include "YSFConvolution.h" #include "YSFConvolution.h"
#include "CRCenc.h" #include "CRCenc.h"
#include "Golay24128.h" #include "Golay24128.h"
@ -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,
@ -99,19 +99,18 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) #define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) #define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
YSFCodec::YSFCodec(QString callsign, QString hostname, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout) : YSF::YSF() :
Codec(callsign, 0, hostname, host, port, ipv6, vocoder, modem, audioin, audioout, 5),
m_fcs(false), m_fcs(false),
m_txfullrate(false) m_txfullrate(false)
{ {
m_attenuation = 5;
} }
YSFCodec::~YSFCodec() YSF::~YSF()
{ {
} }
void YSFCodec::process_udp() void YSF::process_udp()
{ {
QByteArray buf; QByteArray buf;
QByteArray out; QByteArray out;
@ -129,7 +128,7 @@ void YSFCodec::process_udp()
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fflush(stderr); fflush(stderr);
#endif #endif
if(((buf.size() == 14) && (m_hostname.left(3) != "FCS")) || ((buf.size() == 7) && (m_hostname.left(3) == "FCS"))){ if(((buf.size() == 14) && (m_refname.left(3) != "FCS")) || ((buf.size() == 7) && (m_refname.left(3) == "FCS"))){
if(m_modeinfo.status == CONNECTING){ if(m_modeinfo.status == CONNECTING){
m_modeinfo.status = CONNECTED_RW; m_modeinfo.status = CONNECTED_RW;
m_txtimer = new QTimer(); m_txtimer = new QTimer();
@ -173,14 +172,14 @@ void YSFCodec::process_udp()
m_audio = new AudioEngine(m_audioin, m_audioout); m_audio = new AudioEngine(m_audioin, m_audioout);
m_audio->init(); m_audio->init();
if(m_hostname.left(3) == "FCS"){ if(m_refname.left(3) == "FCS"){
char info[100U]; char info[100U];
::sprintf(info, "%9u%9u%-6.6s%-12.12s%7u", 438000000, 438000000, "AA00AA", "MMDVM", 1234567); ::sprintf(info, "%9u%9u%-6.6s%-12.12s%7u", 438000000, 438000000, "AA00AA", "MMDVM", 1234567);
::memset(info + 43U, ' ', 57U); ::memset(info + 43U, ' ', 57U);
out.append(info, 100); out.append(info, 100);
m_udp->writeDatagram(out, m_address, m_modeinfo.port); m_udp->writeDatagram(out, m_address, m_modeinfo.port);
p = 800; p = 800;
set_fcs_mode(true, m_hostname.left(8).toStdString()); set_fcs_mode(true, m_refname.left(8).toStdString());
} }
m_ping_timer->start(p); m_ping_timer->start(p);
} }
@ -282,18 +281,18 @@ void YSFCodec::process_udp()
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void YSFCodec::hostname_lookup(QHostInfo i) void YSF::hostname_lookup(QHostInfo i)
{ {
if (!i.addresses().isEmpty()) { if (!i.addresses().isEmpty()) {
QByteArray out; QByteArray out;
if(m_hostname.left(3) == "FCS"){ if(m_refname.left(3) == "FCS"){
out.append('P'); out.append('P');
out.append('I'); out.append('I');
out.append('N'); out.append('N');
out.append('G'); out.append('G');
out.append(m_modeinfo.callsign.toUtf8()); out.append(m_modeinfo.callsign.toUtf8());
out.append(6 - m_modeinfo.callsign.size(), ' '); out.append(6 - m_modeinfo.callsign.size(), ' ');
out.append(m_hostname.toUtf8()); out.append(m_refname.toUtf8());
out.append(7, '\x00'); out.append(7, '\x00');
} }
else{ else{
@ -319,17 +318,17 @@ void YSFCodec::hostname_lookup(QHostInfo i)
} }
} }
void YSFCodec::send_ping() void YSF::send_ping()
{ {
QByteArray out; QByteArray out;
if(m_hostname.left(3) == "FCS"){ if(m_refname.left(3) == "FCS"){
out.append('P'); out.append('P');
out.append('I'); out.append('I');
out.append('N'); out.append('N');
out.append('G'); out.append('G');
out.append(m_modeinfo.callsign.toUtf8()); out.append(m_modeinfo.callsign.toUtf8());
out.append(6 - m_modeinfo.callsign.size(), ' '); out.append(6 - m_modeinfo.callsign.size(), ' ');
out.append(m_hostname.toUtf8()); out.append(m_refname.toUtf8());
out.append(7, '\x00'); out.append(7, '\x00');
} }
else{ else{
@ -351,10 +350,10 @@ void YSFCodec::send_ping()
#endif #endif
} }
void YSFCodec::send_disconnect() void YSF::send_disconnect()
{ {
QByteArray out; QByteArray out;
if(m_hostname.left(3) == "FCS"){ if(m_refname.left(3) == "FCS"){
out.append('C'); out.append('C');
out.append('L'); out.append('L');
out.append('O'); out.append('O');
@ -381,7 +380,7 @@ void YSFCodec::send_disconnect()
#endif #endif
} }
void YSFCodec::decode_vw(uint8_t* data) void YSF::decode_vw(uint8_t* data)
{ {
uint8_t vch[18U]; uint8_t vch[18U];
uint8_t imbe[11U]; uint8_t imbe[11U];
@ -441,7 +440,7 @@ void YSFCodec::decode_vw(uint8_t* data)
} }
} }
void YSFCodec::decode_vd1(uint8_t* data, uint8_t *dt) void YSF::decode_vd1(uint8_t* data, uint8_t *dt)
{ {
uint8_t dch[45U]; uint8_t dch[45U];
@ -477,7 +476,7 @@ void YSFCodec::decode_vd1(uint8_t* data, uint8_t *dt)
} }
} }
void YSFCodec::decode_vd2(uint8_t* data, uint8_t *dt) void YSF::decode_vd2(uint8_t* data, uint8_t *dt)
{ {
uint8_t dch[25U]; uint8_t dch[25U];
@ -513,7 +512,7 @@ void YSFCodec::decode_vd2(uint8_t* data, uint8_t *dt)
} }
} }
void YSFCodec::decode_dn(uint8_t* data) void YSF::decode_dn(uint8_t* data)
{ {
uint8_t v_tmp[7U]; uint8_t v_tmp[7U];
uint8_t dt[20]; uint8_t dt[20];
@ -606,7 +605,7 @@ void YSFCodec::decode_dn(uint8_t* data)
} }
} }
void YSFCodec::interleave(uint8_t *ambe) void YSF::interleave(uint8_t *ambe)
{ {
char ambe_data[49]; char ambe_data[49];
char dvsi_data[7]; char dvsi_data[7];
@ -625,7 +624,7 @@ void YSFCodec::interleave(uint8_t *ambe)
memcpy(ambe, dvsi_data, 7); memcpy(ambe, dvsi_data, 7);
} }
void YSFCodec::process_modem_data(QByteArray d) void YSF::process_modem_data(QByteArray d)
{ {
if(d.size() < 126){ if(d.size() < 126){
return; return;
@ -664,7 +663,7 @@ void YSFCodec::process_modem_data(QByteArray d)
#endif #endif
} }
void YSFCodec::transmit() void YSF::transmit()
{ {
uint8_t ambe_frame[88]; uint8_t ambe_frame[88];
uint8_t ambe[7]; uint8_t ambe[7];
@ -729,7 +728,7 @@ void YSFCodec::transmit()
} }
} }
void YSFCodec::send_frame() void YSF::send_frame()
{ {
QByteArray txdata; QByteArray txdata;
int frame_size; int frame_size;
@ -775,7 +774,7 @@ void YSFCodec::send_frame()
emit update(m_modeinfo); emit update(m_modeinfo);
} }
void YSFCodec::encode_header(bool eot) void YSF::encode_header(bool eot)
{ {
uint8_t callsign[12]; uint8_t callsign[12];
::memcpy(callsign, " ", 10); ::memcpy(callsign, " ", 10);
@ -830,7 +829,7 @@ void YSFCodec::encode_header(bool eot)
writeDataFRModeData2(csd2, p_frame); writeDataFRModeData2(csd2, p_frame);
} }
void YSFCodec::encode_vw() void YSF::encode_vw()
{ {
uint8_t callsign[12]; uint8_t callsign[12];
::memcpy(callsign, " ", 10); ::memcpy(callsign, " ", 10);
@ -887,7 +886,7 @@ void YSFCodec::encode_vw()
} }
} }
void YSFCodec::encode_imbe(uint8_t* data, const uint8_t* imbe) void YSF::encode_imbe(uint8_t* data, const uint8_t* imbe)
{ {
bool bTemp[144U]; bool bTemp[144U];
bool* bit = bTemp; bool* bit = bTemp;
@ -986,7 +985,7 @@ void YSFCodec::encode_imbe(uint8_t* data, const uint8_t* imbe)
} }
} }
void YSFCodec::encode_dv2() void YSF::encode_dv2()
{ {
uint8_t callsign[12]; uint8_t callsign[12];
::memcpy(callsign, " ", 10); ::memcpy(callsign, " ", 10);
@ -1070,7 +1069,7 @@ void YSFCodec::encode_dv2()
} }
} }
void YSFCodec::writeDataFRModeData1(const uint8_t* dt, uint8_t* data) void YSF::writeDataFRModeData1(const uint8_t* dt, uint8_t* data)
{ {
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES; data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
@ -1111,7 +1110,7 @@ void YSFCodec::writeDataFRModeData1(const uint8_t* dt, uint8_t* data)
} }
} }
void YSFCodec::writeDataFRModeData2(const uint8_t* dt, uint8_t* data) void YSF::writeDataFRModeData2(const uint8_t* dt, uint8_t* data)
{ {
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES; data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
@ -1152,7 +1151,7 @@ void YSFCodec::writeDataFRModeData2(const uint8_t* dt, uint8_t* data)
} }
} }
void YSFCodec::ysf_scramble(uint8_t *buf, const int len) void YSF::ysf_scramble(uint8_t *buf, const int len)
{ // buffer is (de)scrambled in place { // buffer is (de)scrambled in place
static const uint8_t scramble_code[180] = { static const uint8_t scramble_code[180] = {
1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1,
@ -1174,7 +1173,7 @@ void YSFCodec::ysf_scramble(uint8_t *buf, const int len)
} }
} }
void YSFCodec::generate_vch_vd2(const uint8_t *a) void YSF::generate_vch_vd2(const uint8_t *a)
{ {
uint8_t buf[104]; uint8_t buf[104];
uint8_t result[104]; uint8_t result[104];
@ -1215,7 +1214,7 @@ void YSFCodec::generate_vch_vd2(const uint8_t *a)
::memcpy(m_vch, vch, 13); ::memcpy(m_vch, vch, 13);
} }
void YSFCodec::writeVDMode2Data(uint8_t* data, const uint8_t* dt) void YSF::writeVDMode2Data(uint8_t* data, const uint8_t* dt)
{ {
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES; data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
@ -1293,7 +1292,7 @@ void YSFCodec::writeVDMode2Data(uint8_t* data, const uint8_t* dt)
} }
} }
void YSFCodec::get_ambe() void YSF::get_ambe()
{ {
#if !defined(Q_OS_IOS) #if !defined(Q_OS_IOS)
uint8_t ambe[7]; uint8_t ambe[7];
@ -1306,7 +1305,7 @@ void YSFCodec::get_ambe()
#endif #endif
} }
void YSFCodec::process_rx_data() void YSF::process_rx_data()
{ {
int16_t pcm[160]; int16_t pcm[160];
uint8_t ambe[7]; uint8_t ambe[7];
@ -1378,6 +1377,7 @@ void YSFCodec::process_rx_data()
m_rximbecodecq.clear(); m_rximbecodecq.clear();
//m_ambedev->clear_queue(); //m_ambedev->clear_queue();
qDebug() << "YSF playback stopped"; qDebug() << "YSF playback stopped";
m_modeinfo.stream_state = STREAM_IDLE;
return; return;
} }
} }

@ -15,8 +15,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef YSFCODEC_H #ifndef YSF_H
#define YSFCODEC_H #define YSF_H
#include <cstdint> #include <cstdint>
@ -50,15 +50,15 @@ const uint8_t YSF_MR_NOT_BUSY = 0x01U;
const uint8_t YSF_MR_BUSY = 0x02U; const uint8_t YSF_MR_BUSY = 0x02U;
#include <string> #include <string>
#include "codec.h" #include "mode.h"
#include "YSFFICH.h" #include "YSFFICH.h"
class YSFCodec : public Codec class YSF : public Mode
{ {
Q_OBJECT Q_OBJECT
public: public:
YSFCodec(QString callsign, QString hostname, QString host, int port, bool ipv6, QString vocoder, QString modem, QString audioin, QString audioout); YSF();
~YSFCodec(); ~YSF();
void set_fcs_mode(bool y, std::string f = " "){ m_fcs = y; m_fcsname = f; } void set_fcs_mode(bool y, std::string f = " "){ m_fcs = y; m_fcsname = f; }
private slots: private slots:
void process_udp(); void process_udp();
Loading…
Cancel
Save