/* * 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 #include #include #include #include #include #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 int32_t read_async(std::vector& data, uint32_t len) { if (len == 0) { return 0; } if (buff_[out_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 bool write(uint32_t ip_dst_be, std::vector& 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, UDP_BUF_NUM> buff_; std::atomic 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 size_t get_data(std::vector& data, uint32_t len) { std::vector& 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_ */