You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
6.1 KiB
163 lines
6.1 KiB
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Digital Voice Modem - Common Library
|
|
* GPLv2 Open Source. Use is subject to license terms.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright (C) 2023,2024,2025 Bryan Biedenkapp, N2PLL
|
|
*
|
|
*/
|
|
/**
|
|
* @file FrameQueue.h
|
|
* @ingroup network_core
|
|
* @file FrameQueue.cpp
|
|
* @ingroup network_core
|
|
*/
|
|
#if !defined(__FRAME_QUEUE_H__)
|
|
#define __FRAME_QUEUE_H__
|
|
|
|
#include "common/Defines.h"
|
|
#include "common/network/RTPHeader.h"
|
|
#include "common/network/RTPFNEHeader.h"
|
|
#include "common/network/RawFrameQueue.h"
|
|
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
namespace network
|
|
{
|
|
// ---------------------------------------------------------------------------
|
|
// Constants
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const uint8_t RTP_G711_PAYLOAD_TYPE = 0x00U;
|
|
|
|
const uint8_t DVM_RTP_PAYLOAD_TYPE = 0x56U;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Class Declaration
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @brief Implements the network RTP frame queuing logic.
|
|
* @ingroup network_core
|
|
*/
|
|
class HOST_SW_API FrameQueue : public RawFrameQueue {
|
|
public: typedef std::pair<const NET_FUNC::ENUM, const NET_SUBFUNC::ENUM> OpcodePair;
|
|
public:
|
|
auto operator=(FrameQueue&) -> FrameQueue& = delete;
|
|
auto operator=(FrameQueue&&) -> FrameQueue& = delete;
|
|
FrameQueue(FrameQueue&) = delete;
|
|
|
|
/**
|
|
* @brief Initializes a new instance of the FrameQueue class.
|
|
* @param socket Local port used to listen for incoming data.
|
|
* @param peerId Unique ID of this modem on the network.
|
|
*/
|
|
FrameQueue(udp::Socket* socket, uint32_t peerId, bool debug);
|
|
|
|
/**
|
|
* @brief Read message from the received UDP packet.
|
|
* @param[out] messageLength Actual length of message read from packet.
|
|
* @param[out] address IP address data read from.
|
|
* @param[out] addrLen
|
|
* @param[out] rtpHeader RTP Header.
|
|
* @param[out] fneHeader FNE Header.
|
|
* @returns UInt8Array Buffer containing message read.
|
|
*/
|
|
UInt8Array read(int& messageLength, sockaddr_storage& address, uint32_t& addrLen,
|
|
frame::RTPHeader* rtpHeader = nullptr, frame::RTPFNEHeader* fneHeader = nullptr);
|
|
/**
|
|
* @brief Write message to the UDP socket.
|
|
* @param[in] message Message buffer to frame and queue.
|
|
* @param length Length of message.
|
|
* @param streamId Message stream ID.
|
|
* @param peerId Peer ID.
|
|
* @param ssrc RTP SSRC ID.
|
|
* @param opcode Opcode.
|
|
* @param rtpSeq RTP Sequence.
|
|
* @param addr IP address to write data to.
|
|
* @param addrLen
|
|
* @returns bool True, if message was written, otherwise false.
|
|
*/
|
|
bool write(const uint8_t* message, uint32_t length, uint32_t streamId, uint32_t peerId,
|
|
uint32_t ssrc, OpcodePair opcode, uint16_t rtpSeq, sockaddr_storage& addr, uint32_t addrLen);
|
|
|
|
/**
|
|
* @brief Cache message to frame queue.
|
|
* @param[in] queue Queue of messages.
|
|
* @param[in] message Message buffer to frame and queue.
|
|
* @param length Length of message.
|
|
* @param streamId Message stream ID.
|
|
* @param peerId Peer ID.
|
|
* @param opcode Opcode.
|
|
* @param rtpSeq RTP Sequence.
|
|
* @param addr IP address to write data to.
|
|
* @param addrLen
|
|
*/
|
|
void enqueueMessage(udp::BufferQueue* queue, const uint8_t* message, uint32_t length, uint32_t streamId,
|
|
uint32_t peerId, OpcodePair opcode, uint16_t rtpSeq, sockaddr_storage& addr, uint32_t addrLen);
|
|
/**
|
|
* @brief Cache message to frame queue.
|
|
* @param[in] queue Queue of messages.
|
|
* @param[in] message Message buffer to frame and queue.
|
|
* @param length Length of message.
|
|
* @param streamId Message stream ID.
|
|
* @param peerId Peer ID.
|
|
* @param ssrc RTP SSRC ID.
|
|
* @param opcode Opcode.
|
|
* @param rtpSeq RTP Sequence.
|
|
* @param addr IP address to write data to.
|
|
* @param addrLen
|
|
*/
|
|
void enqueueMessage(udp::BufferQueue* queue, const uint8_t* message, uint32_t length, uint32_t streamId,
|
|
uint32_t peerId, uint32_t ssrc, OpcodePair opcode, uint16_t rtpSeq, sockaddr_storage& addr, uint32_t addrLen);
|
|
|
|
/**
|
|
* @brief Helper method to clear any tracked stream timestamps.
|
|
*/
|
|
void clearTimestamps();
|
|
|
|
private:
|
|
uint32_t m_peerId;
|
|
|
|
static std::mutex s_timestampMtx;
|
|
static std::unordered_map<uint32_t, uint32_t> s_streamTimestamps;
|
|
|
|
/**
|
|
* @brief Search for a timestamp entry by stream ID.
|
|
* @param streamId Stream ID to find.
|
|
* @return uint32_t Table entry.
|
|
*/
|
|
uint32_t findTimestamp(uint32_t streamId);
|
|
/**
|
|
* @brief Insert/update a timestamp for a stream ID.
|
|
* @param streamId Stream ID.
|
|
* @param timestamp Timestamp.
|
|
*/
|
|
void setTimestamp(uint32_t streamId, uint32_t timestamp);
|
|
/**
|
|
* @brief Erase a timestamp for a stream ID.
|
|
* @param streamId Stream ID.
|
|
*/
|
|
void eraseTimestamp(uint32_t streamId);
|
|
|
|
/**
|
|
* @brief Generate RTP message for the frame queue.
|
|
* @param[in] message Message buffer to frame and queue.
|
|
* @param length Length of message.
|
|
* @param streamId Message stream ID.
|
|
* @param peerId Peer ID.
|
|
* @param ssrc RTP SSRC ID.
|
|
* @param opcode Opcode.
|
|
* @param rtpSeq RTP Sequence.
|
|
* @param[out] outBufferLen Length of buffer generated.
|
|
* @returns uint8_t* Buffer containing RTP message.
|
|
*/
|
|
uint8_t* generateMessage(const uint8_t* message, uint32_t length, uint32_t streamId, uint32_t peerId,
|
|
uint32_t ssrc, OpcodePair opcode, uint16_t rtpSeq, uint32_t* outBufferLen);
|
|
};
|
|
} // namespace network
|
|
|
|
#endif // __FRAME_QUEUE_H__
|