143 lines
3.6 KiB
C++
143 lines
3.6 KiB
C++
/*
|
||
* eth_udp_client.hpp
|
||
*
|
||
* Created on: 15 апр. 2023 г.
|
||
* Author: sychev
|
||
*/
|
||
|
||
#ifndef FREE_RTOS_ETHERNET_IP_ETH_UDP_CLIENT_HPP_
|
||
#define FREE_RTOS_ETHERNET_IP_ETH_UDP_CLIENT_HPP_
|
||
|
||
#include <array>
|
||
#include <vector>
|
||
#include <atomic>
|
||
#include <iterator>
|
||
#include <cstdint>
|
||
|
||
#include <networking/enet/utils/include/enet_apputils.h>
|
||
|
||
#include "free_rtos/semaphore/semaphore.hpp"
|
||
#include "free_rtos/mutex/mutex.hpp"
|
||
#include "free_rtos/ethernet/eth_frame.h"
|
||
#include "free_rtos/ethernet_ip/eth_arp_iface.hpp"
|
||
#include "free_rtos/ethernet_ip/eth_ip_iface.hpp"
|
||
#include "free_rtos/ethernet/eth_types.h"
|
||
#include "free_rtos/ethernet_ip/eth_udp_types.h"
|
||
#include "free_rtos/handler_store/handler_store.hpp"
|
||
|
||
namespace free_rtos {
|
||
|
||
struct UDPHandlerArgs : public IpHandlerArgs {
|
||
void * p_data;
|
||
};
|
||
|
||
enum UDPToggle : uint32_t {
|
||
UDP_BUF_0 = 0,
|
||
UDP_BUF_1,
|
||
UDP_BUF_NUM,
|
||
UDP_BUSY = UDP_BUF_NUM
|
||
};
|
||
|
||
class EthUpdClient : public Handler {
|
||
friend class EthUdpServer;
|
||
|
||
public:
|
||
EthUpdClient(EthIpIface& ip_iface, EthArpIface& arp,
|
||
TEthMacPorts port_id, uint16_t port_dst_be, uint16_t port_src_be,
|
||
bool use_chksum);
|
||
|
||
virtual int32_t Process(uint8_t * p_data, uint32_t len) override;
|
||
virtual uint16_t Sender(HandlerArgs& handlerArgs, size_t scatter_segment) override;
|
||
|
||
size_t get_data_size();
|
||
|
||
int32_t read(uint8_t * p_data, uint32_t len);
|
||
int32_t read_async(uint8_t * p_data, uint32_t len);
|
||
|
||
template<class T, class Allocator>
|
||
int32_t read_async(std::vector<T, Allocator>& data, uint32_t len)
|
||
{
|
||
if (len == 0) {
|
||
return 0;
|
||
}
|
||
|
||
if (buff_[toggle_].size() == 0) {
|
||
if(capture_buffer() == false) {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
return get_data(data, len);
|
||
}
|
||
|
||
bool write(uint32_t ip_dst_be, uint8_t * p_data, uint32_t len);
|
||
|
||
template<class T, class Allocator>
|
||
bool write(uint32_t ip_dst_be, std::vector<T, Allocator>& data)
|
||
{
|
||
return write(ip_dst_be, data.data(), data.size() * sizeof(T));
|
||
}
|
||
|
||
void clear();
|
||
void clear_async() {
|
||
buff_[out_toggle_].clear();
|
||
}
|
||
|
||
private:
|
||
const uint32_t max_buf_size = 0x0C00; // 0x0C00 - 3072, 0x1800 - 6144, 0x4000 - 16384, 32768, 0x10000 - 65536, 0x11CA - 4554, 0x0BDC - 3036, 0x100000 - 1Mb
|
||
|
||
const uint16_t port_dst_be_; /// big endian
|
||
const uint16_t port_src_be_; /// big endian
|
||
const bool use_checksum_;
|
||
|
||
EthIpIface& ip_iface_;
|
||
EthArpIface& arp_;
|
||
|
||
const TEthMacPorts port_id_;
|
||
|
||
//TEthPkt eth_pkt_;
|
||
|
||
uint32_t src_ip_{0x00000000};
|
||
uint64_t src_mac_{0x0000000000000000};
|
||
|
||
std::array<std::vector<uint8_t>, UDP_BUF_NUM> buff_;
|
||
std::atomic<UDPToggle> in_toggle_{UDPToggle::UDP_BUF_1};
|
||
UDPToggle out_toggle_{UDPToggle::UDP_BUF_0};
|
||
|
||
Semaphore rx_sem_;
|
||
|
||
void put_data(uint8_t * p_data, uint32_t len);
|
||
size_t get_data(uint8_t * p_data, uint32_t len);
|
||
bool capture_buffer();
|
||
|
||
template<class T, class Allocator>
|
||
size_t get_data(std::vector<T, Allocator>& data, uint32_t len)
|
||
{
|
||
std::vector<uint8_t>& buff = buff_[out_toggle_];
|
||
size_t size = buff.size();
|
||
|
||
if (size > len) {
|
||
size = len;
|
||
}
|
||
|
||
auto item_begin = buff.begin();
|
||
auto item_end = item_begin + size;
|
||
|
||
data.insert(data.end(), item_begin, item_end);
|
||
buff.erase(item_begin, item_end);
|
||
|
||
return size;
|
||
}
|
||
|
||
void set_src_ip(uint32_t src_ip, uint64_t src_mac) {
|
||
src_ip_ = src_ip;
|
||
src_mac_ = src_mac;
|
||
}
|
||
|
||
inline uint16_t fill_udp_header(UDPHandlerArgs& udpHandlerArgs);
|
||
};
|
||
|
||
}
|
||
|
||
#endif /* FREE_RTOS_ETHERNET_IP_ETH_UDP_CLIENT_HPP_ */
|