diff --git a/reflector/BMProtocol.cpp b/reflector/BMProtocol.cpp index 7bc07fd..6c57bc1 100644 --- a/reflector/BMProtocol.cpp +++ b/reflector/BMProtocol.cpp @@ -205,7 +205,7 @@ void CBMProtocol::HandleQueue(void) { // encode it CBuffer buffer; - if ( EncodeDvPacket(*packet, &buffer) ) + if ( EncodeDvPacket(*packet, buffer) ) { // encode revision dependent version CBuffer bufferLegacy = buffer; @@ -571,57 +571,39 @@ void CBMProtocol::EncodeConnectNackPacket(CBuffer *Buffer) Buffer->Append((uint8_t)0); } -bool CBMProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer *Buffer) const +bool CBMProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer &Buffer) const { uint8_t tag[] = { 'D','S','V','T',0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; struct dstar_header DstarHeader; Packet.ConvertToDstarStruct(&DstarHeader); - Buffer->Set(tag, sizeof(tag)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)0x80); - Buffer->Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); + Buffer.Append((uint8_t)0x80); + Buffer.Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); return true; } -bool CBMProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const +bool CBMProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer &Buffer) const { uint8_t 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_t)(Packet.GetDstarPacketId() % 21)); - Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); - Buffer->Append((uint8_t *)Packet.GetDvData(), 3); + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); + auto pid = (uint8_t)(Packet.GetPacketId() % 21u); + if (Packet.IsLastPacket()) + pid |= 0x40u; + Buffer.Append(pid); + Buffer.Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); + Buffer.Append((uint8_t *)Packet.GetDvData(), 3); - Buffer->Append((uint8_t)Packet.GetDmrPacketId()); - Buffer->Append((uint8_t)Packet.GetDmrPacketSubid()); - Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dmr), 9); - Buffer->Append((uint8_t *)Packet.GetDvSync(), 7); + Buffer.Append((uint8_t)Packet.GetDmrPacketId()); + Buffer.Append((uint8_t)Packet.GetDmrPacketSubid()); + Buffer.Append((uint8_t *)Packet.GetCodecData(ECodecType::dmr), 9); + Buffer.Append((uint8_t *)Packet.GetDvSync(), 7); return true; } - -bool CBMProtocol::EncodeDvLastFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const -{ - uint8_t tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; - uint8_t dstarambe[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t dstardvdata[] = { 0x25,0x1A,0xC6 }; - - Buffer->Set(tag, sizeof(tag)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)((Packet.GetPacketId() % 21) | 0x40)); - Buffer->Append(dstarambe, sizeof(dstarambe)); - Buffer->Append(dstardvdata, sizeof(dstardvdata)); - - - Buffer->Append((uint8_t)Packet.GetDmrPacketId()); - Buffer->Append((uint8_t)Packet.GetDmrPacketSubid()); - Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dmr), 9); - Buffer->Append((uint8_t *)Packet.GetDvSync(), 7); - - return true; -} diff --git a/reflector/BMProtocol.h b/reflector/BMProtocol.h index da58320..06b3905 100644 --- a/reflector/BMProtocol.h +++ b/reflector/BMProtocol.h @@ -66,9 +66,8 @@ protected: void EncodeDisconnectPacket(CBuffer *); void EncodeConnectAckPacket(CBuffer *, const char *); void EncodeConnectNackPacket(CBuffer *); - bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const; - bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; - bool EncodeDvLastFramePacket(const CDvFramePacket &, CBuffer *) const; + bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer &) const; + bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer &) const; protected: // time diff --git a/reflector/Buffer.h b/reflector/Buffer.h index b4cf127..deec049 100644 --- a/reflector/Buffer.h +++ b/reflector/Buffer.h @@ -63,6 +63,7 @@ public: // pass through void clear() { m_data.clear(); } + void reserve(unsigned int size) { m_data.reserve(size); } std::vector::size_type size() const { return m_data.size(); } uint8_t *data() { return m_data.data(); } const uint8_t *data() const { return m_data.data(); } diff --git a/reflector/Callsign.h b/reflector/Callsign.h index 184aade..d05b60f 100644 --- a/reflector/Callsign.h +++ b/reflector/Callsign.h @@ -41,7 +41,7 @@ public: // status bool IsValid(void) const; bool HasSuffix(void) const; - bool HasModule(void) const { return m_Module != ' '; } + bool HasModule(void) const { return m_Module != ' '; } // set void SetCallsign(const char *, bool = true); @@ -59,9 +59,9 @@ public: void GetCallsign(uint8_t *) const; void GetCallsignString(char *) const; const std::string GetCS(unsigned len = 9) const; - uint32_t GetDmrid(void) const { return m_uiDmrid; } + uint32_t GetDmrid(void) const { return m_uiDmrid; } void GetSuffix(uint8_t *) const; - char GetCSModule(void) const { return m_Module; } + char GetCSModule(void) const { return m_Module; } // compare bool HasSameCallsign(const CCallsign &) const; diff --git a/reflector/DExtraProtocol.cpp b/reflector/DExtraProtocol.cpp index 9f9302c..3b55594 100644 --- a/reflector/DExtraProtocol.cpp +++ b/reflector/DExtraProtocol.cpp @@ -236,7 +236,7 @@ void CDextraProtocol::HandleQueue(void) // encode it CBuffer buffer; - if ( EncodeDvPacket(*packet, &buffer) ) + if ( EncodeDvPacket(*packet, buffer) ) { // and push it to all our clients linked to the module and who are not streaming in CClients *clients = g_Reflector.GetClients(); @@ -586,33 +586,33 @@ void CDextraProtocol::EncodeDisconnectedPacket(CBuffer *Buffer) Buffer->Set(tag, sizeof(tag)); } -bool CDextraProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer *Buffer) const +bool CDextraProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer &Buffer) const { uint8_t tag[] = { 'D','S','V','T',0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; struct dstar_header DstarHeader; Packet.ConvertToDstarStruct(&DstarHeader); - Buffer->Set(tag, sizeof(tag)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)0x80); - Buffer->Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); + Buffer.Append((uint8_t)0x80); + Buffer.Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); return true; } -bool CDextraProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const +bool CDextraProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer &Buffer) const { uint8_t tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; - Buffer->Set(tag, sizeof(tag)); - Buffer->Append(Packet.GetStreamId()); + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); uint8_t id = Packet.GetDstarPacketId() % 21; if (Packet.IsLastPacket()) id |= 0x40U; - Buffer->Append(id); - Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); - Buffer->Append((uint8_t *)Packet.GetDvData(), 3); + Buffer.Append(id); + Buffer.Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); + Buffer.Append((uint8_t *)Packet.GetDvData(), 3); return true; diff --git a/reflector/DExtraProtocol.h b/reflector/DExtraProtocol.h index 42f76d4..69f329d 100644 --- a/reflector/DExtraProtocol.h +++ b/reflector/DExtraProtocol.h @@ -81,8 +81,8 @@ protected: void EncodeConnectNackPacket(CBuffer *); void EncodeDisconnectPacket(CBuffer *, char); void EncodeDisconnectedPacket(CBuffer *); - bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const; - bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; + bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer &) const; + bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer &) const; protected: // time diff --git a/reflector/DPlusProtocol.cpp b/reflector/DPlusProtocol.cpp index a3e085a..fe55dd8 100644 --- a/reflector/DPlusProtocol.cpp +++ b/reflector/DPlusProtocol.cpp @@ -248,7 +248,7 @@ void CDplusProtocol::HandleQueue(void) // encode it CBuffer buffer; - if ( EncodeDvPacket(*packet, &buffer) ) + if ( EncodeDvPacket(*packet, buffer) ) { // and push it to all our clients who are not streaming in // note that for dplus protocol, all stream of all modules are push to all clients @@ -300,7 +300,7 @@ void CDplusProtocol::SendDvHeader(CDvHeaderPacket *packet, CDplusClient *client) { // encode it CBuffer buffer; - if ( EncodeDvPacket(*packet, &buffer) ) + if ( EncodeDvPacket(*packet, buffer) ) { if ( (client->IsDextraDongle() || !client->HasModule()) ) { @@ -312,7 +312,7 @@ void CDplusProtocol::SendDvHeader(CDvHeaderPacket *packet, CDplusClient *client) // encode it CBuffer buffer2; - if ( EncodeDvPacket(packet2, &buffer2) ) + if ( EncodeDvPacket(packet2, buffer2) ) { // and send it Send(buffer2, client->GetIp()); @@ -466,44 +466,41 @@ void CDplusProtocol::EncodeDisconnectPacket(CBuffer *Buffer) } -bool CDplusProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer *Buffer) const +bool CDplusProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer &Buffer) const { uint8_t tag[] = { 0x3A,0x80,0x44,0x53,0x56,0x54,0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; struct dstar_header DstarHeader; Packet.ConvertToDstarStruct(&DstarHeader); - Buffer->Set(tag, sizeof(tag)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)0x80); - Buffer->Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); + Buffer.Append((uint8_t)0x80); + Buffer.Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); return true; } -bool CDplusProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const +bool CDplusProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer &Buffer) const { uint8_t tag[] = { 0x1D,0x80,0x44,0x53,0x56,0x54,0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; - Buffer->Set(tag, sizeof(tag)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)(Packet.GetPacketId() % 21)); - Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); - Buffer->Append((uint8_t *)Packet.GetDvData(), 3); - - return true; - -} - -bool CDplusProtocol::EncodeDvLastFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const -{ - uint8_t tag1[] = { 0x20,0x80,0x44,0x53,0x56,0x54,0x20,0x00,0x81,0x00,0x20,0x00,0x01,0x02 }; - uint8_t tag2[] = { 0x55,0xC8,0x7A,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x25,0x1A,0xC6 }; + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); + if (Packet.IsLastPacket()) + { + uint8_t tag2[] = { 0x55,0xC8,0x7A,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x25,0x1A,0xC6 }; - Buffer->Set(tag1, sizeof(tag1)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)((Packet.GetPacketId() % 21) | 0x40)); - Buffer->Append(tag2, sizeof(tag2)); + Buffer.Append((uint8_t)((Packet.GetPacketId() % 21) | 0x40)); + Buffer.Append(tag2, sizeof(tag2)); + } + else + { + Buffer.Append((uint8_t)(Packet.GetPacketId() % 21)); + Buffer.Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); + Buffer.Append((uint8_t *)Packet.GetDvData(), 3); + } return true; + } diff --git a/reflector/DPlusProtocol.h b/reflector/DPlusProtocol.h index 35b5144..8b151e5 100644 --- a/reflector/DPlusProtocol.h +++ b/reflector/DPlusProtocol.h @@ -67,14 +67,12 @@ protected: void EncodeLoginAckPacket(CBuffer *); void EncodeLoginNackPacket(CBuffer *); void EncodeDisconnectPacket(CBuffer *); - bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const; - bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; - bool EncodeDvLastFramePacket(const CDvFramePacket &, CBuffer *) const; - + bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer &) const; + bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer &) const; protected: // for keep alive - CTimer m_LastKeepaliveTime; + CTimer m_LastKeepaliveTime; // for queue header caches std::unordered_map m_StreamsCache; diff --git a/reflector/DVFramePacket.cpp b/reflector/DVFramePacket.cpp index 7ba0eeb..c4a37c5 100644 --- a/reflector/DVFramePacket.cpp +++ b/reflector/DVFramePacket.cpp @@ -107,6 +107,57 @@ CDvFramePacket::CDvFramePacket(const CM17Packet &m17) : CPacket(m17) } } +// Network +unsigned int CDvFramePacket::GetNetworkSize() +{ + return CPacket::GetNetworkSize() + 4 + 3 + 7 + 14 + 9 + 9 + 16; +} + +CDvFramePacket::CDvFramePacket(const CBuffer &buf) : CPacket(buf) +{ + if (buf.size() >= GetNetworkSize()) + { + auto data = buf.data(); + auto off = CPacket::GetNetworkSize(); + uint32_t seq = 0; + for (unsigned int i=0; i<4; i++) + seq = 0x100u * seq + data[off+i]; + off += 4; + memcpy(m_uiDvData, data+off, 3); off += 3; + memcpy(m_uiDvSync, data+off, 7); off += 7; + memcpy(m_Nonce, data+off, 14); off += 14; + memcpy(m_TCPack.dstar, data+off, 9); off += 9; + memcpy(m_TCPack.dmr, data+off, 9); off += 9; + memcpy(m_TCPack.m17, data+off, 16); off += 16; + SetTCParams(seq); + m_TCPack.rt_timer.start(); + m_TCPack.module = m_cModule; + m_TCPack.is_last = m_bLastPacket; + m_TCPack.streamid = m_uiStreamId; + m_TCPack.codec_in = m_eCodecIn; + } + else + std::cerr << "CBuffer is too small to initialize a CDvFramePacket" << std::endl; +} + +void CDvFramePacket::EncodeInterlinkPacket(CBuffer &buf) const +{ + CPacket::EncodeInterlinkPacket("URFF", buf); + buf.resize(GetNetworkSize()); + auto data = buf.data(); + auto off = CPacket::GetNetworkSize(); + data[off++] = (m_TCPack.sequence / 0x1000000u) & 0xffu; + data[off++] = (m_TCPack.sequence / 0x10000u) & 0xffu; + data[off++] = (m_TCPack.sequence / 0x100u) & 0xffu; + data[off++] = m_TCPack.sequence & 0xffu; + memcpy(data+off, m_uiDvData, 3); off += 3; + memcpy(data+off, m_uiDvSync, 7); off += 7; + memcpy(data+off, m_Nonce, 14); off += 14; + memcpy(data+off, m_TCPack.dstar, 9); off += 9; + memcpy(data+off, m_TCPack.dmr, 9); off += 9; + memcpy(data+off, m_TCPack.m17, 16); +} + //////////////////////////////////////////////////////////////////////////////////////// // virtual duplication diff --git a/reflector/DVFramePacket.h b/reflector/DVFramePacket.h index 1af47a2..49380b3 100644 --- a/reflector/DVFramePacket.h +++ b/reflector/DVFramePacket.h @@ -50,6 +50,10 @@ public: CDvFramePacket(uint16_t streamid, uint8_t counter, const uint8_t *ambe, const uint8_t *dvdata, uint8_t counter1, uint8_t counter2, const uint8_t *ambe2, const uint8_t *dmrsync, ECodecType type, bool islast); // M17 Frame CDvFramePacket(const CM17Packet &m17); + // URF Network + CDvFramePacket(const CBuffer &buf); + static unsigned int GetNetworkSize(); + void EncodeInterlinkPacket(CBuffer &buf) const; // virtual duplication std::unique_ptr Duplicate(void) const; diff --git a/reflector/DVHeaderPacket.cpp b/reflector/DVHeaderPacket.cpp index d0e2cd3..4077f3e 100644 --- a/reflector/DVHeaderPacket.cpp +++ b/reflector/DVHeaderPacket.cpp @@ -33,6 +33,53 @@ CDvHeaderPacket::CDvHeaderPacket() m_uiCrc = 0; } +// network +CDvHeaderPacket::CDvHeaderPacket(const CBuffer &buf) : CPacket(buf) +{ + if (buf.size() >= GetNetworkSize()) + { + auto o = CPacket::GetNetworkSize(); + auto data = buf.data(); + m_uiFlag1 = data[o++]; + m_uiFlag2 = data[o++]; + m_uiFlag3 = data[o++]; + m_csUR.SetCallsign(data+o, CALLSIGN_LEN); + o += CALLSIGN_LEN; + m_csRPT1.SetCallsign(data+o, CALLSIGN_LEN); + o += CALLSIGN_LEN; + m_csRPT2.SetCallsign(data+o, CALLSIGN_LEN); + o += CALLSIGN_LEN; + m_csMY.SetCallsign(data+o, CALLSIGN_LEN); + o += CALLSIGN_LEN; + m_uiCrc = data[o] * 0x100u + data[o+1]; + } + else + { + std::cerr << "CBuffer is too small to initialize a CDvHeaderPacket" << std::endl; + } +} +unsigned int CDvHeaderPacket::GetNetworkSize() +{ + return CPacket::GetNetworkSize() + (4 * CALLSIGN_LEN) + 5; +} + +void CDvHeaderPacket::EncodeInterlinkPacket(CBuffer &buf) const +{ + CPacket::EncodeInterlinkPacket("URFH", buf); + buf.resize(GetNetworkSize()); + auto data = buf.data(); + auto off = CPacket::GetNetworkSize(); + data[off++] = m_uiFlag1; + data[off++] = m_uiFlag2; + data[off++] = m_uiFlag3; + m_csUR.GetCallsign(data+off); off += CALLSIGN_LEN; + m_csRPT1.GetCallsign(data+off); off += CALLSIGN_LEN; + m_csRPT2.GetCallsign(data+off); off += CALLSIGN_LEN; + m_csMY.GetCallsign(data+off); off += CALLSIGN_LEN; + data[off++] = (m_uiCrc / 0x100u) & 0xffu; + data[off] = m_uiCrc & 0xffu; +} + // dstar constructor CDvHeaderPacket::CDvHeaderPacket(const struct dstar_header *buffer, uint16_t sid, uint8_t pid) diff --git a/reflector/DVHeaderPacket.h b/reflector/DVHeaderPacket.h index e78427d..7216fda 100644 --- a/reflector/DVHeaderPacket.h +++ b/reflector/DVHeaderPacket.h @@ -59,6 +59,11 @@ public: CDvHeaderPacket(const CCallsign &, const CCallsign &, const CCallsign &, const CCallsign &, uint16_t, uint8_t); CDvHeaderPacket(const CM17Packet &); + // network + CDvHeaderPacket(const CBuffer &buf); + static unsigned int GetNetworkSize(); + void EncodeInterlinkPacket(CBuffer &buf) const; + // virtual duplication std::unique_ptr Duplicate(void) const; @@ -89,9 +94,6 @@ public: // operators bool operator ==(const CDvHeaderPacket &) const; -#ifdef IMPLEMENT_CDVHEADERPACKET_CONST_CHAR_OPERATOR - operator const char *() const; -#endif protected: // data @@ -103,8 +105,4 @@ protected: CCallsign m_csRPT2; CCallsign m_csMY; uint16_t m_uiCrc; -#ifdef IMPLEMENT_CDVHEADERPACKET_CONST_CHAR_OPERATOR - // buffer - char m_sz[256]; -#endif }; diff --git a/reflector/G3Protocol.cpp b/reflector/G3Protocol.cpp index 33f465d..1368e54 100644 --- a/reflector/G3Protocol.cpp +++ b/reflector/G3Protocol.cpp @@ -451,7 +451,7 @@ void CG3Protocol::HandleQueue(void) // encode it CBuffer buffer; - if ( EncodeDvPacket(*packet, &buffer) ) + if ( EncodeDvPacket(*packet, buffer) ) { // and push it to all our clients linked to the module and who are not streaming in CClients *clients = g_Reflector.GetClients(); @@ -612,46 +612,43 @@ bool CG3Protocol::IsValidDvFramePacket(const CBuffer &Buffer, std::unique_ptrSet(tag, sizeof(tag)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)0x80); - Buffer->Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); + Buffer.Append((uint8_t)0x80); + Buffer.Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header)); return true; } -bool CG3Protocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const +bool CG3Protocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer &Buffer) const { uint8_t 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_t)(Packet.GetPacketId() % 21)); - Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); - Buffer->Append((uint8_t *)Packet.GetDvData(), 3); - - return true; - -} - -bool CG3Protocol::EncodeDvLastFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const -{ - uint8_t tag1[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; - uint8_t tag2[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1A,0xC6 }; + Buffer.Set(tag, sizeof(tag)); + Buffer.Append(Packet.GetStreamId()); + if (Packet.IsLastPacket()) + { + uint8_t tag2[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1A,0xC6 }; - Buffer->Set(tag1, sizeof(tag1)); - Buffer->Append(Packet.GetStreamId()); - Buffer->Append((uint8_t)((Packet.GetPacketId() % 21) | 0x40)); - Buffer->Append(tag2, sizeof(tag2)); + Buffer.Append((uint8_t)((Packet.GetPacketId() % 21) | 0x40)); + Buffer.Append(tag2, sizeof(tag2)); + } + else + { + Buffer.Append((uint8_t)(Packet.GetPacketId() % 21)); + Buffer.Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9); + Buffer.Append((uint8_t *)Packet.GetDvData(), 3); + } return true; + } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/reflector/G3Protocol.h b/reflector/G3Protocol.h index a39bb86..193e529 100644 --- a/reflector/G3Protocol.h +++ b/reflector/G3Protocol.h @@ -99,9 +99,8 @@ protected: bool IsValidDvFramePacket(const CBuffer &, std::unique_ptr &); // packet encoding helpers - bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const; - bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; - bool EncodeDvLastFramePacket(const CDvFramePacket &, CBuffer *) const; + bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer &) const; + bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer &) const; protected: std::future m_PresenceFuture, m_ConfigFuture, m_IcmpFuture; diff --git a/reflector/Packet.cpp b/reflector/Packet.cpp index 504ab60..8efbd01 100644 --- a/reflector/Packet.cpp +++ b/reflector/Packet.cpp @@ -36,7 +36,58 @@ CPacket::CPacket() m_bLastPacket = false; }; -// dstar contrsuctor +// for the network +unsigned int CPacket::GetNetworkSize() +{ + return 20u; +} + +CPacket::CPacket(const CBuffer &buf) +{ + if (buf.size() > 19) + { + auto data = buf.data(); + m_eCodecIn = (ECodecType)data[4]; + m_eOrigin = (EOrigin)data[5]; + m_bLastPacket = data[6] ? true : false; + m_cModule = data[7]; + m_uiStreamId = data[8]*0x100u + data[9]; + m_uiM17FrameNumber = data[10]*0x1000000u + data[11]*0x10000u + data[12]*0x100 + data[13]; + m_uiDstarPacketId = data[14]; + m_uiDmrPacketId = data[15]; + m_uiDmrPacketSubid = data[16]; + m_uiYsfPacketId = data[17]; + m_uiYsfPacketSubId = data[18]; + m_uiYsfPacketFrameId = data[19]; + } + else + std::cerr << "CPacket initialization failed because the buffer is too small!" << std::endl; +} + +void CPacket::EncodeInterlinkPacket(const char *magic, CBuffer &buf) const +{ + buf.Set(magic); + buf.resize(20); + auto data = buf.data(); + data[4] = (uint8_t)m_eCodecIn; + data[5] = (uint8_t)m_eOrigin; + data[6] = m_bLastPacket ? 1 : 0; + data[7] = m_cModule; + data[8] = m_uiStreamId / 0x100u; + data[9] = m_uiStreamId % 0x100u; + data[10] = (m_uiM17FrameNumber / 0x1000000u) % 0x100u; + data[11] = (m_uiM17FrameNumber / 0x10000u) % 0x100u; + data[12] = (m_uiM17FrameNumber / 0x100u) % 0x100u; + data[13] = m_uiM17FrameNumber % 100u; + data[14] = m_uiDstarPacketId; + data[15] = m_uiDmrPacketId; + data[16] = m_uiDmrPacketSubid; + data[17] = m_uiYsfPacketId; + data[18] = m_uiYsfPacketSubId; + data[19] = m_uiYsfPacketFrameId; +} + +// dstar contstructor CPacket::CPacket(uint16_t sid, uint8_t dstarpid) { m_uiStreamId = sid; diff --git a/reflector/Packet.h b/reflector/Packet.h index b62cb8c..8cba8c1 100644 --- a/reflector/Packet.h +++ b/reflector/Packet.h @@ -20,16 +20,18 @@ // Origin Id +#include "Buffer.h" #include "TCPacketDef.h" #include "M17Packet.h" -enum class EOrigin { local, peer }; +enum class EOrigin : std::uint8_t { local=0, peer=1 }; class CPacket { public: // constructor CPacket(); + CPacket(const CBuffer &Buffer); CPacket(uint16_t sid, uint8_t dstarpid); CPacket(uint16_t sid, uint8_t dmrpid, uint8_t dmrsubpid, bool lastpacket); CPacket(uint16_t sid, uint8_t ysfpid, uint8_t ysfsubpid, uint8_t ysfsubpidmax, bool lastpacket); @@ -70,7 +72,12 @@ public: void SetRemotePeerOrigin(void) { m_eOrigin = EOrigin::peer; } protected: + // network + void EncodeInterlinkPacket(const char *magic, CBuffer &Buffer) const; + static unsigned int GetNetworkSize(); + // data + // if you change something here, you'll need to update the CBuffer ctor and EncodeInterlinkPacket()!!! ECodecType m_eCodecIn; EOrigin m_eOrigin; bool m_bLastPacket; diff --git a/reflector/SEProtocol.cpp b/reflector/SEProtocol.cpp index 59e8c53..ba036ee 100644 --- a/reflector/SEProtocol.cpp +++ b/reflector/SEProtocol.cpp @@ -16,7 +16,7 @@ #include "SEProtocol.h" -bool CSEProtocol::EncodeDvPacket(const CPacket &packet, CBuffer *buffer) const +bool CSEProtocol::EncodeDvPacket(const CPacket &packet, CBuffer &buffer) const { if ( packet.IsDvFrame() ) return EncodeDvFramePacket((CDvFramePacket &)packet, buffer); diff --git a/reflector/SEProtocol.h b/reflector/SEProtocol.h index 3c2614e..a45bf31 100644 --- a/reflector/SEProtocol.h +++ b/reflector/SEProtocol.h @@ -23,7 +23,7 @@ class CSEProtocol : public CProtocol { protected: // packet encoding helpers - virtual bool EncodeDvPacket(const CPacket &, CBuffer *) const; - virtual bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const = 0; - virtual bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const = 0; + virtual bool EncodeDvPacket(const CPacket &, CBuffer &) const; + virtual bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer &) const = 0; + virtual bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer &) const = 0; }; diff --git a/reflector/URFProtocol.cpp b/reflector/URFProtocol.cpp index 65b6709..7df0815 100644 --- a/reflector/URFProtocol.cpp +++ b/reflector/URFProtocol.cpp @@ -215,7 +215,7 @@ void CURFProtocol::HandleQueue(void) { // encode it CBuffer buffer; - if ( EncodeDvPacket(*packet, &buffer) ) + if ( EncodeDvPacket(*packet, buffer) ) { // and push it to all our clients linked to the module and who are not streaming in CClients *clients = g_Reflector.GetClients(); @@ -472,10 +472,12 @@ bool CURFProtocol::IsValidNackPacket(const CBuffer &Buffer, CCallsign *callsign) bool CURFProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, std::unique_ptr &header) { - if (sizeof(CDvHeaderPacket) == Buffer.size()) { - header = std::unique_ptr(new CDvHeaderPacket()); - memcpy(header.get(), Buffer.data(), sizeof(CDvHeaderPacket)); - if (header) { + uint8_t magic[] = { 'U', 'R', 'F', 'H' }; + if (Buffer.size()==CDvHeaderPacket::GetNetworkSize() && 0==Buffer.Compare(magic, 4)) + { + header = std::unique_ptr(new CDvHeaderPacket(Buffer)); + if (header) + { if (header->IsValid()) return true; else @@ -487,14 +489,12 @@ bool CURFProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, std::unique_ptr< bool CURFProtocol::IsValidDvFramePacket(const CBuffer &Buffer, std::unique_ptr &dvframe) { - // otherwise try protocol revision 2 - if (sizeof(CDvFramePacket)==Buffer.size()) + uint8_t magic[] = { 'U', 'R', 'F', 'F' }; + if (Buffer.size()==CDvFramePacket::GetNetworkSize() && 0==Buffer.Compare(magic, 4)) { - // create packet - dvframe = std::unique_ptr(new CDvFramePacket()); - memcpy(dvframe.get(), Buffer.data(), sizeof(CDvFramePacket)); - // check validity of packet - if (dvframe) { + dvframe = std::unique_ptr(new CDvFramePacket(Buffer)); + if (dvframe) + { if (dvframe->IsValid()) return true; else @@ -507,19 +507,15 @@ bool CURFProtocol::IsValidDvFramePacket(const CBuffer &Buffer, std::unique_ptrresize(len); - memcpy(buffer->data(), &packet, len); + packet.EncodeInterlinkPacket(buffer); return true; } -bool CURFProtocol::EncodeDvFramePacket(const CDvFramePacket &packet, CBuffer *buffer) const +bool CURFProtocol::EncodeDvFramePacket(const CDvFramePacket &packet, CBuffer &buffer) const { - auto len = sizeof(CDvFramePacket); - buffer->resize(len); - memcpy(buffer->data(), &packet, len); + packet.EncodeInterlinkPacket(buffer); return true; } diff --git a/reflector/URFProtocol.h b/reflector/URFProtocol.h index b634390..5418a0e 100644 --- a/reflector/URFProtocol.h +++ b/reflector/URFProtocol.h @@ -61,8 +61,8 @@ protected: void EncodeDisconnectPacket(CBuffer *); void EncodeConnectAckPacket(CBuffer *, const char *); void EncodeConnectNackPacket(CBuffer *Buffer); - bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const; - bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; + bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer &) const; + bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer &) const; protected: // time