mirror of https://github.com/LX3JL/xlxd.git
Implementation of the "vocoder extension" by SV9OAN, as described in https://github.com/chazapis/pydv, which allows the use of the open source Codec 2 with D-STAR. With the changes here, xlxd/ambed can be used to transcode and bridge the two formats. The solution implemented uses an additional DExtra listener on a different port (30201 instead of 30001). The new port is to be used by reflectors using the "ORF" prefix (Open ReFlector). Any client connected to an ORF reflector will receive streams encoded with Codec 2. All other D-STAR protocol handlers will still send out data encoded with AMBE. Note that the protocol/port only affects data transmitted by the reflector. The stream vocoder is recognized by all protocol handlers, so a client can still transmit data using any vocoder on any port. The rationale behind this is that DExtra links may be used by repeaters or other reflectors, so it is not really possible to know what their clients support. So, nothing will change when linking a repeater to an XRF reflector, but will do when linking to an ORF one. Summary of code changes in xlxd: * Added protocol "DExtra Open", listening on port 30201. The protocol handler is subclassed from DExtra. Minor changes were required to make the DExtra implementation more "abstract" to allow that. * Codec used no longer a protocol client property. All D-STAR protocol handlers use the header to determine the protocol. DMR protocol handlers just specify the appropriate codec when opening a stream. * DV frames now also include Codec 2 data. * Interface with ambed changed to 1 codec in, 2 codecs out. * Interface with other xlx peers changed to accommodate the enlarged DV frames, so compatible peers will exchange fully transcoded streams. * Major version changed to 3, to recognize peer compatibility. Summary of code changes to ambed: * Added (virtual) interface class for Codec 2. * Vocodec channels now have 3 interfaces (1 in, 2 out) and are grouped together in triplets. Each group contains all possible permutations of respective interfaces - 3 channels. Only one channel from each group can be used at a given time. * When an incoming packet is decoded in the interface loop, it is duplicated and sent to two separate voice queues (one for each outgoing codec). * Interface changed to 1 codec in, 2 codecs out. * Major version changed to 2, as the interface is incompatible with previous versions.pull/118/head
parent
b3360b66e2
commit
9581d729a7
@ -0,0 +1,242 @@
|
||||
//
|
||||
// ccodec2interface.cpp
|
||||
// ambed
|
||||
//
|
||||
// Created by Antony Chazapis (SV9OAN) on 26/12/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include "ctimepoint.h"
|
||||
#include "cambepacket.h"
|
||||
#include "cvoicepacket.h"
|
||||
#include "ccodec2interface.h"
|
||||
#include "cvocodecchannel.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CCodec2Interface::CCodec2Interface()
|
||||
: CVocodecInterface()
|
||||
{}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// destructor
|
||||
|
||||
CCodec2Interface::~CCodec2Interface()
|
||||
{
|
||||
codec2_destroy(codec2_state);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// initialization
|
||||
|
||||
bool CCodec2Interface::Init(void)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
// create codec state
|
||||
codec2_state = codec2_create(CODEC2_MODE_3200);
|
||||
if (codec2_state == NULL)
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
// base class
|
||||
if ( ok )
|
||||
{
|
||||
ok &= CVocodecInterface::Init();
|
||||
}
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// task
|
||||
|
||||
void CCodec2Interface::Task(void)
|
||||
{
|
||||
CPacketQueue *Queue;
|
||||
CVocodecChannel *Channel;
|
||||
CAmbePacket AmbePacket;
|
||||
CVoicePacket VoicePacket;
|
||||
bool done;
|
||||
|
||||
// process the streams (channels) incoming queue
|
||||
do
|
||||
{
|
||||
done = true;
|
||||
for ( int i = 0; i < GetNbChannels(); i++ )
|
||||
{
|
||||
// get active outgoing channel for interface channel
|
||||
Channel = GetChannelWithChannelOut(i);
|
||||
|
||||
// any packet in voice queue 1 ?
|
||||
if ( Channel != NULL && Channel->IsInterfaceOut1(this) )
|
||||
{
|
||||
CVoicePacket *Packet = NULL;
|
||||
|
||||
Queue = Channel->GetVoiceQueue1();
|
||||
if ( !Queue->empty() )
|
||||
{
|
||||
// get packet
|
||||
Packet = (CVoicePacket *)Queue->front();
|
||||
Queue->pop();
|
||||
}
|
||||
Channel->ReleaseVoiceQueue1();
|
||||
|
||||
if ( Packet != NULL )
|
||||
{
|
||||
// this is second step of transcoding
|
||||
// we just received from a decoded speech packet
|
||||
// encode and cpush back to relevant channel outcoming queue
|
||||
EncodeVoicePacket(Packet, &AmbePacket);
|
||||
AmbePacket.SetPid(Packet->GetPid());
|
||||
delete Packet;
|
||||
|
||||
CAmbePacket *clone = new CAmbePacket(AmbePacket);
|
||||
|
||||
Queue = Channel->GetPacketQueueOut1();
|
||||
Queue->push(clone);
|
||||
Channel->ReleasePacketQueueOut1();
|
||||
|
||||
// done
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
|
||||
// any packet in voice queue 1 ?
|
||||
if ( Channel != NULL && Channel->IsInterfaceOut2(this) )
|
||||
{
|
||||
CVoicePacket *Packet = NULL;
|
||||
|
||||
Queue = Channel->GetVoiceQueue2();
|
||||
if ( !Queue->empty() )
|
||||
{
|
||||
// get packet
|
||||
Packet = (CVoicePacket *)Queue->front();
|
||||
Queue->pop();
|
||||
}
|
||||
Channel->ReleaseVoiceQueue2();
|
||||
|
||||
if ( Packet != NULL )
|
||||
{
|
||||
// this is second step of transcoding
|
||||
// we just received from a decoded speech packet
|
||||
// encode and cpush back to relevant channel outcoming queue
|
||||
EncodeVoicePacket(Packet, &AmbePacket);
|
||||
AmbePacket.SetPid(Packet->GetPid());
|
||||
delete Packet;
|
||||
|
||||
CAmbePacket *clone = new CAmbePacket(AmbePacket);
|
||||
|
||||
Queue = Channel->GetPacketQueueOut2();
|
||||
Queue->push(clone);
|
||||
Channel->ReleasePacketQueueOut2();
|
||||
|
||||
// done
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
|
||||
// get active incoming channel for interface channel
|
||||
Channel = GetChannelWithChannelIn(i);
|
||||
|
||||
// any packet in ambe queue for us ?
|
||||
if ( Channel != NULL && Channel->IsInterfaceIn(this) )
|
||||
{
|
||||
CAmbePacket *Packet = NULL;
|
||||
|
||||
Queue = Channel->GetPacketQueueIn();
|
||||
if ( !Queue->empty() )
|
||||
{
|
||||
// get packet
|
||||
Packet = (CAmbePacket *)Queue->front();
|
||||
Queue->pop();
|
||||
}
|
||||
Channel->ReleasePacketQueueIn();
|
||||
|
||||
if ( Packet != NULL )
|
||||
{
|
||||
// this is first step of transcoding
|
||||
// a fresh new packet to be transcoded is showing up
|
||||
// decode and copy the result into both voice queues
|
||||
DecodeAmbePacket(Packet, &VoicePacket);
|
||||
VoicePacket.SetPid(Packet->GetPid());
|
||||
delete Packet;
|
||||
|
||||
CVoicePacket *clone1 = new CVoicePacket(VoicePacket);
|
||||
clone1->ApplyGain(Channel->GetSpeechGain());
|
||||
CVoicePacket *clone2 = new CVoicePacket(*clone1);
|
||||
|
||||
Queue = Channel->GetVoiceQueue1();
|
||||
Queue->push(clone1);
|
||||
Channel->ReleaseVoiceQueue1();
|
||||
|
||||
Queue = Channel->GetVoiceQueue2();
|
||||
Queue->push(clone2);
|
||||
Channel->ReleaseVoiceQueue2();
|
||||
|
||||
// done
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
// and wait a bit
|
||||
CTimePoint::TaskSleepFor(2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// decoder helper
|
||||
|
||||
void CCodec2Interface::DecodeAmbePacket(CAmbePacket *PacketIn, CVoicePacket *PacketOut)
|
||||
{
|
||||
short voice[160];
|
||||
|
||||
codec2_decode(codec2_state, voice, (unsigned char *)PacketIn->GetAmbe());
|
||||
for ( int i = 0; i < 160; i++ )
|
||||
{
|
||||
voice[i] = MAKEWORD(HIBYTE(voice[i]), LOBYTE(voice[i]));
|
||||
}
|
||||
PacketOut->SetVoice((uint8 *)voice, 160 * 2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// encoder helpers
|
||||
|
||||
void CCodec2Interface::EncodeVoicePacket(CVoicePacket *PacketIn, CAmbePacket *PacketOut)
|
||||
{
|
||||
unsigned char ambe[AMBE_SIZE];
|
||||
short voice[160];
|
||||
|
||||
::memcpy(voice, (short *)PacketIn->GetVoice(), 160 * 2);
|
||||
for ( int i = 0; i < 160; i++ )
|
||||
{
|
||||
voice[i] = MAKEWORD(HIBYTE(voice[i]), LOBYTE(voice[i]));
|
||||
}
|
||||
codec2_encode(codec2_state, ambe, voice);
|
||||
ambe[8] = 0x00;
|
||||
PacketOut->SetCodec(CODEC_CODEC2);
|
||||
PacketOut->SetAmbe((uint8 *)ambe);
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
//
|
||||
// ccodec2interface.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Antony Chazapis (SV9OAN) on 26/12/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef ccodec2interface_h
|
||||
#define ccodec2interface_h
|
||||
|
||||
#include "cvocodecinterface.h"
|
||||
#include <codec2/codec2.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CCodec2Interface : public CVocodecInterface
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
CCodec2Interface();
|
||||
|
||||
// destructor
|
||||
virtual ~CCodec2Interface();
|
||||
|
||||
// initialization
|
||||
bool Init(void);
|
||||
|
||||
// get
|
||||
const char *GetName(void) const { return "Codec 2"; }
|
||||
|
||||
// manage channels
|
||||
int GetNbChannels(void) const { return 1; }
|
||||
uint8 GetChannelCodec(int) const { return CODEC_CODEC2; }
|
||||
|
||||
// task
|
||||
void Task(void);
|
||||
|
||||
protected:
|
||||
// decoder helper
|
||||
void DecodeAmbePacket(CAmbePacket *, CVoicePacket *);
|
||||
|
||||
// encoder helpers
|
||||
void EncodeVoicePacket(CVoicePacket *, CAmbePacket *);
|
||||
|
||||
// data
|
||||
struct CODEC2 *codec2_state;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* ccodec2interface_h */
|
||||
@ -0,0 +1,42 @@
|
||||
//
|
||||
// cdextraopenclient.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Antony Chazapis (SV9OAN) on 19/12/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include "cdextraopenclient.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructors
|
||||
|
||||
CDextraOpenClient::CDextraOpenClient()
|
||||
: CDextraClient()
|
||||
{}
|
||||
|
||||
CDextraOpenClient::CDextraOpenClient(const CCallsign &callsign, const CIp &ip, char reflectorModule, int protRev)
|
||||
: CDextraClient(callsign, ip, reflectorModule, protRev)
|
||||
{}
|
||||
|
||||
CDextraOpenClient::CDextraOpenClient(const CDextraClient &client)
|
||||
: CDextraClient(client)
|
||||
{}
|
||||
@ -0,0 +1,54 @@
|
||||
//
|
||||
// cdextraopenclient.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Antony Chazapis (SV9OAN) on 19/12/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cdextraopenclient_h
|
||||
#define cdextraopenclient_h
|
||||
|
||||
#include "cdextraclient.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CDextraOpenClient : public CDextraClient
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
CDextraOpenClient();
|
||||
CDextraOpenClient(const CCallsign &, const CIp &, char = ' ', int = 0);
|
||||
CDextraOpenClient(const CDextraClient &);
|
||||
|
||||
// destructor
|
||||
virtual ~CDextraOpenClient() {};
|
||||
|
||||
// identity
|
||||
int GetProtocol(void) const { return PROTOCOL_DEXTRA_OPEN; }
|
||||
const char *GetProtocolName(void) const { return "DExtra Open"; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cdextraopenclient_h */
|
||||
@ -0,0 +1,98 @@
|
||||
//
|
||||
// cdextraopenprotocol.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Antony Chazapis (SV9OAN) on 19/12/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include "cdextraopenprotocol.h"
|
||||
#include "cdextraopenclient.h"
|
||||
#include "creflector.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// operation
|
||||
|
||||
bool CDextraOpenProtocol::Init(void)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
// base class
|
||||
ok = CProtocol::Init();
|
||||
|
||||
// update the reflector callsign
|
||||
m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"ORF", 3);
|
||||
|
||||
// create our socket
|
||||
ok &= m_Socket.Open(DEXTRA_OPEN_PORT);
|
||||
if ( !ok )
|
||||
{
|
||||
std::cout << "Error opening socket on port UDP" << DEXTRA_OPEN_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
|
||||
}
|
||||
|
||||
// update time
|
||||
m_LastKeepaliveTime.Now();
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// create client
|
||||
|
||||
CClient *CDextraOpenProtocol::CreateClient(const CCallsign &callsign, const CIp &ip, char reflectormodule, int revision) const
|
||||
{
|
||||
CClient *client = new CDextraOpenClient(callsign, ip, reflectormodule, revision);
|
||||
return client;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// packet encoding helpers
|
||||
|
||||
bool CDextraOpenProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer *Buffer) const
|
||||
{
|
||||
uint8 tag[] = { 'D','S','V','T',0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
|
||||
struct dstar_header DstarHeader;
|
||||
|
||||
Packet.ConvertToDstarStruct(&DstarHeader, CODEC_CODEC2);
|
||||
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8)0x80);
|
||||
Buffer->Append((uint8 *)&DstarHeader, sizeof(struct dstar_header));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDextraOpenProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const
|
||||
{
|
||||
uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
|
||||
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8)(Packet.GetPacketId() % 21));
|
||||
Buffer->Append((uint8 *)Packet.GetCodec2(), AMBE_SIZE);
|
||||
Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
//
|
||||
// cdextraopenprotocol.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Antony Chazapis (SV9OAN) on 19/12/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cdextraopenprotocol_h
|
||||
#define cdextraopenprotocol_h
|
||||
|
||||
#include "cdextraprotocol.h"
|
||||
#include "cdvheaderpacket.h"
|
||||
#include "cdvframepacket.h"
|
||||
#include "cclient.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// With the D-STAR vocoder extension by SV9OAN, voice in D-STAR streams can be encoded
|
||||
// with either AMBE or Codec 2. Although the extension is backwards compatible and
|
||||
// implementations can use the same reflector connections as AMBE-only clients,
|
||||
// it should be avoided, to save the user confusion and establish interoperability.
|
||||
|
||||
// By implementing another DExtra listener on a different port (30201 instead of 30001),
|
||||
// xlxd can be used to bridge between the two formats. The new port is to be used by
|
||||
// reflectors using the "ORF" prefix (Open ReFlector).
|
||||
|
||||
// Any client connected to an ORF reflector will receive streams encoded with Codec 2.
|
||||
// All other D-STAR protocol handlers will still send out data encoded with AMBE.
|
||||
// Note that the protocol/port only affects data transmitted by the reflector.
|
||||
// The stream vocoder is recognized by all protocol handlers, so a client can still
|
||||
// transmit data using any vocoder on any port. The rationale behind this is that
|
||||
// DExtra links may be used by repeaters or other reflectors, so it is not really
|
||||
// possible to know what their clients support. So, nothing will change when linking
|
||||
// a repeater to an XRF reflector, but will do when linking to an ORF one.
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CDextraOpenProtocol : public CDextraProtocol
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CDextraOpenProtocol() {};
|
||||
|
||||
// destructor
|
||||
virtual ~CDextraOpenProtocol() {};
|
||||
|
||||
// initialization
|
||||
bool Init(void);
|
||||
|
||||
// identity
|
||||
int GetProtocol(void) const { return PROTOCOL_DEXTRA_OPEN; }
|
||||
|
||||
protected:
|
||||
// create client
|
||||
CClient *CreateClient(const CCallsign &, const CIp &, char, int) const;
|
||||
|
||||
// packet encoding helpers
|
||||
bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const;
|
||||
bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cdextraopenprotocol_h */
|
||||
Loading…
Reference in new issue